Page 1 of 1

Clone Series, OnAddSeries

Posted: Tue Feb 09, 2010 10:29 am
by 10555199
Hi
I'm presenting the TChartEditform to the user at runtime so he can
add/remove series.


In the "OnAddSeries" event on the TChart I create an link between the added
series and an object in a objectlist.

procedure TForm1.Chart1AddSeries(Sender: TCustomChartSeries);
var
o: TMyObject;
begin
o:= TMyObject.Create;
sender.Identifier:= IFXGuid.ToString(o.id);
MyObjList.Add(gl);
end;

I link the series to an object in myobjectList by setting the
series.Identifier to the objects Id.

The problem is when the user makes a clone of the series by clicking "clone"
in the TChartEditform.
This event is then run, but after the event has finished, then the original
series properties are set to the Clone
sender.Identifier:= IFXGuid.ToString(o.id); //will get the source series Identifier value, not the one assigned in the event.

Any tips on how I can prevent the Identifier value to be overwritten?

Re: Clone Series, OnAddSeries

Posted: Tue Feb 09, 2010 11:17 am
by narcis
Hi Infront,

Could this be a problem with TMyObject constructor and how id property is set? Code below works fine for me here. Could you please modify it so that we can reproduce the issue?

Code: Select all

uses Series;

procedure TForm4.Chart1AddSeries(Sender: TCustomChartSeries);
begin
  Sender.Identifier:= IntToStr(c);
  Inc(c);

  Memo1.Lines.Add(Sender.Name + ' - ' + Sender.Identifier);
end;

procedure TForm4.FormCreate(Sender: TObject);
begin
  Memo1.Lines.Clear;
  c:=0;

  Chart1.AddSeries(TLineSeries.Create(Self));
  Chart1[0].FillSampleValues;
end;
Thanks in advance.

Re: Clone Series, OnAddSeries

Posted: Wed Feb 10, 2010 8:31 pm
by 10555199
Yes the code works fine when you add series.
The problem is when you are using the charteditor. And press the "Clone" button.
First the clone series will be added and the identifier will be set correct.
But after this event has finished running the clone gets its properties assigned from the source line. Then the identifier set in the event gets overwritten.

I have pasted the CloneChartSeries method from Chart.pas
I have added comments on the last 2 lines of code

Code: Select all

// Duplicates ASeries with AOwner as new series owner, adds the new Series to AChart
Function CloneChartSeries(ASeries:TChartSeries; AOwner:TComponent; AChart:TCustomAxisPanel):TChartSeries;
var tmp : TTeeFunctionClass;
begin
  with ASeries do
  begin
    if FunctionType=nil then
       tmp:=nil
    else
       tmp:=TTeeFunctionClass(FunctionType.ClassType);

    result:=CreateNewSeries(AOwner,AChart,TChartSeriesClass(ClassType),tmp);   //The OnAddseries will then be run
  end;

  result.Assign(ASeries);     //her the new series(clone) gets assigned the properties from the source series
end;

Re: Clone Series, OnAddSeries

Posted: Thu Feb 11, 2010 9:30 am
by narcis
Hi Infront,

Thanks for your feedback. I could reproduce the problem now using this code:

Code: Select all

var
  Form4: TForm4;
  c: Integer;

implementation

{$R *.dfm}

uses Series;

procedure TForm4.Chart1AddSeries(Sender: TCustomChartSeries);
begin
  Sender.Identifier:= IntToStr(c);
  Inc(c);

  Memo1.Lines.Clear;
  Memo1.Lines.Add(Sender.Name + ' - ' + Sender.Identifier);
end;

procedure TForm4.Chart1AfterDraw(Sender: TObject);
var i: Integer;
begin
  for i := 0 to Chart1.SeriesCount - 1 do
    Memo1.Lines.Add(Chart1[i].Name + ' - ' + Chart1[i].Identifier);
end;

procedure TForm4.FormCreate(Sender: TObject);
begin
  c:=0;

  Chart1.AddSeries(TLineSeries.Create(Self));
  Chart1[0].FillSampleValues;
end;
Debugging this example I've seen this is by design as in TeEngine.pas, at TCustomChartSeries.Assign(Source:TPersistent), Identifier is assigned:

Code: Select all

{ copy basic properties from one series to self }
procedure TCustomChartSeries.Assign(Source:TPersistent);
Begin
  if Source is TCustomChartSeries then
  With TCustomChartSeries(Source) do
  begin
    Self.FShowInLegend := FShowInLegend;
    Self.FTitle        := FTitle;
    Self.FStyle        := FStyle;
    Self.FIdentifier   := FIdentifier;
  end;
  
  inherited;
end;
I can think of 2 solutions here:

1. Assign TMyObject.id to Series.Name instead of Identifier.

2. Remove FIdentifier assignment in your code. Identifier is an internal use property valid only for Borland/CodeGear/Embarcadero's DecisionGraph component. The Identifier property is used to identify all Series lists of values, e.g. X and Y values. So if you are not using Decision Cube components I guess you can remove that safely.

Anyway, I have added this issue to the defect list (TV52014678) to be investigated for future releases.