Search code examples
delphiteechart

Reduce the number of drawn TChart points


My TChart has a lot of points added by series.AddXY method. A point is added every second (but there could be also long periods without data). After the chart has been changed (point added), when I go to the tab with the chart, it takes about 5 seconds before it is repainted.

I thought that using an aggregate function would help to draw the chart faster:

ser1: TFastLineSeries;
ser2: TPointSeries;
ser3: TFastLineSeries;
utc: TDateTime;

ser1.SetFunction(TAverageTeeFunction.Create(Self));
ser1.FunctionType.Period := 100;
ser1.FunctionType.PeriodStyle := psRange;

ser2.SetFunction(TAverageTeeFunction.Create(Self));
ser2.FunctionType.Period := 100;
ser2.FunctionType.PeriodStyle := psRange;

ser3.SetFunction(TAverageTeeFunction.Create(Self));
ser3.FunctionType.Period := 100;
ser3.FunctionType.PeriodStyle := psRange;

for i := 0 to 30000 do begin
   .....
   ser1.AddXY(utc, 0, utcStr);
   ser2.AddXY(utc, deviation, utcStr);
   ser3.AddXY(utc, trend, utcStr);
   .....
end;

but it is as slow as it was.

How to draw the chart faster?

Update

This is non-zoomable chart for 3 hours of data. "Now" is at the right edge, "-3h" on the left. Points are constantly arriving to the right and deleted from the left. The view frame is shifted by setting chart.BottomAxis.Minimum and chart.BottomAxis.Maximum properties. I would be satisfied by AVG drawing where amount of averages is the horizontal amount of pixels on the chart.


Solution

  • I rounded DateTime value

    axisTimestamp := Trunc(timestamp * 40000) / 40000;
    

    and then used this value to set chart point.

    If a point with such XValue exists then I calculate an average:

    if series.XValue[i] = axisTimestamp then
        series.YValue[i] := (series.YValue[i] + newValue) / 2;