04-18-2013 03:15 AM
Hi all,
I have a question about graph update in LabWindows/CVI. My question doest not concern plotting, but graph legend : how can I avoid "legend flashing effect" when I refresh my graph ?
Please see below my function...
(Note that the following options are ON : "autosize legend" and "automatically add new plots to legend"...But I can turn it OFF if needed)
Thank you very much for any help ! 🙂
/*========================================================================================*/
/* Update graph function */
/*========================================================================================*/
void UpdateGraph (float64 *acqData, CHNLCONFIG *chnlConfig)
{
int plotIndex;
int plotHdl;
const int chnlColor[NB_CHANNELS] = {VAL_RED, VAL_GREEN, VAL_BLUE, VAL_DK_RED, VAL_DK_GREEN, VAL_DK_BLUE};
const char *chnlName[NB_CHANNELS] = {"U1", "U2", "U3", "I1", "I2", "I3"};
const int chnlAxis[NB_CHANNELS] = {VAL_LEFT_YAXIS, VAL_LEFT_YAXIS, VAL_LEFT_YAXIS, VAL_RIGHT_YAXIS, VAL_RIGHT_YAXIS, VAL_RIGHT_YAXIS};
// Defer graph update
SetCtrlAttribute (mesPanelHdl, TABMES_UIGRAPH, ATTR_REFRESH_GRAPH, 0);
// Delete graph
DeleteGraphPlot (mesPanelHdl, TABMES_UIGRAPH, -1, VAL_DELAYED_DRAW);
// For each plot...
for (plotIndex = 0 ; plotIndex < NB_CHANNELS ; plotIndex++)
{
// If channel activated...
if (chnlConfig[plotIndex].selected)
{
// Plot curve
plotHdl = PlotY (mesPanelHdl, TABMES_UIGRAPH, acqData + plotIndex * RATE, RATE, VAL_DOUBLE, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, chnlColor[plotIndex]);
// Set curve name
SetPlotAttribute (mesPanelHdl, TABMES_UIGRAPH, plotHdl, ATTR_PLOT_LG_TEXT, chnlName[plotIndex]);
// Set curve axis
SetPlotAttribute (mesPanelHdl, TABMES_UIGRAPH, plotHdl, ATTR_PLOT_YAXIS, chnlAxis[plotIndex]);
}
}
// Refresh graph
SetCtrlAttribute (mesPanelHdl, TABMES_UIGRAPH, ATTR_REFRESH_GRAPH, 1);
}
Solved! Go to Solution.
04-18-2013 03:17 AM
Said diffrently, my question would be : is there a function similar to LabVIEW "differ panel update" function ?
04-18-2013 03:37 AM
Hi,
I am not using legends so I am not sure what exactly you see, but for my graphs I avoid flickering due to updating several plots by hiding (and re-showing) the graph. So try replacing your two lines
SetCtrlAttribute (mesPanelHdl, TABMES_UIGRAPH, ATTR_REFRESH_GRAPH, 0);
and
SetCtrlAttribute (mesPanelHdl, TABMES_UIGRAPH, ATTR_REFRESH_GRAPH, 1);
with
SetCtrlAttribute (mesPanelHdl, TABMES_UIGRAPH, ATTR_VISIBLE, 0);
and
SetCtrlAttribute (mesPanelHdl, TABMES_UIGRAPH, ATTR_VISIBLE, 1);
04-18-2013 03:47 AM
Thank you for your answer.
But it's not a relevant solution for me : with ATTR_VISIBLE instead of ATTR_REFRESH_GRAPH, the entire graph seems to be "flashing" ! 😄
Before I try your suggestion, only the legend was "flashing". I tried to turn OFF "automatically add plots to legend" and "autosize legend" options and I modified the code in order to set legend only once (before continuous plotting), but the problem with this solution is that legend plot names are deleted when I delete the graph, at each iteration !
Any function in LabWindows to defer panel update for instance ?
04-18-2013 04:08 AM
The idea of this suggestion is that the user will not realize that the graph has been hidden as long as the UI is not updated. All the action appears on a hidden graph and only the last function to make it visible again will refresh it. (This tip I actually learned from Luis)
I successfully use this approach to delete plots (using VAL_IMMEDIATE_DRAW then), add or change annotations, add new plots etc. BUT, as mentioned, I have not tried it with legends...
04-18-2013 04:16 AM
I'm not sure what I'm saying applies to graphs also, but hiding the control as suggested by wolfgang applies to tables too, and I seem to remember that it does not work if the table is the active control.
So if your graph is not in indicator mode AND it is the active control in the panel you may try setting another control as the active one by setting these lines in your function:
ctrl = GetActiveCtrl (panelHandle);
if (ctrl == PANEL_GRAPH) {
wasActive = 1;
SetActiveCtrl (panelHandle, xx);
}
// Update the graph
if (wasActive)
SetActiveCtrl (panelHandle, PANEL_GRAPH);
(It's more or less a blind shot, but it may worth a try)
04-18-2013 06:43 AM
Wolfgang, I took a look at Luis's technique. He says : "As long as you don't process UI events between the time when you hide the graph and the time when you re-show it, the graph should never visually be removed from the panel."
However, I can see that graph flickering even with graph "hiding/modifying/re-showing" technique (ATTR_VISIBLE). But I have to say that my function UpdateGraph () is called in another thread...do you think the flickering could have something to do with it ?
What do you mean exactly by "UI events" ? Do you mean "Callback function calls" or anyrthing else ?
04-18-2013 06:50 AM
(Roberto, thank you for your help as well, but my graph is in "indicator" mode. I tried your suggestion anyway, but I could not get rid off the flickering effect. 🙂 )
04-18-2013 06:55 AM
I understand it such that you should not call functions that will update your panel while your graph is hidden, such as ProcessDrawEvents or ProcessSystemEvents. You should process callback events only after you have finished updating your graph.
(Luis probably will show up in three hours from now)
04-18-2013 07:08 AM
OK for UI events, that's clear.
I put a breakpoint in my code to execute it step by step.
It appears that :
- after SetCtrlAttribute (mesPanelHdl, TABMES_UIGRAPH, ATTR_VISIBLE, 0) instruction : graph is still visible (that's exactly what I need...as you suggested user should not see the "hide" effect)
- after the first PlotY call : graph is hidden (and that's what I would like to avoid)