Steema Issues Database

Note: This database is for bugs and wishes only. For technical support help, if you are a customer please visit our online forums;
otherwise you can use StackOverflow.
Before using this bug-tracker we recommend a look at this document, Steema Bug Fixing Policy.



Bug 832 - Trouble writing chart and restoring it when simple functions are used
Summary: Trouble writing chart and restoring it when simple functions are used
Status: RESOLVED FIXED
Alias: None
Product: VCL TeeChart
Classification: Unclassified
Component: Chart (show other bugs)
Version: unspecified
Hardware: PC Windows
: High critical
Target Milestone: ---
Assignee: Steema Issue Manager
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-07-08 07:46 EDT by h.hasenack
Modified: 2021-04-21 05:05 EDT (History)
3 users (show)

See Also:
Chart Series: ---
Delphi / C++ Builder RAD IDE Version:


Attachments
Reproduceable Test case (2.70 KB, application/x-zip-compressed)
2014-08-20 03:45 EDT, david berneda
Details

Note You need to log in before you can comment on or make changes to this bug.
Description h.hasenack 2014-07-08 07:46:41 EDT
simple functions with single datasources lose their datasource when the chart is written using TStream.WriteObjectResource and later reloading it.

This is because of the 'Datasources' defineproiperties implementation and the IsDataSourceStored implementation.

When only 1 datasource is present, it is stored using a component link instead of a component name (like de datasources list). 

When the chart is reloaded later on, the series get to be owned by the chart rather than the form containg the chart causing the single datsource link not be resolved.

I have created a solution and verified that it works in my case. It is not likely to break any existing code, so here it is. IMHO it could be even fixed a bit better if the .Loaded routine that resolves the FTempDatasourcesList would be a bit more intelligent.

To me the issue is critical since it blocks storing and restoring charts defined /adjusted by my users.


Here are my patches for teengine.pas:

procedure TChartSeries.DefineProperties(Filer: TFiler);
begin
  inherited;

  Filer.DefineProperty('DataSources',ReadDataSources,WriteDataSources,
       Assigned(FDataSources)
       {$ifdef HH_PATCH_TC_DATASOURCEPERSISTANCE}
         and (FDataSources.Count>0) and not IsDataSourceStored
       {$else}
         and (FDataSources.Count>1)
       {$endif}
       );  { <-- don't translate }

  Filer.DefineProperty('CustomHorizAxis', ReadCustomHorizAxis,
                                          WriteCustomHorizAxis,Assigned(FCustomHorizAxis));  { <-- don't translate }
  Filer.DefineProperty('CustomVertAxis', ReadCustomVertAxis,
                                          WriteCustomVertAxis,Assigned(FCustomVertAxis));  { <-- don't translate }

  Filer.DefineBinaryProperty('Data',ReadData,WriteData,IsDataStored);
end;


Function TChartSeries.IsDataSourceStored:Boolean;
Begin
{$ifdef HH_PATCH_TC_DATASOURCEPERSISTANCE}
  // chart custom elements always through Datasources property (linked by component name)
  result:=(DataSources.Count=1) and not (Datasources[0] is TCustomChartElement);
{$else}
  result:=DataSources.Count=1;;
{$endif}
end;
Comment 1 sandra pazos 2014-08-08 09:54:46 EDT
Many thanks for your fix. We will review it for inclusion in our source code for future maintenance releases.
Comment 2 david berneda 2014-08-20 03:45:49 EDT
Created attachment 268 [details]
Reproduceable Test case

Small project to reproduce stream writing/reading a Chart with Series/TeeFunction and DataSource.
Comment 3 david berneda 2014-08-20 03:48:40 EDT
One solution to this problem is using a TWriter object.
In the attached project, the "Stream" button does not work, and the "Writer" button works.

Setting TWriter Root property to the owner of the datasource (the Form1), stores the datasource component name without the Form prefix, so it can be reloaded correctly:

  s:=TMemoryStream.Create;
  try
    w:=TWriter.Create(s,8192);
    try
      w.WriteSignature;
      w.Root:=Self;           <-----------------  Form1
      w.WriteComponent(Chart1);
    finally
      w.Free;
    end;
Comment 4 h.hasenack 2014-09-12 03:40:39 EDT
I believe my solution using the component name and the afterwards resolver is a better solution.
If the code soent break anything, could you please add it to the next teechart release?

Thx
Comment 5 marc meumann 2021-04-21 05:05:58 EDT
slow to get here but code added. Thx for the feedback.