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 780 - [TV52016721] Cloning a Chart copies the series to the destination chart, and it al...
Summary: [TV52016721] Cloning a Chart copies the series to the destination chart, and ...
Status: RESOLVED FIXED
Alias: None
Product: VCL TeeChart
Classification: Unclassified
Component: Series (show other bugs)
Version: unspecified
Hardware: All All
: Normal enhancement
Target Milestone: ---
Assignee: yeray alonso
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-09-17 16:41 EDT by yeray alonso
Modified: 2018-01-30 05:12 EST (History)
1 user (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description yeray alonso 2014-05-26 06:57:11 EDT
Cloning a Chart copies the series to the destination chart, and it also copies the custom axes, but not the CustomVertAxis and CustomHorizAxis links.
Not sure if this has to be done in the Assign(), in the AssignFormat(), or in the CloneChart() method, at TeEngine.pas:
TChartSeries.AssignFormat(Source:TChartSeries)
TChartSeries.Assign(Source:TPersistent);
CloneChart(Dest,Origin:TCustomChart; AOwner:TComponent; ForceManualData:Boolean);
http://www.teechart.net/support/viewtopic.php?f=3&t=14354&p=63137#p63137
Here it is the code to reproduce the problem. You just need two empty charts in a form:
uses Series;
procedure TForm1.FormCreate(Sender: TObject);
var i, nSeries: Integer;
begin
  nSeries:=4;
  Chart1.View3D:=false;
  Chart1.MarginLeft:=10;
  for i:=0 to nSeries-1 do
  begin
    Chart1.AddSeries(TLineSeries).FillSampleValues;
    with Chart1.CustomAxes.Add as TChartAxis do
    begin
      StartPosition:=i*100/nSeries;
      EndPosition:=(i+1)*100/nSeries;
      Axis.Color:=Chart1[i].Color;
      LabelsFont.Color:=Chart1[i].Color;
    end;
    Chart1[i].CustomVertAxis:=Chart1.CustomAxes[i];
  end;
  //Clone Chart1 to Chart2
  CloneChart(Chart2, Chart1, Self, false);
end;

As a workaround, if you know the relations, you can reassign them as follows, but what if you don't?
  for i:=0 to Chart2.SeriesCount-1 do
    Chart2[i].CustomVertAxis:=Chart2.CustomAxes[i]; [created:2013-09-17T16:41:54.000+02:00 reported by:yeray@steema.com reported in version:2013.08.030521 (TeeChart VCL)]
Comment 1 yeray alonso 2014-05-27 10:09:38 EDT
Another customer suggested another workaround using a Dictionary to save the correlations between the axes in the original and destination charts.
The customer uses this dictionary to set the Series and Axis properties in the tools in the destination chart.

Worth to take a look at when implementing the fix.

http://www.teechart.net/support/viewtopic.php?p=66163#p66163

Here the code:

class procedure TTeeChartRenderer.cloneTools(
   const   fromChart:  TChart;
   const   toChart:    TChart
);
var
   axisLookupDict: IDictionary<TChartAxis, TChartAxis>;

   toolIterator:    TTeeCustomTool;
   copiedTool:     TTeeCustomTool;
begin
   Assert( Assigned(fromChart) and Assigned(toChart) );

   // This is a lookup dictionary to find the matching axis of "toChart"
   // when we still have the "old" axis of "fromChart"
   axisLookupDict := createAxisDictionary(fromChart, toChart);
   
   for toolIterator in fromChart.Tools do begin

      copiedTool :=  VclTee.Chart.CloneChartTool(toolIterator, toChart);

      // Point tool to matching series of toChart
      if toolIterator is TTeeCustomToolSeries then
         (copiedTool as TTeeCustomToolSeries).Series :=
            toChart.Series[ (toolIterator as TTeeCustomToolSeries).Series.SeriesIndex ];

      // Point tool to matching axis of toChart
      if toolIterator is TTeeCustomToolAxis then
         (copiedTool as TTeeCustomToolAxis).Axis :=
            axisLookupDict[ (toolIterator as TTeeCustomToolAxis).Axis ];

      toChart.Tools.Add(copiedTool);

   end;
end;



class function TTeeChartRenderer.createAxisDictionary(
   const   originalChart:    TChart;
   const   clonedChart:    TChart
): IDictionary<TChartAxis, TChartAxis>;
var
   axisIndex: Integer;
begin
   Assert( Assigned(originalChart) and Assigned(clonedChart) );
   Result := TDictionary<TChartAxis, TChartAxis>.Create();

   try

      {TODO -oJM -cGeneral : Does that that also include "custom axes"?}
      for axisIndex := 0 to Pred(originalChart.Axes.Count) do
         Result.Add(
            originalChart.Axes.Items[axisIndex],
            clonedChart.Axes.Items[axisIndex]
         );

   except
      Result.Free();
      raise;
   end;
end;