LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Two quick questions about graph annotations.Can you get a callback handle from the annotation and is there an easy way to force the annotation(s) to remain in view on the yaxis but not on the x axis?

Application : we use an X-Y plot to display some relatively large datasets (up to 8 Mpoint). We are already reducing the data that displays to 4000 points and recalculating for each zoom / unzoom operation to improve lag time. I am trying to label each of the peaks of interest with graph annotaion. In the wide shot, the labels plot on top of each other and that is OK. It is only in the narrow view where the labels are useful .
 
First Question: I know that the user can move the annotations around on the graph which suggests that each annotation has some hot control characteristics. They do not seem to generate a callabck to the UI control where the annotations are located.  Can you intercept the callback and use this to discover the index for the given annotation. My application would have thousands of annotation in a wide view but only a handful in the narrow view. I would like to be able to select the annotation and then display additional information about the peak reffered by the annotation.
 
Second Question : Same application but the user zooms in to a narrow view causing the y axis to autoscale, and the annoatation that labels the most abundant peak go off screen in the y direction. Is there a quick way to force the annotation to stay in view for the y axis only not the x axis? I do not want to force all of the annotations to be in view( do not want the extra x axis annotations to line the right and left edges of the zoom) just those in the select x axis range. I assume I could manually range check the x axis min/max, set the visibility to off for those outside the range and then force all remaining annotation to view in x and y. I would prefer to not add these extra steps on top of the other calculations that happen on zoom operations. Am I missing something easy here?
 
Thanks in advance for your time.
Greg
0 Kudos
Message 1 of 5
(3,550 Views)
Hello Greg,

Concerning your first question, an EVENT_COMMIT should be sent to the graph control after the user finishes moving an annotation. Also, an EVENT_VAL_CHANGED is sent continuously while the annotation is being moved.
The main problem is how to distinguish which annotation was moved. Unfortunately, unlike graph cursors, events generated by annotations are not properly setting the eventdata1 parameter with the index of the annotation that caused the event. The fact that eventdata1 isn't set is considered buggy behavior and will be changing in the next version of CVI. Until it changes, there is a kludgy workaround you can use: assuming that your graph doesn't already have one or more graph cursors, if you create one graph cursor, and make it both transparent and disabled, so that it's effectively invisible and unintrusive, then when an annotation is moved, eventdata1 will contain the annotation index -- but you must subtract 1 from the value that is received (the 1 refers the cursor that you created). Keep in mind that this behavior will be changed on any version of CVI after 8.1.1 -- after it changes, you will no longer need to create a graph cursor, and you won't have to subtract anything (you can use the _CVI_ macro, to ensure that your code won't break when a new version of CVI is introduced).

As for your second question, although you have the ability to constrain individual annotations to always stay within the view (use SetAnnotationAttribute with ATTR_ANNOTATION_CAPTION_ALWAYS_IN_VIEW), there is no way to constrain it in Y but not in X. So your only recourse would be to manually capture the zoom events (EVENT_ZOOM) and then shift the annotations programmatically. (I know, it's kind of a pain when you have so many...)

Hope this helps,

Luis


0 Kudos
Message 2 of 5
(3,530 Views)
Greg,

A co-worker just pointed out a pretty basic mistake in my earlier post. When I suggested that you use _CVI_ to guard against a future behavior change, that actually doesn't make sense, since _CVI_ is a compile time check. You need a runtime check, so you'd have to use the function GetCVIVersion instead.

Sorry about that.

Luis
0 Kudos
Message 3 of 5
(3,512 Views)

Thanks for the quick reply.

Unfortunately, I am already using a couple of cursors so the workaround may not be helpful. As for capturing the manually capturing the Zoom, I do already so I will just add the annotation manipulation. I don't know if there is anyone else who would be interested in the x axis only or y axis only "remain in view" but I would like to request these two new attributes for graph annotation if y'all could work them into the next round of updates.

I hope you had a good NIWeek .

Greg

0 Kudos
Message 4 of 5
(3,504 Views)
Hi Greg,

The fact that you're already using cursors doesn't mean that you can't use the workaround. My point was that if you didn't have any, then you'd have to create at least one. But since you already have a couple, then you don't have to.

The code inside your graph callback will look something like this:

case EVENT_COMMIT:
if (GetCVIVersion() <= 811)
{
GetCtrlAttribute (panel, control, ATTR_NUM_CURSORS, &numCursors);
if (eventData1 > numCursors)
annotationIndex = eventData1 - numCursors;
else
break; // the user operated a cursor, and not an annotation. Do nothing (presumably)
}
else
annotationIndex = eventData1;
break;
0 Kudos
Message 5 of 5
(3,489 Views)