TCursorTool & Chart redraw
TCursorTool & Chart redraw
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
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
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) ?
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) ?
Pep Jorge
http://support.steema.com
http://support.steema.com
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:
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.
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;
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.
Marjan Slatinek,
http://www.steema.com
http://www.steema.com
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>.
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>.
Marjan Slatinek,
http://www.steema.com
http://www.steema.com
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 ?
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 ?