Setting same ChartRect for two charts

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Arne Jakobsen
Newbie
Newbie
Posts: 3
Joined: Fri Sep 16, 2005 4:00 am

Setting same ChartRect for two charts

Post by Arne Jakobsen » Thu Aug 31, 2006 1:22 pm

I have two charts place one above the other on a form. I would like the ChartRect (if that is the area of the chart, which is bounded by the axes) to be identical for the two charts, so that a given x-coordinate can be at the same horisontal position on both charts. I can read the values of TChart.ChartRect.Left and TChart.ChartRect.Right, bu how can i set them and have the new settings reflected in the chart?

Best Regards and Thank You in advance,
Arne Jakobsen

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Thu Aug 31, 2006 1:31 pm

Hi Arne,

You can do something like in the code snippet below or you can use custom axes so that you don't need to use several chart. For more information on how to use custom axes please read "Tutorial 4 - Axis Control" and have a look at the features demo. Tutorials and demo can be found at TeeChart's program group.

Code: Select all

procedure TForm1.FormCreate(Sender: TObject);
var
  Chart1, Chart2, Chart3, Chart4: TChart;
begin
  Chart1 := TChart.Create( Self );
  Chart2 := TChart.Create( Self );
  Chart3 := TChart.Create( Self );
  Chart4 := TChart.Create( Self );

  Chart1.Parent := Self;
  Chart2.Parent := Self;
  Chart3.Parent := Self;
  Chart4.Parent := Self;

  Chart1.Left := 0;
  Chart2.Left := 0;
  Chart3.Left := 0;
  Chart4.Left := 0;

  Chart1.Top := 0;
  Chart2.Top := 100;
  Chart3.Top := 200;
  Chart4.Top := 300;

  Chart1.Width := 500;
  Chart2.Width := 500;
  Chart3.Width := 500;
  Chart4.Width := 500;

  Chart1.Height := 100;
  Chart2.Height := 100;
  Chart3.Height := 100;
  Chart4.Height := 100;

  Chart1.View3D := false;
  Chart2.View3D := false;
  Chart3.View3D := false;
  Chart4.View3D := false;

  Chart1.Show;
  Chart2.Show;
  Chart3.Show;
  Chart4.Show;

  Chart1.AddSeries( TLineSeries );
  Chart2.AddSeries( TLineSeries );
  Chart3.AddSeries( TLineSeries );
  Chart4.AddSeries( TLineSeries );

  Chart1[0].FillSampleValues();
  Chart2[0].FillSampleValues();
  Chart3[0].FillSampleValues();
  Chart4[0].FillSampleValues();

  Chart1.Legend.LegendStyle := lsSeries;
  Chart2.Legend.LegendStyle := lsSeries;
  Chart3.Legend.LegendStyle := lsSeries;
  Chart4.Legend.LegendStyle := lsSeries;

  Chart1.Legend.CheckBoxes := true;
  Chart2.Legend.CheckBoxes := true;
  Chart3.Legend.CheckBoxes := true;
  Chart4.Legend.CheckBoxes := true;

  Chart1.LeftAxis.Grid.Visible:=false;
  Chart2.LeftAxis.Grid.Visible:=false;
  Chart3.LeftAxis.Grid.Visible:=false;
  Chart4.LeftAxis.Grid.Visible:=false;

  Chart1.BottomAxis.Grid.Visible:=false;
  Chart2.BottomAxis.Grid.Visible:=false;
  Chart3.BottomAxis.Grid.Visible:=false;
  Chart4.BottomAxis.Grid.Visible:=false;

  Chart1.MarginUnits := muPixels;
  Chart2.MarginUnits := muPixels;
  Chart3.MarginUnits := muPixels;
  Chart4.MarginUnits := muPixels;

  Chart1.MarginLeft:=50;
  Chart2.MarginLeft:=50;
  Chart3.MarginLeft:=50;
  Chart4.MarginLeft:=50;

  Chart1.LeftAxis.LabelsSize:=30;
  Chart2.LeftAxis.LabelsSize:=30;
  Chart3.LeftAxis.LabelsSize:=30;
  Chart4.LeftAxis.LabelsSize:=30;
end;
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Arne Jakobsen
Newbie
Newbie
Posts: 3
Joined: Fri Sep 16, 2005 4:00 am

Post by Arne Jakobsen » Fri Sep 01, 2006 11:14 am

Thank You for yoyr reply

If I change the series a litle bit, by for instance changing:

Chart1.AddSeries( TLineSeries );
Chart2.AddSeries( TLineSeries );
Chart3.AddSeries( TLineSeries );
Chart4.AddSeries( TLineSeries );

to

ASeries := TLineSeries.Create(Chart1);
ASeries.Title := 'Loooooooooooooong name';
ASeries.ParentChart:= Chart1;
ASeries := TLineSeries.Create(Chart2);
ASeries.Title := 'short name';
ASeries.ParentChart:= Chart2;
Chart3.AddSeries( TLineSeries );
Chart4.AddSeries( TLineSeries );

Then I am in trouble again, because the chart makes room for the legend by resizing the plot area. Can I do anything to syncronize the sizes of the plot areas in two charts? Something like:

ALeftMargin := max(Chart1.MarginLeft, Chart2.MarginLeft);
Chart1.MarginLeft := ALeftMargin;
Chart2.MarginLeft := ALeftMargin;

ARightMargin := max(Chart1.MarginRight, Chart2.MarginRight);
Chart1.MarginRight := ARightMargin;
Chart2.MarginRight := ARightMargin;

Except that it should work for the plot areas.


Best Regards and Thank You in advance
Arne Jakobsen

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Mon Sep 04, 2006 11:07 am

Hi Arne,

Then you can try doing something like this:

Code: Select all

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, TeEngine, Series, ExtCtrls, TeeProcs, Chart, StdCtrls;

type
  TForm1 = class(TForm)
    Chart1: TChart;
    Chart2: TChart;
    Series1: TLineSeries;
    Series2: TLineSeries;
    Series3: TLineSeries;
    procedure Chart1AfterDraw(Sender: TObject);
    procedure Chart2AfterDraw(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure UpdateChartMargins;
    function MaxLegendTextSize: Integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses Math;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
  UpdateChartMargins;
end;

procedure TForm1.Chart2AfterDraw(Sender: TObject);
begin
  UpdateChartMargins;
end;

procedure TForm1.UpdateChartMargins;
var
  ALeftMargin, ARightMargin: Integer;
begin
  ALeftMargin := max(Chart1.MarginLeft, Chart2.MarginLeft);
  Chart1.MarginLeft := ALeftMargin;
  Chart2.MarginLeft := ALeftMargin;

  ARightMargin:=MaxLegendTextSize*Chart1.Legend.Font.Size;

  Chart1.MarginRight:=ARightMargin;
  Chart2.MarginRight:=ARightMargin;

  Chart1.Legend.CustomPosition:=true;
  Chart1.Legend.Left := Chart1.Width - ARightMargin + 10;
  Chart1.Legend.Top := 50;

  Chart2.Legend.CustomPosition:=true;
  Chart2.Legend.Left := Chart1.Legend.Left;
  Chart2.Legend.Top := Chart1.Legend.Top;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Chart1.MarginUnits:=muPixels;
  Chart2.MarginUnits:=muPixels;

  Chart1.Legend.ResizeChart:=false;
  Chart2.Legend.ResizeChart:=false;

  Chart1.Draw;
  Chart2.Draw;
end;

function TForm1.MaxLegendTextSize: Integer;
var i,max,tmp: Integer;
begin

  max:=0;
  for i:=0 to Chart1.Legend.Items.Count - 1 do
  begin
    tmp:=StrLen(PChar(string(Chart1.Legend.Item[i].Text)));
    if tmp>max then max:=tmp;
  end;

  for i:=0 to Chart2.Legend.Items.Count - 1 do
  begin
    tmp:=StrLen(PChar(string(Chart2.Legend.Item[i].Text)));
    if tmp>max then max:=tmp;
  end;

  result:=max;
end;

end.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

SteveP
Advanced
Posts: 132
Joined: Sun Sep 07, 2003 4:00 am

Post by SteveP » Tue Sep 05, 2006 12:54 pm

How about directly assigning values to chart1.ChartRect.Left, etc. and make the two charts the same. This fixes the inner axis bounding region, so if axis label size changes with data value, the position of the inner region will remain fixed.

Arne Jakobsen
Newbie
Newbie
Posts: 3
Joined: Fri Sep 16, 2005 4:00 am

Post by Arne Jakobsen » Wed Sep 06, 2006 12:47 pm

I ended up doing something like the following:

Chart1.MarginUnits := muPixels;
Chart2.MarginUnits := muPixels;

if (Chart1.ChartRect.Left > Chart2.ChartRect.Left) then begin
Chart2.MarginLeft := Chart2.MarginLeft +
Chart1.ChartRect.Left - Chart2.ChartRect.Left;
end else if (Chart2.ChartRect.Left > Chart1.ChartRect.Left) then begin
Chart1.MarginLeft := Chart1.MarginLeft +
Chart2.ChartRect.Left - Chart1.ChartRect.Left;
end;

if (Chart1.ChartRect.Right > Chart2.ChartRect.Right) then begin
Chart1.MarginRight := Chart1.MarginRight +
Chart1.ChartRect.Right - Chart2.ChartRect.Right;
end else if (Chart2.ChartRect.Right > Chart1.ChartRect.Right) then begin
Chart2.MarginRight := Chart2.MarginRight +
Chart2.ChartRect.Right - Chart1.ChartRect.Right;
end;

Thank you for your assistance,
Arne Jakobsen

Post Reply