Page 1 of 1

Saveing TChart during series update?

Posted: Thu Mar 05, 2009 8:13 am
by 10545590
Hello !

We want to implement a very simple HTTP Server into our application. This webserver should serve a webside which contains the actual chart view as JPG.

Everytime the webside is requested from the browser the chart should be refreshed. For use the following code for that:

Code: Select all

  TeeSaveToJPEGFile( Chart1,                          // Chart ...
                     FHTMLDir + '\mychart.jpg',       // Path
                     False,                           // not gray scale
                     jpBestQuality,
                     95,                              // compression
                     640, //Chart1.Width,
                     480); //Chart1.Height );
In general this works fine, but sometime the resulting jpg is not complete. Some parts of the chart are missing. In some cases axis are missing, sometimes curves are not complete and sometimes the jpg is just a white image with no contense.

The problem is that our application adds every second new values to the series. So do you have any idea what causes this problem ?

Or could you make any suggestion what´s the best way to save a chart into a JPG file while the chart is beeing updated constantly?

Greetz Dominik

Posted: Thu Mar 05, 2009 3:11 pm
by yeray
Hi Dominik,

We think that probably the problem is that sometimes the exportation process coincides with the repaint routine. Every time you add a point, having autorepaint to true, the chart is repainted and this take some time. And if in this time you try to export the chart, you could find problems.

So we recommend you to set autorepaint to false, add your points, and before you show/export your chart, force a chart repaint.

You can find more related info in the Real-time Charting article here.

Posted: Mon Mar 09, 2009 11:44 am
by 10545590
Hi Yeray,

I tried this:

Code: Select all

  Chart.AutoRepaint := False;
  TeeSaveToJPEGFile( Chart,                           // Chart ...
                     HTMLDir + '\mychart.jpg',       // Path
                     False,                           // not gray scale
                     jpBestQuality,
                     95,                              // compression
                     Chart_Width, //Chart1.Width,
                     Chart_Height); //Chart1.Height );
  Chart.AutoRepaint := True;
  Chart.Repaint;
But I have still the same problems. Sometimes not all parts of the chart are in the JPEG file.

I also tried to use a copy of the chart and save the jpeg from that copy via a thread. But then I get problems if the webserver wants to read the graphic and the stream is writing at that time.

So I hope you have any further idea :roll:

Posted: Mon Mar 09, 2009 12:23 pm
by yeray
Hi Dominik,

No, I probably haven't explained well. In this code you are disabling the autoRepaint just before exporting and re-enabling it just after exporting.

I think you should disable it at OnCreate, for example, and leave it always disabled. Then, add a Chart1.Repaint call just after the every point addition and another Chart1.Repaint call just before the exportation:

Code: Select all

Chart.Repaint;
TeeSaveToJPEGFile( Chart,                           // Chart ...
                     HTMLDir + '\mychart.jpg',       // Path
                     False,                           // not gray scale
                     jpBestQuality,
                     95,                              // compression
                     Chart_Width, //Chart1.Width,
                     Chart_Height); //Chart1.Height ); 

Posted: Mon Mar 09, 2009 12:32 pm
by 10545590
Hi Yeray,

thx for the information.

One last question ...
There is a AutoRepaint for series:

Code: Select all

//  for i := 0 to Chart.SeriesCount - 1 do
//    TFastLineSeries(Chart[i]).AutoRepaint := True;
and a AutoRepaint for the Chart:

Code: Select all

Chart.AutoRepaint := ....
I should use Chart.AutoRepaint !?

Posted: Mon Mar 09, 2009 3:03 pm
by yeray
Hi Dominik,

I'm afraid that the solution I suggested wasn't still the most plausible. You are adding points every second and allowing the exportation though another thread, aren't you? Then:

- Disabling autoRepaint and repainting after adding points and before exporting, it still could cause conflicts if the repaint after adding points takes too time.

- Disabling the autoRepaint before adding the points and enabling it one finished adding points, this would prevent your a asynchronous exportation to work with a "half painted chart". Here there is an example (often more comprehensive):

Code: Select all

uses series, TeeJPEG, JPEG;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  for i:=0 to 9 do
    Chart1.AddSeries(TFastLineSeries.Create(self));

  Chart1.AutoRepaint := false;
end;

procedure TForm1.Button1Click(Sender: TObject);
var HTMLDir: string;
begin
  HTMLDir := 'C:\tmp\';

  TeeSaveToJPEGFile( Chart1,                           // Chart ...
                     HTMLDir + '\mychart.jpg',       // Path
                     False,                           // not gray scale
                     jpBestQuality,
                     95,                              // compression
                     Chart1.Width, //Chart1.Width,
                     Chart1.Height); //Chart1.Height );
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var i, j: Integer;
begin
  Chart1.AutoRepaint := false;

  for i:=0 to Chart1.SeriesCount-1 do
    for j:=0 to 9 do
      Chart1[i].Add(random*100);

  Chart1.AutoRepaint := true;
  Chart1.Repaint;
end;