Page 1 of 1

TCursorTool & Chart redraw

Posted: Tue Apr 13, 2004 12:45 pm
by 8577046
I am using a CursorTool (TChart 6.01, Delphi 6) in a sort of playback situation.
Around 4 times a second I use
CursorTool.XValue := NewValue;
to set the cursor to a new position.

It seems that the Chart (2 x TBarSeries) is redrawn every time I set the cursor to a new position, because my application has 50% CPU usage (2.4 GHz, 512 MB, XP Pro).

When I change the type of the CursorTool to 'Follow mouse' and don't set the CursorTool.XValue manually CPU usage drops dramatically. This even happens when I move the mouse as fast as I can.

Based on this experiment my conclusion is that the charts are redrawn when I set the cursortool manually.

Is this right?

If so, how can I avoid that (to lower the CPU usage)?
Please note: there are no changes in the chart, I am just moving the cursortool.

Regards,
Bert

Posted: Thu Apr 15, 2004 11:43 am
by Pep
Hi Bert,

the Cursor tool does not triggers a chart repaint.
It paints the cursor lines using xor mode to avoid repainting.

I've tried a simple example here, which only changes the XValue (using a TTimer) and the CPU usage is litle. Have you tried to set the Marks visible to false for the Series ?
If you still having problems, could you please provide me a small project to test / debug (you could post it at the steema.public.attachments newsgroup) ?

Posted: Fri Apr 16, 2004 6:48 am
by 8577046
Hi,

Thanks for your reply.

I don't know what's going on in my application.
Some time next week I will try to isolate the chart and the problem for further investigation.

Bert

Posted: Mon Apr 19, 2004 6:04 pm
by 8577046
The attachment is in the newsgroup.

Please have a look.


Bert

Posted: Tue Apr 20, 2004 6:07 pm
by Pep
Hi Bert,

ok, I'll take a look and tell you something asap.

Posted: Tue Apr 27, 2004 3:04 pm
by 8577046
Hello Pep,

Any news about a fix for this bug?

Bert

Posted: Tue Apr 27, 2004 4:59 pm
by Marjan
Hi, Bert.

Yes, the XValue does eventually call the Repaint method so at the end chart is redrawn and this increases CPU load. I've tried to use the following code to minimize the redraw time but the CPU load was still high:

Code: Select all

procedure TCursorChartForm.TimerTimer(Sender: TObject);
var
  TimerValue : integer;
  Dt: TDateTime;
begin
  Timer.Enabled := False;
  TimerValue := GetTickCount mod TimeLength;
  Dt := TimerValue / _24HOUR;
  // the following line sets the cursor but also makes the Chart to redraw the series
  cursorTool.ParentChart.AutoRepaint := False;
  CursorTool.RedrawCursor;
  CursorTool.XValue := Dt;
  CursorTool.RedrawCursor;
  cursorTool.ParentChart.AutoRepaint := True;
  Timer.Enabled := True;
end;
I'll log this to our to-do list so that it can be addressed for next major Teechart release. Right now I cannot find another way to significantly speed-up cursor refreshing/drawing time.

From your code I see you're plotting 12.000 points which means there are more than 8 points per chart pixel in horizontal direction. This means that 8 points share the same coordinate i.e. are overlapped. Try decreasing the number of points you're trying to plot. I've posted an article about fast drawing on our web site (real-time charting). It will give you some additional ideas how to optimize drawing time.

Posted: Wed Apr 28, 2004 7:09 pm
by 8577046
Hello Marjan,

Thank you for your fix. It avoids the unnecessary redraw of the chart.
The reason for the 12.000 points is that I also have zooming abilities in my application. Leaving out points is no option.

Best regards,
Bert

Posted: Thu Apr 29, 2004 7:19 am
by Marjan
Hi, Bert.

Ok, yes, I understand. Perhaps it would be worth to use the reduction trick and (based on zoom factor) repopulate series with data for each zoom. I'm using something similar in one of my applications and it's still a lot faster to calculate first and last point index, then perform a reduction and finally populate series with data for each zoom operation. Calculating averages and populating series is still a lot faster than drawing 12.000 points <gg>.

Posted: Thu Apr 29, 2004 3:23 pm
by 9333098
If a reduction is done and only one value plotted per X pixel location, then the resulting chart may not look the same as if all are plotted. This can occur because several data points normally get plotted at the same X pixel location. If they have different Y values, a vertical line ends up being shown at that specific X pixel (instead of just one dot when reduction is done). So instead, the sub-range of points that should be plotted at a given X pixel can be searched and their min and max values found. Then a vetical line drawn at that X pixel. It can even get more complicated. When all points are drawn, the last point plotted at a given X pixel is connected by a "sloped" line to the first point drawn at the next X pixel. So that should also be taken into account instead of simply drawing vertical lines at each X pixel. These last point and first points should be found and determined whether they lie within the vertical line segments at each X pixel.

This can be checked by drawing one series with all points and another on top of it with the one point reduction method and observing how different they appear. For thousands of points, there's often a large difference. I've used a candle series to draw vertica line results from the local min/max approach and it appears much closer to the all-points series. It does take more time to draw the chart this way.

Perhaps TChart could implement these methods internally as an option to speed up drawing ?