3

Top post: I have accepted an answer,but it doesn't work for me. I will post a new question, stressing Delphi 7. Thanks to all who gave some good input


I have measurements taken at one second intervals over an hour.

I had a previous question where it was taking 45 seconds to updates a TStringGrid and managed to get that down to "faster than the eye can see". Partly by moving some computation and database related functionality of of the loop, but - surprisingly to me - the change that really made the difference was setting the strindgrid's rowCount to 3600 before the loop rather than incrementing it inside the loop.

Now I have a similar problem with a TChart. Maybe if I try preallocating the chart? So, I could Chart1.Series[0].Count := 3600, but than I can't use AddXy() or Add(), so how would I explicitly set the values in series?

I have a very simple chart, with Floats on the y-axis and hour:seconds on the x-axis

Can anyone help, or suggest another way to speed up chart drawing?


Update: several have suggested using TFastLineSeries, but I don't see how.

Aha - double click on the Chart, to show all series, select one & click change

Community
  • 1
  • 1
Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551
  • 1
    My TCharts typically drawn 100,000 points in the blink of an eye. Would you like to tell us more about your TCharts. – David Heffernan Jan 22 '11 at 12:30
  • +1 thanks, that tells me that there is hope :-) I just have up to 3600 floats, with values between 0 & 600 and label teh x-axis with MM:SS times – Mawg says reinstate Monica Jan 22 '11 at 14:12
  • 1
    I would be interested in learning more about anything you/anyone may know about this. I have a similar situation. Our systems usually (until lately) have been deployed on windows XP systems. Large amounts of points draw very quickly without any issues. The same dataset on my Windows 7 systems draws extraordinarily slow. Slow to a point that i can see each line being individually drawn, and when a portion of the chart needs to be re-scaled due to max/min values, i can see all of the re-scaling as well. Trying to hunt down the answer – PoultrySlave Feb 28 '14 at 22:34
  • Poultry Slave?? I'll get there's a good story behind that :-) Sorry that I can't help you. At around that time I purchased a bunch of TMS software components and their charts are excellent. I can only recommend you Google for "best free Delphi chart component". – Mawg says reinstate Monica Mar 01 '14 at 04:21

3 Answers3

5

You can find the "official" recommendations about fast charting on Steema website

kludg
  • 27,213
  • 5
  • 67
  • 118
4

I manage to draw millons of datapoints in a blink of an eye. Here's how I do it: What you can do is to create two arrays for the X and Y Values, fill them with your values and then these arrays to your chart. For example:

var
  XValues, YValues: array of double; 
begin

  SetLength(XValues, numberofValues);
  SetLength(YValues, numberofValues);

  for ix := 0 to numberofValues - 1 do 
  begin
    XValues[ix] := ...your values
    YValues[ix] := ...your values
  end;

  Chart.Series[0].XValues.Value := TChartValues(XValues);
  Chart.Series[0].XValues.Count := high(XValues);
  Chart.Series[0].XValues.Modified := true;
  Chart.Series[0].YValues.Value := TChartValues(YValues);
  Chart.Series[0].YValues.Count := high(YValues);
  Chart.Series[0].YValues.Modified := True;

What also speeds up the drawing is using the TFastLineSeries instead of the regular TLineSeries. When using the FastlineSeries you also have the property DrawAllPoints. When set to false the drawing is even faster. TChart will then skip datapoints that share the same X Position with other datapoints on the screen. It will only draw the first point of these.

This is where you find it the DrawAllPoints option: alt text

Michael Küller
  • 3,982
  • 4
  • 22
  • 42
  • 1
    The big downside of DrawAllPoints is that the resulting graph is, in general, a very poor representation of the underlying data – David Heffernan Jan 22 '11 at 19:36
  • +1 Michael, that looks like exactly what I want to do. Unfortunately, the line Chart1.Series[0].XValues.Value := TChartValues(XValues); gives an error '[' expected but ':=' found – Mawg says reinstate Monica Jan 23 '11 at 02:26
  • Btw, what does DrawAllPoints belong to? Chart.Series[0].XValues? Chart.Series[0] ? Chart? None seem to work – Mawg says reinstate Monica Jan 23 '11 at 02:28
  • Delphi 7, if it makes any difference – Mawg says reinstate Monica Jan 23 '11 at 03:06
  • DrawAllPoints belongs to TFastLineSeries. You can set it directly on your form editor. They just call it Draw All there. Its a checkbox on the Series -> Format pane. I use TChart Pro 8.07 maybe this is different in other versions? I don't see why Chart1.Series[0].XValues := TChartValues(XValues) shouldn't work. Just rechecked it. – Michael Küller Jan 23 '11 at 20:54
  • Michael, thank you very much for trying to help. Unfortunately, Delphi 7 does now show DrawAll as in your new screenshot. In fact, the Series/Format tab only has an option to select border color. Nor do I see DrawAll in the object inspector, nor does it appear in auto-complete in the code editor. – Mawg says reinstate Monica Jan 24 '11 at 04:01
  • @Leonix You must have some other problem. 3,600 is a trivial amount of points. I see absolutely no need to use DrawAllPoints. – David Heffernan Jan 24 '11 at 19:22
2

I would just like to comment on the Michael Schmooks answer. Using High(XValues) to set the Count value for the series causes the last item in the array not to be displayed. This is because high(XValues) returns the highest index of the array, and not the size of the array.

Of course, this is only noticed when a very low nr of items happens to be added.

Chart.Series[0].XValues.Count := high(XValues) + 1;
bosvos
  • 549
  • 5
  • 14