Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

How to click and select a WaveFormPlot on WaveFormGraph

Solved!
Go to solution

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

0 Kudos
Message 1 of 9
(4,794 Views)
Solution
Accepted by topic author robson

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:

 

private void waveformGraph1_PlotAreaMouseDown(object sender, MouseEventArgs e)
{
    XYGraphHitTestInfo hitLocation = waveformGraph1.HitTest(e.X, e.Y);

    switch (hitLocation)
    {
    case XYGraphHitTestInfo.Plot:
        XYPlot thePlot = waveformGraph1.GetPlotAt(e.X, e.Y);
        thePlot.LineColor = Color.White;
        foreach (XYPlot plot in waveformGraph1.Plots)
            if (!plot.Equals(thePlot))
                plot.LineColor = Color.LimeGreen;
        break;
    }
}

 

NickB

National Instruments 

0 Kudos
Message 2 of 9
(4,790 Views)

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 of  

XYGraphHitTestInfo.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

0 Kudos
Message 3 of 9
(4,745 Views)

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.

 

private void legend1_MouseDown(object sender, MouseEventArgs e)
{
    LegendHitTestInfo hitLocation = legend1.HitTest(e.X, e.Y);
    switch (hitLocation)
    {
    case LegendHitTestInfo.Item:
        LegendItem item = legend1.GetItemAt(e.X, e.Y);
        foreach (XYPlot plot in waveformGraph1.Plots)
        {
            if (!plot.Equals(item.Source))
                plot.LineColor = Color.LimeGreen;
            else
                plot.LineColor = Color.White;
        }
        break;
    }
}

 

Let me know if you have any questions - 

 

NickB

National Instruments 

0 Kudos
Message 4 of 9
(4,735 Views)

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'

0 Kudos
Message 5 of 9
(4,727 Views)

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

0 Kudos
Message 6 of 9
(4,707 Views)
 
0 Kudos
Message 7 of 9
(4,707 Views)

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.

 

private void GetDataPointFromClientPoint(Point mousePoint, out double x, out double y)
{
    Range xRange = waveformGraph1.XAxes[0].Range;
    Range yRange = waveformGraph1.YAxes[0].Range;
    PointF virtDataPoint = waveformGraph1.PointToVirtual(mousePoint);

    x = (xRange.Maximum - xRange.Minimum) * virtDataPoint.X + xRange.Minimum;
    y = (yRange.Maximum - yRange.Minimum) * virtDataPoint.Y + yRange.Minimum;
}

 

private void GetDataPointFromClientPoint(Point mousePoint, out double x, out double y)
{
    XYPlot plot = waveformGraph1.Plots[0];

    plot.InverseMapDataPoint(plot.GetBounds(), mousePoint, out x, out y);
}

 

Let me know if have any further questions!

 

NickB

National Instruments 

0 Kudos
Message 8 of 9
(4,701 Views)

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

0 Kudos
Message 9 of 9
(4,694 Views)