Page 1 of 1
Problem with SaveChartToStream/LoadChartFromStream
Posted: Tue Jan 18, 2005 8:10 pm
by 9339850
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
Posted: Wed Jan 19, 2005 4:25 pm
by 9339850
Any one?
I need a resolution asap...boss is taking software to a sales conference.
Posted: Thu Jan 20, 2005 7:58 am
by Marjan
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).
Posted: Thu Jan 20, 2005 10:45 pm
by 9339850
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
Posted: Fri Jan 21, 2005 8:43 am
by Marjan
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.
Posted: Fri Jan 21, 2005 9:24 am
by 8439980
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;
Posted: Fri Jan 21, 2005 9:41 am
by Marjan
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.
Posted: Fri Jan 21, 2005 1:27 pm
by 9339850
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