04-17-2012 12:51 AM
Hi NI team.
I develope winforms C# application. I have Waveform graph in it and I place multiple plots on it.
Those plots have different scale. For example, I might have two plots with amplitudes of 0.005 and 5 A. In order to see both plots normally and not to see one as normal and the second as a flat line I apply different scale to them. However they share the same X-axis which is a time.
In my application I can choose active plot and do different things with it, like show cursors, drag the plot around the graph(Y position) and so on. But there is something I don't know how to implement.
I want the following behavior: On selecting active plot Y-axis gets its scale from plot and the axis divisions starting to show relevant values. I attach image to let you understand it better than I can explain on my poor English.
Regards, Artem.
04-17-2012 11:30 AM - edited 04-17-2012 11:30 AM
Hi there,
We have a workaround for the solution you are looking for. See the attached code. The trick is fairly simple.
private void Form1_Load(object sender, EventArgs e) { yAxis1.Mode = NationalInstruments.UI.AxisMode.Fixed; yAxis2.Mode = NationalInstruments.UI.AxisMode.Fixed; waveformPlot2.YAxis = yAxis2; yAxis2.Visible = false; waveformPlot1.PlotY(GetMyData(1000, 2.2, 2.2)); waveformPlot2.PlotY(GetMyData(1000, 0.22, .22)); } // Generate some data here Random r = new Random(); private double[] GetMyData(int samples, double amplitude, double yOffset) { double[] d = new double[samples]; for (int i = 0; i < samples;i++ ) { d[i] = yOffset + amplitude * (Math.Sin(Math.PI * i / 100) + r.NextDouble() * 0.2); } return d; } // Handle the mouse click or mouse down event
// this method is all you would need for your application!
private void waveformGraph1_MouseDown(object sender, MouseEventArgs e) { // Hit test gives you what is present at a particular location on the graph. if (waveformGraph1.HitTest(e.X, e.Y) == NationalInstruments.UI.XYGraphHitTestInfo.Plot) { XYPlot plot = waveformGraph1.GetPlotAt(e.X, e.Y); if (plot.YAxis == yAxis1) {
// If you click on the first plot, hide the second axis
yAxis1.Visible = true; yAxis2.Visible = false; } else if(plot.YAxis == yAxis2) {
// if you click on the second plot, hide the first axis!
yAxis1.Visible = false; yAxis2.Visible = true; } } }
Hope this helps!
Regards,
Vijet Patankar,
National Instruments.
11-20-2012 05:57 AM
Well... it is not exactly the right place, but I will ask you here on slightly different topic. If there is an answer for my new question in another thread - just give me link, please.
I miss general picture in my mind. I need some schematic understanding of NI control's "box model". What should be placed inside what...
Lets say I have just placed WaveformGraph control on my form. My graph will have 1 XAxis and 1 YAxis and 1 Plot.
But what happens later? Or what is correct to happend in future?
In my code if I want to place some data on graph I do the following:
var plot1 = new WaveformPlot();
// Set plot axis section
plot1.DefaultIncrement = 1;
plot1.PlotY(array1);
waveformGraph1.Plots.Add(plot1);
Is it correct?
If my data object is logically different from all other data objects
(e.g. array of current measurements with its units, length, time between two points and so on vs array of voltage measurements)
is it correct to create different plot for each data object?
It also depends on what I am going to do with my data, right? So I want to be able to drag my plots along Y axis (place one above another, or place them so that their Y-zero are on the same place), set division value for each plot individually e.t.c.
And what is totally unclear to me are the axes.. What should i do in // Set plot axis section ? Create new y/x axis? Share X axis since they all run above the same time, and create new y-axis for each plot?
Hm... sorry for unclear question... 🙂
Here are two images. You can see two plots on the graph. On picture#1 the lower plot is the selected one, so the Y axis has different units and values from the Y axis on the picture#2 where the upper plot is selected.
I also implemented in my code the feature of dragging plot by Y... (using those plot handles I draw on the left user can drag plots up and down, see picture#3)
But despite all my code works as I want, I have a very strong feeling that I am doing it all wrong... I miss general understanding of NI controls structure...
Thank you very much for you patient reading 🙂
11-20-2012 10:39 AM
Hi there,
The following is the typical usecase of plotting data on the graph:
// Create Graph and its subobjects WaveformGraph g = new WaveformGraph(); WaveformPlot p = new WaveformPlot(); XAxis x = new XAxis(); YAxis y = new YAxis(); // ================================= // CONFIGURE GRAPH: // minimum set of configuration: g.XAxes.Add(x); g.YAxes.Add(y); p.XAxis = x; p.YAxis = y; g.Plots.Add(p); // on top of the above configurations you can do a lot of things like, // for plot p.DefaultIncrement = 0.1; p.DefaultStart = 1000; p.HistoryCapacity = 100; // for axis x.Range = new Range(1000, 100000); x.Mode = AxisMode.AutoScaleLoose; x.LogBase = 8; x.MajorDivisions.LabelFormat = new FormatString(FormatStringMode.DateTime, "g"); x.MajorDivisions.GridVisible = true; x.OriginLineVisible = true; x.Position = XAxisPosition.TopBottom; // makes x axis visible at both top and bottom! // for graph g.InteractionMode = GraphInteractionModes.ZoomX | GraphInteractionModes.ZoomY | GraphInteractionModes.ZoomAroundPoint; g.Caption = "My Graph!"; g.ZoomFactor = 5; // ================================= // Plot data double[] data = new double[100]; // some data here g.PlotY(data); // OR g.Plots[0].PlotY(data); // OR p.PlotY(data);
Furthermore, these concept topics may help you better understand our graph controls in general.
Hope this helps.
Vijet Patankar
National Instruments
11-21-2012 09:16 AM
Thanks a lot for the links !