06-11-2010 12:14 PM
Hello word!
I'm plotting several WaveFormPlots on my WaveFormGraph using Measurement Studio 9 and C#.
Because the plots are many, I want to plot all them with the same color and use the mouse click to highlight one of them.
I looked for this event in the WaveFormGraph events list but it seems does not exist!
How is possible to catch the mouse click event on a specific WaveFormPlot?
Thank you
Roberto
Solved! Go to Solution.
06-11-2010 01:20 PM
Hello Roberto -
You should try using the HitTest and GetPlotAt methods in conjunction with a PlotAreaMouseDown event handler. The code could look something like the following:
NickB
National Instruments
06-15-2010 02:45 AM
Hello NickB
your suggestion is the right solution.
I tryed your example and it works fine until the waveFormGraph is not zoomed.
The only one pending question is this: the HitTest() method returns XYGraphHitTestInfo.PlotArea instead ofXYGraphHitTestInfo.Plot if the mouse click is over the interpolation line between two sampled points.
This happens very frequent if you need to zoom the plot area.
Thank you NickB, if you have another suggestion about this please reply me again
Roberto
06-15-2010 12:14 PM
Hey Roberto -
The primary problem is that HitTest on the XYGraph only recognizes points, and not the lines that connect them. There are two possible alternatives.
The first would be to create an invisible cursor with a SnapMode of nearest point. You could then set the cursor to the data coordinates of the moust click, and then get the plot that the cursor is associated with. This could lead to some unexpected behavior though - if you click directly on a line in between two points, and a point from another plot is closer, the wrong plot will be selected.
The second method is most fool-proof, but may not meet your needs entirely. You could create a legend for your graph, and then perform a hit test on the Legend, instead of the graph. You could then get the item that was selected in the legend, map that to a plot, and highlight as necessary.
Let me know if you have any questions -
NickB
National Instruments
06-15-2010 02:53 PM
Hello NickB
thanks again!
I did something like your suggestion before post this topic:
private void legendDUT_MouseClick(object sender, MouseEventArgs e) { for (int i = 0; i < waveDut.Plots.Count; i++) { WaveformPlot pl = waveDut.Plots[i]; pl.LineColor = Color.DarkGreen; pl.LineWidth = 1; } LegendItem item = legendDUT.GetItemAt(e.X, e.Y); ((WaveformPlot)(item.Source)).LineColor = Color.White; ((WaveformPlot)(item.Source)).LineWidth = 3; }
I will implement the cursor technique as you describe me than I hope that will be enough !
Regards
Roberto Bergo'
06-16-2010 07:51 AM
Please nickb
how cao I set the cursor to the data coordinates of the mouse click when the cursor coordinates are related to X and Y scales and the MouseEventArgs refers to the pixels of the plot area?
Roberto
06-16-2010 07:53 AM
06-16-2010 09:59 AM
Hey Roberto -
There are two different ways to do that, I will show them both below. One little issue you have to remember is that because you can have multiple x and y axes, the data point mapping to a mouse coordinate could be different depending upon the axis you want to use. That is why you must pick either an axis or plot for both of the following two methods.
Let me know if have any further questions!
NickB
National Instruments
06-16-2010 01:24 PM
Hello NickB
another goal!
I used the PointToVirtual() solution. It works very well if no zoom is used.
When user zoom a lot the invisible cursor (let visible in debug mode) moves outside the plot area.
I work around this moving always the cursor very far before move it to the clicked point.
This is the final code that works fine in any case:
private void waveDut_PlotAreaMouseDown(object sender, MouseEventArgs e) { XYGraphHitTestInfo hitLocation = waveDut.HitTest(e.X, e.Y); XYPlot thePlot; switch (hitLocation) { case XYGraphHitTestInfo.Plot: //If I got the plot... thePlot = waveDut.GetPlotAt(e.X, e.Y); thePlot.LineColor = Color.White; thePlot.LineWidth = 3; foreach (XYPlot plot in waveDut.Plots) if (!plot.Equals(thePlot)) { plot.LineColor = Color.DarkGreen; plot.LineWidth = 1; } break; default: //otherwise... look around the click point Point mp = new Point(e.X, e.Y); double x, y; GetDataPointFromClientPoint(mp, out x, out y); xyCursInvisible.SnapMode = CursorSnapMode.NearestPoint; xyCursInvisible.MoveCursor(-1000,-1000); xyCursInvisible.MoveCursor(x, y); thePlot = xyCursInvisible.Plot; if (thePlot != null) { thePlot.LineColor = Color.White; thePlot.LineWidth = 2; foreach (XYPlot plot in waveDut.Plots) if (!plot.Equals(thePlot)) { plot.LineColor = Color.DarkGreen; plot.LineWidth = 1; } } break; } } private void GetDataPointFromClientPoint(Point mousePoint, out double x, out double y) { Range xRange = waveDut.XAxes[0].Range; Range yRange = waveDut.YAxes[0].Range; PointF virtDataPoint = waveDut.PointToVirtual(mousePoint); x = (xRange.Maximum - xRange.Minimum) * virtDataPoint.X + xRange.Minimum; y = (yRange.Maximum - yRange.Minimum) * virtDataPoint.Y + yRange.Minimum; }
Thank you again
Roberto