How to synchronize multiple 3D Charts

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
X-ray
Newbie
Newbie
Posts: 7
Joined: Tue Jan 16, 2018 12:00 am

How to synchronize multiple 3D Charts

Post by X-ray » Thu Nov 15, 2018 6:19 pm

Hello,

I have a couple of (Cloned) 3D Charts on a form, about 10 to 20.
The first (main) one has a TTeeCommander component connected to zoom, pan and rotate it.
When this main chart gets zoomed, rotated, moved, all other Charts should follow in the same way.
Currently what I do is using the ChartAfterDraw event of the main chart and do this:

Code: Select all

procedure TMyForm.ChartAfterDraw(Sender: TObject);
var
  i: Integer;
begin
    for i := 1 to High(FChartArray) do
    begin
      if (FChartArray[i].Chart.View3DOptions.Zoom <> FChartArray[0].Chart.View3DOptions.Zoom) or
         (FChartArray[i].Chart.View3DOptions.Rotation <> FChartArray[0].Chart.View3DOptions.Rotation) or
         (FChartArray[i].Chart.View3DOptions.Elevation <> FChartArray[0].Chart.View3DOptions.Elevation) or
         (FChartArray[i].Chart.View3DOptions.HorizOffset <> FChartArray[0].Chart.View3DOptions.HorizOffset) or
         (FChartArray[i].Chart.View3DOptions.VertOffset <> FChartArray[0].Chart.View3DOptions.VertOffset) then
      begin
        FChartArray[i].Chart.View3DOptions.Assign(FChartArray[0].Chart.View3DOptions);
        FChartArray[i].Chart.Refresh;
      end;
    end;
 end;
So I loop over all charts check if the Rotation. zoom etc is different than the main Chart and if yes I update the other chart.
This works pretty well most of the times but the program freezes (endless loop) for example when maximizing the form.
Is there any other way just updating the other charts when one of the View3DOptions has changed by hand?

best regards

Yeray
Site Admin
Site Admin
Posts: 9533
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: How to synchronize multiple 3D Charts

Post by Yeray » Mon Nov 19, 2018 11:18 am

Hello,

I guess the easiest solution would be to add a boolean to control whether the mouse has been pressed inside the main chart.
In the following example I'm using FChartArrayDown boolean to do this, even if I couldn't reproduce the endless loop when maximizing the window:

Code: Select all

uses TeeComma, Chart, Series, TeeGDIPlus;

var FCommander: TTeeCommander;
    FChartArray: array of TChart;
    FChartArrayDown: Boolean;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  FCommander:=TTeeCommander.Create(Self);
  FCommander.Parent:=Self;

  FChartArrayDown:=False;

  SetLength(FChartArray, 3);
  FChartArray[0]:=TChart.Create(Self);
  with FChartArray[0] do
  begin
    Parent:=Self;
    OnAfterDraw:=ChartAfterDraw;
    OnMouseDown:=ChartMouseDown;
    OnMouseUp:=ChartMouseUp;

    with AddSeries(TBarSeries) do
    begin
      ColorEachPoint:=True;
      FillSampleValues;
    end;
  end;

  FCommander.Panel:=FChartArray[0];

  for i:=Length(FChartArray)-1 downto 0 do
  begin
    if i>0 then
    begin
      FChartArray[i]:=TChart.Create(Self);
      FChartArray[i].Parent:=Self;
      CloneChart(FChartArray[i], FChartArray[0], Self, False);
    end;

    FChartArray[i].Align:=alTop;
    FChartArray[i].Top:=20;
  end;

  FCommander.Align:=alTop;
end;

procedure TForm1.ChartAfterDraw(Sender: TObject);
var
  i: Integer;
begin
  if FChartArrayDown then
  for i := 1 to High(FChartArray) do
  begin
    if (FChartArray[i].View3DOptions.Zoom <> FChartArray[0].View3DOptions.Zoom) or
       (FChartArray[i].View3DOptions.Rotation <> FChartArray[0].View3DOptions.Rotation) or
       (FChartArray[i].View3DOptions.Elevation <> FChartArray[0].View3DOptions.Elevation) or
       (FChartArray[i].View3DOptions.HorizOffset <> FChartArray[0].View3DOptions.HorizOffset) or
       (FChartArray[i].View3DOptions.VertOffset <> FChartArray[0].View3DOptions.VertOffset) then
    begin
      FChartArray[i].View3DOptions.Assign(FChartArray[0].View3DOptions);
      FChartArray[i].Refresh;
    end;
  end;
end;

procedure TForm1.ChartMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  FChartArrayDown:=True;
end;

procedure TForm1.ChartMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  FChartArrayDown:=False;
end;
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

X-ray
Newbie
Newbie
Posts: 7
Joined: Tue Jan 16, 2018 12:00 am

Re: How to synchronize multiple 3D Charts

Post by X-ray » Mon Nov 19, 2018 1:24 pm

Hello Yeray,

thank you, its working fine now, that was exactly what I also found out as solution, to minimize the number of redraws.

best regards

Yeray
Site Admin
Site Admin
Posts: 9533
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: How to synchronize multiple 3D Charts

Post by Yeray » Tue Nov 20, 2018 9:07 am

Hello,

An alternative would be to use events like OnZoom, OnUndoZoom and OnScroll. The problem is that there's no OnRotate event. I've added it to the public tracker:
http://bugs.teechart.net/show_bug.cgi?id=2127
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Post Reply