LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Exactly how is the X and Y value of a graph cursor calculated?

I have a graph program where the X and Y values are continuously updated on the screen when the cursor moves over the graph. I use two different ways to get the X and Y value, by getting the mouse cursor position (when moving) and by getting the value of the graph cursor position (when clicking).

I've noticed that there's about 0.2% difference in value when using the graph cursor (in free form mode) and when using the mouse cursor. Not that 0.2% is a lot, but it looks a bit strange when your value changes when you click on the same point your mouse was hovering over.

IMO the graph cursor is (should be) more precise than the pixel method, so I would like to make the calculation exactly equal to the graph cursor method. The question remains: what is that method???

The different methods are described below.


case EVENT_LEFT_CLICK:
GetGraphCursor (panel, control, 1, &XValue, &YValue);
SetCtrlVal(panel, GRAPHPANEL_CURSOR1X, XValue);
SetCtrlVal(panel, GRAPHPANEL_CURSOR1Y, YValue);


case EVENT_MOUSE_MOVE:
GetCtrlAttribute (GraphPanel, GRAPHPANEL_GRAPH, ATTR_TOP, &GraphArea.top);
GetCtrlAttribute (GraphPanel, GRAPHPANEL_GRAPH, ATTR_PLOT_AREA_TOP, &PlotArea.top);
PlotArea.top += GraphArea.top;
GetCtrlAttribute (GraphPanel, GRAPHPANEL_GRAPH, ATTR_LEFT, &GraphArea.left);
GetCtrlAttribute (GraphPanel, GRAPHPANEL_GRAPH, ATTR_PLOT_AREA_LEFT, &PlotArea.left);
PlotArea.left += GraphArea.left;
GetCtrlAttribute (GraphPanel, GRAPHPANEL_GRAPH, ATTR_PLOT_AREA_HEIGHT, &PlotArea.height);
GetCtrlAttribute (GraphPanel, GRAPHPANEL_GRAPH, ATTR_PLOT_AREA_WIDTH, &PlotArea.width);

if (!RectContainsPoint (PlotArea, MakePoint (eventData2, eventData1))) break;

GetAxisScalingMode (panel, control, VAL_XAXIS, 0, &XAxisMin, &XAxisMax);
GetAxisScalingMode (panel, control, VAL_LEFT_YAXIS, 0, &YAxisMin, &YAxisMax);

eventData1 -= PlotArea.top;
eventData2 -= PlotArea.left;

XValue = XAxisMin + (XAxisMax - XAxisMin) / (double)PlotArea.width * (double)eventData2;
YValue = YAxisMin + (YAxisMax - YAxisMin) / (double)PlotArea.height * (double)(PlotArea.height - eventData1);

SetCtrlVal(panel, GRAPHPANEL_CURSOR1X, XValue);
SetCtrlVal(panel, GRAPHPANEL_CURSOR1Y, YValue);
0 Kudos
Message 1 of 2
(3,347 Views)
Erwin,

The reason why there is a discrepancy is because the graph axes are lcoated 1 pixel inside the plot area, on its left edge (the x-axis) and on its top edge (the y-axis). But not on the right and bottom edges. So, in order to make the calculations match, all you have to do is add 1 to the values you obtain from ATTR_PLOT_AREA_LEFT and ATTR_PLOT_AREA_TOP (and to keep the right edge identical, you'll also have to subtract 1 from the width and the height). Once you do that, the values will be identical.

Also, for the GetGraphCursor method, you will probably want to do it on the EVENT_VAL_CHANGED case, and not the EVENT_LEFT_CLICK case, since if you do it on EVENT_LEFT_CLICK, the graph hasn't received the click yet, so the cursor hasn't yet had a chance to move to the new mouse position.

Luis
NI
Message 2 of 2
(3,330 Views)