LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

defer update panel

Solved!
Go to solution

In that case, no, I haven't been able to reproduce it yet. I was actually able to reproduce the graph disappearing in one situation involving a cursor snapping to a plot, but without cursors then that wouldn't be a factor.

 

It might be something that's being affected by some specific setting in your graph that I don't have. If you could attach here a stripped-down version of your .uir, with just the graph control, and as long as you're not changing any of the graph settings programmatically, I might be able to run a closer approximation to your application by using your actual graph, instead of the plain vanilla graph that I'm using.

 

I don't think the data that I plot, or the text that I set in the legend would matter (but I can't be sure of that either).

 

Luis

0 Kudos
Message 21 of 33
(1,031 Views)

Here is my simplified UIR (please see ZIP attached)...You will find a project with that UIR.

 

I did not remove the tab I use in my application (maybe it has something to do with graph disappearing ?). So you can use "graphPanelHandle" instead of default "panelHandle" variable to set graph attributes.

example : SetCtrlAttribute (graphPanelHandle, TABMES_UIGRAPH, ATTR_VISIBLE, 1);

0 Kudos
Message 22 of 33
(1,026 Views)

I used your project but, unfortunately, I still can't reproduce the problem. I'm attaching here the exact code that I ran, in case you want to try it yourself.

 

I expect that the only difference between your test and mine is that actual data that is being plotted. I wouldn't have expected that to make a difference, but maybe it does. If you can reproduce the problem by tweaking the data somewhat, please let me know.

 

One thing to watch for is that I noticed that your graph has the "copy original plot data" option disabled. It's okay to do that, but you have to be careful that the data for all your plots has to be remain static and available while those plots are present in the graph. In my case, that meant using 6 concurrent arrays and making sure that they are available globally. This is necessary since the graph needs to access the original data whenever an axis range changes, which can happen outside of the actual plot function.

 

It occurs to me that I never asked you exactly when the graph disappears. Is it when you step over the PlotY function? If so, is it on the very first plot, or in one of the following ones?

 

Thanks,

Luis

0 Kudos
Message 23 of 33
(1,023 Views)

Hi Luis,

 

As I explained previously, I have noticed that the graph disappears when PlotY or SetPlotAttribute function executes. So the behaviour is not always strictly the same...sometimes it's PlotY and sometimes it's SetPlotAttribute which makes the graph disappear ! 😕

 

What do you mean by : "I expect that the only difference between your test and mine is that actual data that is being plotted"

0 Kudos
Message 24 of 33
(1,018 Views)

I meant that my test program is not plotting the same data that you're plotting (acqData) since I don't have access to it. Therefore, I'm just generating a 100-element array of random data from 0 to 100. I wouldn't think that that makes any difference, but I'm not sure.

 

Have you been able to reproduce the graph disappearing with the test program that I attached?

 

0 Kudos
Message 25 of 33
(1,010 Views)

Luis,

 

Here is a version in which the disappearing is reproduced (cf screenshot and ZIP).

 

I think that the disappearing does not depend from the data you are plotting. At the beginning I tried to call UpdateGraph function with "my" data, and it did not disappear.

 

So the differences between your version and mine is that :

- now UpdateGraph function is called in a separated thread

- now UpdateGraph function is called twice in that separated thread (not necessary to see the disappearing, but the disappearing often occurs during the second function call !)

Download All
0 Kudos
Message 26 of 33
(1,010 Views)

Ah, ok, it all makes sense now. I'm sorry that I overlooked the detail that you were updating the graph from a separate thread. I see now that you had mentioned it before but I missed it.

 

Well, this is actually defined behavior then. When you plot to the graph, or when you set an attribute in the graph, those functions schedule an event to update the visual display accordingly. The only reason why normally it is viable to do this trick of hiding the graph, then plotting or setting attributes, followed by restoring the graph, is because you don't give a chance for CVI to process these events during the time when the graph is hidden. However, the thread that processes these events is the thread the owns the graph (i.e. the thread in which you loaded the panel), not the thread in which you are plotting to the graph.So, all it takes is for an OS thread switch to occur while you are updating the grpah, and then for the main thread to process one of these deferred events, for the panel to be redrawn with the graph hidden.

 

The bottom line is that, for this trick to work, you would have to freeze the main thread while you're updating the graph. To freeze the main thread you'll have to either exit RunUserInterface, or wait for it to enter some callback function and then don't allow it to exit until you've updated the graph, which, admittedly would be pretty odd. At that point, you're essentially updating the graph from the main thread, or at least you're locking the main thread while you're updating the graph, which is the same thing.

 

So, given how impractical it would be to use ATTR_VISIBLE to delay updates from a separate thread, we could return to the ATTR_REFRESH_GRAPH alternative to see if that could work for you. If you're still interested in pursuing that solution, let me know and we can try to see if we can make that work.

 

Luis

Message 27 of 33
(996 Views)

Thank you for those explanations Luis ! 🙂

 

At the beginning I tried using ATTR_REFRESH_GRAPH, but the graph seemed to be flickering because of the legend redraw. With ATTR_REFRESH_GRAPH, the only solution I found was to keep my plot handles valid between UpdateGraph function calls, as described in a previous post :

"I'm going to try using SetPlotAttribute with ATTR_PLOT_YDATA attribute...So, after getting a plot handle during first function call, I will have the possibility to replace plot Y data only for this plot handle (without changing any other attribute). I will need to declare some static variable inside UpdateGraph () function."

 

But I'm interested in any other idea you could have. 🙂

0 Kudos
Message 28 of 33
(985 Views)

Another alternative could be to move graph update to the main thread as in the attached code.

 

(As you see in the code, I tried also the ATTR_REFRESH_GRAPH way: see if my solution can work for you)



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 29 of 33
(982 Views)

Hi Julien,

 

If moving the graph update to the main thread doesn't work for you, I'm attaching another solution which should be able to use ATTR_REFRESH_GRAPH without any flashing of the legend.

 

The reason the legend was flashing when you were using ATTR_REFRESH_GRAPH to disable updates is actually quite similar to the reason why ATTR_VISIBLE was not working: when you disable ATTR_REFRESH_GRAPH, no plots will be sent to the graph. All drawing is deferred until the time when you reenable ATTR_REFRESH_GRAPH or you call the RefreshGraph function. However, updating the legend attribute is still scheduling UI updates to be handled later by the main thread. The flashing is a function of when the main thread happens to receive those events:

 

  1. If the main thread processes the UI updates while the other thread is not updating the graph, then the legend will redraw, reflecting the last labels that you set for each plot.
  2. If the main thread processes the UI updates while the other thread is updating the graph, then the graph will have no drawable plots (since they only become drawable once ATTR_REFRESH_GRAPH is reenabled). Consequently the legend is drawn without any plots.

 

 

The result of this is that flashing occurs whenever the two scenarios above alternate.

 

By the way, I couldn't reproduce flashing when I used Roberto's variation which updates the graph every 0.5 seconds. Probably because given so much time between updates, it's very unlikely for scenario 2. above, to occur. But I could reproduce when I started updating the graph as fast as possible.

 

The only solution I could think of would be to prevent any "paint" events from occurring in the main thread during the time when the thread is updating the graph. I'm attaching a modified version of Roberto's test program which does this. It seem to work without flashing.

Message 30 of 33
(972 Views)