SubChart’s Series disappear

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Christopher
Guru
Posts: 1325
Joined: Fri Nov 15, 2002 12:00 am

Re: SubChart’s Series disappear

Post by Christopher » Thu Aug 13, 2020 11:06 am

Hello!
xsLiu wrote:
Thu Aug 13, 2020 1:28 am
If Charts have Margins (MarginTop, MarginBottom, MarginLeft, MarginRight) and Axes have Offsets (MinimumOffset, MaximumOffset), how to modify the code ?
The Margins require no code change, as they automatically change the ChartRect size - the Offsets do require a change, as they affect the values of pixelXUnit and pixelYUnit. In the following code, press Button1 to make changes and then the modified Button2 to see the results:

Code: Select all

procedure TForm1.Button1Click(Sender: TObject);
begin
    //VCLTee.EditChar.EditChart(Self, Chart1);
    Chart1.MarginUnits:=muPixels;
    Chart1.MarginBottom:=40;
    Chart1.MarginTop:=40;
    Chart1.MarginLeft:=40;
    Chart1.MarginRight:=40;

    Chart1.Axes.Left.MinimumOffset:=20;
    Chart1.Axes.Left.MaximumOffset:=20;
    Chart1.Axes.Bottom.MinimumOffset:=20;
    Chart1.Axes.Bottom.MaximumOffset:=20;
end;

procedure TForm1.Button2Click(Sender: TObject);
var charRect, subRect : TRect;
    pixelXUnit,pixelYUnit:Double;
    subBottomMax,subLeftMax:Double;
begin
    charRect:=Chart1.ChartRect;
    subRect:=SubChart.ChartRect;

    pixelXUnit:=(Chart1.Axes.Bottom.Maximum-Chart1.Axes.Bottom.Minimum)/(charRect.Width-Chart1.Axes.Bottom.MinimumOffset-Chart1.Axes.Bottom.MaximumOffset);
    pixelYUnit:=(Chart1.Axes.Left.Maximum-Chart1.Axes.Left.Minimum)/(charRect.Height-Chart1.Axes.Left.MinimumOffset-Chart1.Axes.Left.MaximumOffset);

    subBottomMax:=pixelXUnit*subRect.Width;
    subLeftMax:=pixelYUnit*subRect.Height;

    SubChart.Axes.Bottom.SetMinMax(Chart1.Axes.Bottom.Minimum, subBottomMax);
    SubChart.Axes.Left.SetMinMax(Chart1.Axes.Left.Minimum, subLeftMax);
end;
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

xsLiu
Newbie
Newbie
Posts: 29
Joined: Wed May 22, 2019 12:00 am

Re: SubChart’s Series disappear

Post by xsLiu » Fri Aug 14, 2020 2:38 am

Your code makes it clear to me how to get SubChart.ChartRect. Really helpful, thanks a lot!!

In my app, the position (SubChart.Left, SubChart.Top) and size (SubChart.Width, SubChart.Height) of the SubChart are unkown at the beginning. I’m trying to display the SubChart by using SubChart.ChartRect as following, but the SubChart does not show its Series as mentioned earlier.
SubChart.CustomChartRect := true;
SubChart.ChartRect := TeeRect(SubLeft, SubTop, SubRight, SubBottom);
It seems that SubChart’s position/size and SubChart.ChartRect are different. If the values (Width, Height, etc.) of SubChart.ChartRect are assigned directly to that of SubChart, the pixel length are not exactly the same for both Chart and SubChart.
Is there any way to determine the position and size of the SubChart with SubChart.ChartRect?

Christopher
Guru
Posts: 1325
Joined: Fri Nov 15, 2002 12:00 am

Re: SubChart’s Series disappear

Post by Christopher » Fri Aug 14, 2020 12:08 pm

Hello,
Is there any way to determine the position and size of the SubChart with SubChart.ChartRect?
No, not really, because they are two different things. One thing is the position of the TWinControl relative to its parent (Left,Top) and its size (Width,Height), and another thing is the size of the area enclosed by the Chart axes (which is the ChartRect). You can see that if you run a TChart without a series added to it, the ChartRect is empty - this is becuase the series defines the axes, and the length of the axes define the ChartRect. So the ChartRect of your SubChart will be empty until you add a series to it.

What this means, in practice, is that the calculations in my example should be run at the same time as you add a series to your SubChart - as soon as you've added the series, you can call Repaint and obtain the values for ChartRect, e.g. (click Button1 then Button2)

Code: Select all

unit ChartTest;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VclTee.TeeGDIPlus, VCLTee.TeEngine,
  Vcl.ExtCtrls, VCLTee.TeeProcs, VCLTee.Chart, Vcl.StdCtrls, VCLTee.TeeWorldSeries, VCLTee.Series,
  VCLTee.TeeURL, VCLTee.TeeSeriesTextEd, VCLTee.TeeSubChart, VCLTee.EditChar;

type
  TForm1 = class(TForm)
    Chart1: TChart;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Chart1AfterDraw(Sender: TObject);
    procedure SubChartAfterDraw(Sender: TObject);
  private
    SubChartTool: TSubChartTool;
    SubChart: TChart;
    procedure AddSubChart(Resize: Boolean = True; AddSeries: Boolean = True);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AddSubChart(Resize: Boolean; AddSeries: Boolean);
var t:Integer;
    rnd:Double;
begin
    SubChartTool:=TSubChartTool.Create(Self);
    Chart1.Tools.Add(SubChartTool);

    SubChart:=SubChartTool.Charts.AddChart('SubChart');

    if Resize then
    begin
        SubChart.View3D:=false;
        SubChart.Height:=300;
        SubChart.Width:=400;
        SubChart.Top:=10;
        SubChart.Left:=Chart1.Width-SubChart.Width-10;
    end;

    if AddSeries then
    begin
        SubChart.AddSeries(TLineSeries).FillSampleValues;
    end;

    SubChart.OnAfterDraw:=SubChartAfterDraw;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
    AddSubChart;

    Chart1.Repaint;

    ShowMessage('SubChart ChartRect: Width ' + IntToStr(SubChart.ChartRect.Width) );
end;

procedure TForm1.Button2Click(Sender: TObject);
var charRect, subRect : TRect;
    pixelXUnit,pixelYUnit:Double;
    subBottomMax,subLeftMax:Double;
begin
    if SubChart <> nil then
    begin
        charRect:=Chart1.ChartRect;
        subRect:=SubChart.ChartRect;

        pixelXUnit:=(Chart1.Axes.Bottom.Maximum-Chart1.Axes.Bottom.Minimum)/(charRect.Width-Chart1.Axes.Bottom.MinimumOffset-Chart1.Axes.Bottom.MaximumOffset);
        pixelYUnit:=(Chart1.Axes.Left.Maximum-Chart1.Axes.Left.Minimum)/(charRect.Height-Chart1.Axes.Left.MinimumOffset-Chart1.Axes.Left.MaximumOffset);

        subBottomMax:=pixelXUnit*subRect.Width;
        subLeftMax:=pixelYUnit*subRect.Height;

        SubChart.Axes.Bottom.SetMinMax(Chart1.Axes.Bottom.Minimum, subBottomMax);
        SubChart.Axes.Left.SetMinMax(Chart1.Axes.Left.Minimum, subLeftMax);
    end;
end;

procedure TForm1.SubChartAfterDraw(Sender: TObject);
var subX1,subX2:Integer;

  procedure DoBottomAxes;
  begin
      subX1:=SubChart.Axes.Bottom.CalcXPosValue(1);
      subX2:=SubChart.Axes.Bottom.CalcXPosValue(2);

      SubChart.Canvas.Pen.Color:=clRed;
      SubChart.Canvas.Pen.Width:=3;
      SubChart.Canvas.Line(subX1, SubChart.ChartRect.Bottom, subX2, SubChart.ChartRect.Bottom);
      SubChart.Canvas.Font.Color:=clRed;
      SubChart.Canvas.TextOut(subX1, SubChart.ChartRect.Bottom-20, 'Pixels: '+IntToStr(subX2-subX1));
  end;

  procedure DoLeftAxes;
  begin
      subX1:=SubChart.Axes.Left.CalcYPosValue(Chart1.Axes.Left.Minimum);
      subX2:=SubChart.Axes.Left.CalcYPosValue(Chart1.Axes.Left.Minimum + 50);

      SubChart.Canvas.Pen.Color:=clBlue;
      SubChart.Canvas.Pen.Width:=3;
      SubChart.Canvas.Line(SubChart.ChartRect.Left, subX1, SubChart.ChartRect.Left, subX2);
      SubChart.Canvas.Font.Color:=clBlue;
      SubChart.Canvas.TextOut(SubChart.ChartRect.Left+5, subX2, 'Pixels: '+IntToStr(subX1-subX2));
  end;
begin
    DoBottomAxes;
    DoLeftAxes;
end;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var charX1,charX2:Integer;

  procedure DoBottomAxes;
  begin
      charX1:=Chart1.Axes.Bottom.CalcXPosValue(1);
      charX2:=Chart1.Axes.Bottom.CalcXPosValue(2);

      Chart1.Canvas.Pen.Color:=clRed;
      Chart1.Canvas.Pen.Width:=3;
      Chart1.Canvas.Line(charX1, Chart1.ChartRect.Bottom, charX2, Chart1.ChartRect.Bottom);
      Chart1.Canvas.Font.Color:=clRed;
      Chart1.Canvas.TextOut(charX1, Chart1.ChartRect.Bottom - 20, 'Pixels: '+IntToStr(charX2-charX1));
  end;

  procedure DoLeftAxes;
  begin
      charX1:=Chart1.Axes.Left.CalcYPosValue(Chart1.Axes.Left.Minimum);
      charX2:=Chart1.Axes.Left.CalcYPosValue(Chart1.Axes.Left.Minimum + 50);

      Chart1.Canvas.Pen.Color:=clBlue;
      Chart1.Canvas.Pen.Width:=3;
      Chart1.Canvas.Line(Chart1.ChartRect.Left, charX1, Chart1.ChartRect.Left, charX2);
      Chart1.Canvas.Font.Color:=clBlue;
      Chart1.Canvas.TextOut(Chart1.ChartRect.Left+5, charX2, 'Pixels: '+IntToStr(charX1-charX2));
  end;
begin
    DoBottomAxes;
    DoLeftAxes;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    Chart1.OnAfterDraw:=Chart1AfterDraw;
    Chart1.AddSeries(TLineSeries).FillSampleValues;
end;

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

xsLiu
Newbie
Newbie
Posts: 29
Joined: Wed May 22, 2019 12:00 am

Re: SubChart’s Series disappear

Post by xsLiu » Sat Aug 15, 2020 9:59 am

My problems have been basically solved, except SubChart is roughly positioned.
Thanks for your clear explanations and detailed codes.

Post Reply