Problem with SaveChartToStream/LoadChartFromStream

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Rob
Newbie
Newbie
Posts: 14
Joined: Thu Nov 11, 2004 5:00 am

Problem with SaveChartToStream/LoadChartFromStream

Post by Rob » Tue Jan 18, 2005 8:10 pm

Hello,
I am using Delphi 6 Ent and TeeChart 7

I have searched the forum, but I did not find definate answer to the problem of SaveChartToStream/LoadChartFromStream not loading the series formatting and applying it to the Chart's series.

I saved a Chart to a memory stream with the with the TextFormat option set to true [SaveChartToStream( Chart1, AStream, False, True) ] so that I may verify the format. I had set the BarStyle of a series to bsDiamond and I can only assume it was saved out properly like so:

Code: Select all

object TBarSeries
    Marks.Callout.Brush.Color = clBlack
    Marks.Visible = True
    BarStyle = bsDiamond
    Gradient.Direction = gdTopBottom
    XValues.Name = 'X'
    XValues.Order = loAscending
    YValues.Name = 'Bar'
    YValues.Order = loNone
end
However when I load the Chart back in the formatting is not applied.

Any help/suggestions would be very much appreciated.

Thanks,
Rob

Rob
Newbie
Newbie
Posts: 14
Joined: Thu Nov 11, 2004 5:00 am

Post by Rob » Wed Jan 19, 2005 4:25 pm

Any one?

I need a resolution asap...boss is taking software to a sales conference. :?

Marjan
Site Admin
Site Admin
Posts: 745
Joined: Fri Nov 07, 2003 5:00 am
Location: Slovenia
Contact:

Post by Marjan » Thu Jan 20, 2005 7:58 am

Hi.

Using the following code and the latest TeeChart version bar style is correctly saved and then loaded to another chart:

Code: Select all

Uses TeeStore, TeeEditPro;


procedure TForm1.FormCreate(Sender: TObject);
begin
  Series1.FillSampleValues(10);
end;

procedure TForm1.Button1Click(Sender: TObject);
var stream: TMemoryStream;
begin
  stream := TMemoryStream.Create;
  try
    SaveChartToStream(Chart1,stream,false,True);
    stream.Position := 0; // reposition for load
    LoadChartFromStream(TCustomChart(Chart2),stream);
    if Assigned(Chart2.Series[0]) then Chart2.Series[0].FillSampleValues(5);
    Chart2.Left := Chart1.Left + Chart1.Width + 10;
    Chart2.Title.Text.Clear;
    Chart2.Title.Text.Add('Target');
  finally
    stream.Free;
  end;
end;
I've also posted a sample application (Delphi 7, TC 7.x) at steema.public.attachments newsgroup (topic=bar style save-load).
Marjan Slatinek,
http://www.steema.com

Rob
Newbie
Newbie
Posts: 14
Joined: Thu Nov 11, 2004 5:00 am

Post by Rob » Thu Jan 20, 2005 10:45 pm

Hi,

This works for me in a sample app which is good my problem is probably in the way I am displaying my chart.

I am displaying my chart by saving my chart to a stream which is stored into a database. I read the stream back into a TCustomChart that never gets drawn on to a canvas.

I turned on "Stop on Delphi Exceptions" in my Debugger Options and I started to gee EReadErrors/Property does not exist.

Any suggestions as to why this may be happening?

Thanks for you reponse.

Rob

Marjan
Site Admin
Site Admin
Posts: 745
Joined: Fri Nov 07, 2003 5:00 am
Location: Slovenia
Contact:

Post by Marjan » Fri Jan 21, 2005 8:43 am

Hi, Rob.

Have you tried adding TeeEditPro unit to the Uses section of your import form? This unit automatically registers all chart series and tools types (including properties).

Another thing : TeeChart events and their implementations cannot be saved/loaded to/from stream. You have to disconnect chart from all events before you save it and then later after you load it, reconnect it again.
Marjan Slatinek,
http://www.steema.com

Jan
Newbie
Newbie
Posts: 24
Joined: Fri Nov 15, 2002 12:00 am
Location: Germany

Post by Jan » Fri Jan 21, 2005 9:24 am

I am having the same problem with the question yesterday. Saving works fine, but trying to load causes one of the above mentioned exceptions.

I have two events (OnZoom and UndoZoom) used. What do you mean with disconnect (OnZoom := Nil ?) and what do you mean with reconnect? I am a little confused: Why has TChart loading-problems with events it can not save?

I will repeat my yesterdays question: can i load a template onto a existing chart (with several types of different series, chosen by the user at runtime), without loosing the seriesinformation (i am just asking, because i did not manage a reload again until now ;-) )

Another thing: i have seen in the exported file is a definition of a visible series. This series can be another type when loaded, because i just need the properties of the axes/walls ... and related. Any workaround for this? We are having a presentation next week and it would be great if this works! Maybe just a minor feature among the calculation routines, but an exciting...

Thanks and hoping for help

Jan

This is the code so far:
procedure TfrmGraphic.btSaveTemplateClick(Sender: TObject);
Var tempZoomProc : Pointer;
tempUndoZoomProc : Pointer;
begin

With SaveChartTemplateDialog do
Begin
Filter:='Teefiles|*.tee';
if Execute then SaveChartToFile (Chart1, FileName, False, True);
end;
end;

procedure TfrmGraphic.btLoadTemplateClick(Sender: TObject);
Var tmpChart : TCustomChart;
begin
// Chart1.Free; //assuming Chart1 is already on the Form
tmpChart := TChart.Create (Self);

With LoadChartTemplateDialog do
Begin
Filter := 'Teefiles|*.tee';
if Execute then LoadChartfromFile (tmpChart, FileName);
end;

Chart1 := tmpChart as TChart;

With Chart1 do
Begin
Parent := Self;
end;

// FreeAndNil (tmpChart);
end;

Marjan
Site Admin
Site Admin
Posts: 745
Joined: Fri Nov 07, 2003 5:00 am
Location: Slovenia
Contact:

Post by Marjan » Fri Jan 21, 2005 9:41 am

Hi, Jan.
I have two events (OnZoom and UndoZoom) used. What do you mean with disconnect (OnZoom := Nil ?) and what do you mean with reconnect?
Something like this should work (providing events existing in your "load" form interface and implementation):

Code: Select all

Chart1.OnZoom := nil;
Chart1.OnUndoZoom := nil;
SaveChartToFile('d:\temp\test.tee',False,True);
LoadChartFromFile(TCustomChart(Chart1),'d:\temp\test.tee');
Chart1.OnZoom := Chart1OnZoom;
Chart1.OnUndoZoom := Chart1OnUndoZoom;
In case you don't need these events on loaded chart you can safely ignore last two lines. Also, be aware of the fact that after load operation all series variables (like Series1, Series2, ...) are no longer valid (in case you use them in your code) and have to be reinitialized or alternatively, replaced with TChart.Series calls.
without loosing the seriesinformation

Yes, in case you're talking about source chart series information (series properties).But if you load the chart from a stream then target chart properties (including series types, ...) will be reset and set to match those of saved chart. Using the Save/Load combination you can't save/load some chart properties and leave others unchanged.

Any workaround for this?

Yes. Call the sourceChart.FreeAllSeries() before save operation. This way only chart properties will be saved to a stream (as there are no series). If you want to avoid calling FreeAllSeries() on source chart, then create a temporary chart, copy source chart to it and then perform FreeAllSeries and save operation on temporary chart. This way the original chart will remain unchanged and at the same time saved chart will not include any series.
Marjan Slatinek,
http://www.steema.com

Rob
Newbie
Newbie
Posts: 14
Joined: Thu Nov 11, 2004 5:00 am

Post by Rob » Fri Jan 21, 2005 1:27 pm

Hi Marjan,

Yes, I have included TeeChartPro and there are no events attached.

I believe I got it working by setting the parent of the chart before I load it from the stream (or in the code snip below a buffer):

Code: Select all

  ChartStream := TMemoryStream.Create;
  try
    FChart := TCustomChart.Create(NIL);
    if Assigned(FChart) then
      begin
        try
          FChart.Name := 'Chart1';
          FChart.Visible := false;
          FChart.Parent := Application.MainForm;
          if FExtraLength > 0 then
            begin
              ChartStream.WriteBuffer( PChar( FExtraData)^, FExtraLength);
              ChartStream.Position := 0;
              LoadChartFromStream( FChart, ChartStream);
              FChart.RemoveAllSeries;
            end;  
          FChart.Left := -1000;
          FChart.Top := 0;
          SetAspectRatio;
          FChart.Color := clWhite;
          FChart.BorderStyle := bsNone;
          FChart.BevelInner := bvNone;
          FChart.BevelOuter := bvNone;
          FChart.MarginTop := 5;
          FChart.MarginBottom := 5;
          FChart.MarginLeft := 5;
          FChart.MarginRight := 5;
          FChart.BackColor := clWhite;
          FChart.BackWall.Transparent := true;
          InitializeChart(FChart);
        except on E:Exception do
          begin
            FChart.Free;
            FChart := NIL;
          end;
        end;
        Retval := FChart;
      end;
  finally
    Result := Retval;
    ChartStream.Free;
  end;
I would still like to know why I am getting the EReadErrors.

Thanks for your reponses.

Rob

Post Reply