ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Gauge Drawing Performance
Posted by Electron Shepherd on Jun-09-2015 06:19
I'm using the gauge chart type, and updating the needle position about 50 times a second. We've added some "dynamics" to make the pointer motion look realistic - so when the value changes from, for example, 30 to 50, the needle moves up to about 55, then drops back to about 48, then moves to about 51, then drops back to about 49.5 and so on, until it comes to rest exactly on 50. Basically we're trying to make it look like an analogue meter. For the changing range detailed above, we calculate a number of intermediate points, and set the pointer value to each of those points in succession, so creating the effect of smooth movement. This works really well, but the call to makeChart is using a lot of CPU. I'm guessing that's because CD is having to do lots of work to lay out and draw the whole gauge every time we change the pointer value.

Of course, the majority of the gauge doesn't change at all - the face and axis could be drawn once and only the pointer drawn on top when the value changes.

I can't see any way to draw just the pointer . I tried setting all the colours apart from the needle to Chart::Transparent, but the same CPU load was still there.

Is there any way I can animate the pointer of the gauge at about 50 frames a second, but without having to do all the calculations associated with drawing the rest of the gauge? Ideally, I'd like to generate the gauge "face" once, and then just generate the pointer, and then I can merge the two with a TransparentBlt call.

  Re: Gauge Drawing Performance
Posted by Peter Kwan on Jun-10-2015 03:19
Hi Electron,

I can think of some methods, but I am not sure if they can actually help. It is possible
the overhead is not to just to draw the chart itself, but for MFC to update the screen.

The methods I can think of are:

(a) Create a meter object but with no pointer and display it. Create another meter object
with just the pointer (with everything else transparent) and try to "TransparentBlt" it or
otherwise put it on top of the first meter.

or

(b) Create a meter object but with no pointer and use it as the background image of
another meter that just contain the pointer. To use one chart as the background image o
another, the code is:

//Set c1 as the backgrouind image of c2. This code should be run before adding
//things to c2.
c2->getDrawArea()->merge(c1->makeChart3(), 0, 0, Chart::TopLeft, 0);

or

(c) Create a meter object but with no pointer. Set up a dynamic layer (using
BaseChart.initDynamicLayer). Then DrawArea.merge to put another meter that just have
a pointer onto it. To updating the pointer, call initDynamicLayer again (which would wipe
away the old pointer), and re-add another pointer only meter.

Another thing you may consider is to reduce the refresh rate to 24 frame per second
(which is frame rate of a DVD movie, which is not as good as HDTV but can be
acceptable sometime).

Regards
Peter Kwan