Page 1 of 2

SubChart’s Series disappear

Posted: Sun Aug 02, 2020 9:31 am
by 16586272
When SubChart changes its position and size, the Series disappear.
The program works well in Windows 7, but it goes wrong in Windows 10.
Can't figure out what the problem is?

procedure SubChart_SizePostion(var TheChart, SubChart: TChart);
const
SubChartToEdge = 0;
MinSizeRatio = 0.3;
var
tmpMin, tmpMax, SubHorizRange, SubVertRange, SubXYScreen, SubHorizAxisScale, SubVertAxisScale, SubOffset: Double;
SubLeft, SubTop, SubRight, SubBottom, SubChartWidth, SubChartHeight: integer;
begin
if (TheChart = nil) or (SubChart = nil) then { 双图 }
exit;

with TheChart do
begin
if (ChartWidth > 0) and (ChartHeight > 0) and (SeriesCount > 0) then
begin
with Series[0] do
begin
with GetHorizAxis do
SubHorizRange := Maximum - Minimum;
with GetVertAxis do
SubVertRange := Maximum - Minimum;
SubXYScreen := GetXYScreen(TheChart);
SubHorizAxisScale := (SubHorizRange / ChartWidth);
SubVertAxisScale := (SubVertRange / ChartHeight) * SubXYScreen;
end;

with SubChart.Series[0].GetHorizAxis do
begin
Automatic := true;
CalcMinMax(tmpMin, tmpMax);
SetMinMax(tmpMin, tmpMax);
SubHorizRange := Maximum - Minimum;

SubChartWidth := Round(SubHorizRange / SubHorizAxisScale);
if SubChartWidth / ChartWidth < MinSizeRatio then
SubChartWidth := Round(ChartWidth * MinSizeRatio);
SubOffset := (SubHorizAxisScale * SubChartWidth - SubHorizRange) / 2.0;
SetMinMax(tmpMin - SubOffset, tmpMax + SubOffset);
Increment := Series[0].GetHorizAxis.Increment;
end;
with SubChart.Series[0].GetVertAxis do
begin
Automatic := true;
CalcMinMax(tmpMin, tmpMax);
SetMinMax(tmpMin, tmpMax);
SubVertRange := Maximum - Minimum;

SubChartHeight := Round(SubVertRange / SubVertAxisScale);
if SubChartHeight / ChartHeight < MinSizeRatio then
SubChartHeight := Round(ChartHeight * MinSizeRatio);
SubOffset := (SubVertAxisScale * SubChartHeight / SubXYScreen - SubVertRange) / 2.0;
SetMinMax(tmpMin - SubOffset, tmpMax + SubOffset);
Increment := Series[0].GetVertAxis.Increment;
end;

SubRight := ChartRect.Right - SubChartToEdge;
SubTop := ChartRect.Top + SubChartToEdge;
SubLeft := SubRight - SubChartWidth;
SubBottom := SubTop + SubChartHeight;
with SubChart do
begin
CustomChartRect := true;
ChartRect := TeeRect(SubLeft, SubTop, SubRight, SubBottom);
end;
end;
end;
end;

Image

Re: SubChart’s Series disappear

Posted: Mon Aug 03, 2020 8:37 am
by Christopher
Hello!

I'm running Delphi 10.2 Update 3 on Windows 10 v.1903 using TeeChart Pro v2020.30.200525 32bit VCL, and using this code (click button1 then click button2):

Code: Select all

procedure TForm1.Button1Click(Sender: TObject);
var SubChart1: TSubChartTool;
    SubChart: TChart;
begin
if Chart1.Tools.Count=0 then
begin
  SubChart1:=TSubChartTool.Create(Self);
  Chart1.Tools.Add(SubChart1);
  SubChart:=SubChart1.Charts.AddChart('SubChart');
  SubChart.Title.Visible:=true;
  SubChart.Title.Text.Add('SubChart');
  SubChart.Width:=300;
  SubChart.Height:=300;
  SubChart.View3D:=false;
  SubChart.AddSeries(TBarSeries);
  SubChart[0].FillSampleValues();
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var SubChart: TChart;
begin
if Chart1.Tools.Count=1 then
begin
  SubChart:=TSubChartTool(Chart1.Tools[0]).Charts[0].Chart;
  SubChart.Left:=300;
  SubChart.Height:=100;
  SubChart.Width:=150;
  SubChart.Height:=150;
end;
end;
The SubChart resizes without losing its series as expected. Does this code work correctly for you at your end?

Re: SubChart’s Series disappear

Posted: Wed Aug 05, 2020 12:17 pm
by 16586272
Yes, it works fine.
Based on your code, I wrote a test program and it does not work. Please find attached.
Would you like to help me find out what the problems are?

Re: SubChart’s Series disappear

Posted: Wed Aug 05, 2020 2:41 pm
by Christopher
Hello,
Would you like to help me find out what the problems are?
Of course I would like to help you overcome your TeeChart problems. When I first run the app, I get this:
Project1_2020-08-05_16-38-03.png
Project1_2020-08-05_16-38-03.png (8.37 KiB) Viewed 28752 times
Is this what you would expect?

Before I start spending the time to look at the code, would you please be so kind as to tell me what you expect the app to do, and where you think the problems are?

Re: SubChart’s Series disappear

Posted: Thu Aug 06, 2020 2:01 am
by 16586272
Is this what you would expect?
Of Course Not. I corrected the code, and the chart appears.
Before I start spending the time to look at the code, would you please be so kind as to tell me what you expect the app to do, and where you think the problems are?
I developed an application before, and there were some problems on SubChart’s position and size. I extracted the main code from the app, modified it by referring to your code, and wrote this test app.
Problems are as follows:
1. SubChart does not show its Series.
2. Axis Scales of TheChart and SubChart are not equal, respectively.
3. Although TheChart and SubChart use the same functions, they have different properties. e.g. the Font and Size of Axis Title and Axis Label.
Image

Re: SubChart’s Series disappear

Posted: Thu Aug 06, 2020 3:30 pm
by Christopher
Hello,

I've made the following changes:

Code: Select all

          {with SubChart do
            begin
              CustomChartRect := true;
              ChartRect := TeeRect(SubLeft, SubTop, SubRight, SubBottom);
            end; }

          SubChart.Top:=SubTop;
          SubChart.Left:=SubLeft;
          SubChart.Width:=SubRight-SubLeft;
          SubChart.Height:=SubBottom-SubTop;
and:

Code: Select all

uses
  TeeThemes

  if SubChart <> nil then
    begin
      SubChart := TSubChartTool(SubChartTool).Charts[0].Chart;
      { Make SubChart to be isometric axis, and its Axis Scales of horizontal and vertical Axes are the same with TheChart's Axis Scales, respectively. }
      SubChart_SizePostion(TheChart, SubChart);
    end;

  with TWindowsXPTheme.Create(SubChart) do
  try
    Apply;
  finally
    Free;
  end;

  with TWindowsXPTheme.Create(TheChart) do
  try
    Apply;
  finally
    Free;
  end;
and these changes give me:
Project1_2020-08-06_17-25-33.png
Project1_2020-08-06_17-25-33.png (67.69 KiB) Viewed 28723 times
The first changes addresses your first point, and corrects the positioning of the SubChart. The second change addresses your third point and homogenizes Chart display characteristics by the application of a theme to both charts. I'm not sure about your second point, as the TheChart and SubChart contain series with different data, and so will show different axes label values.

Re: SubChart’s Series disappear

Posted: Fri Aug 07, 2020 5:35 am
by 16586272
That's just great !!!
I'm not sure about your second point, as the TheChart and SubChart contain series with different data, and so will show different axes label values.
In this app, assume that the size (width and height) of SubChart is smaller than that of TheChart.
Firstly, I want the proportional scales (HorizRange / ChartWidth, please see SubChart_SizePostion in UAxis_Iso unit. Not axes label values) of SubChart’s abscissa axis and TheChart’s horizontal axis are the same.
Secondly, based on the proportional scale of horizontal / abscissa axis (they are the same) and the range (Maximum - Minimum) of SubChart’s abscissa axis, we can get SubChart’s width.
Similarly, for SubChart’s ordinate axis and TheChart’s vertical axis, and we can get SubChart’s height.
That is to say, a curve drawn in TheChart and SubChart should be the same size.

However, I can not get the same Axis Scales (proportional scales) and correct SubChart’s size.

I updated the app by using your code. Please find attached.

Re: SubChart’s Series disappear

Posted: Fri Aug 07, 2020 8:38 am
by 16586272
The second change addresses your third point and homogenizes Chart display characteristics by the application of a theme to both charts.
By the application of a theme to both charts, Chart display characteristics have successfully homogenized. It seems that Chart display characteristics are reset to the Default Values of the selected theme.
That means that we have to reset every characteristics as expected, such as Series Color, Font Size, when applied a theme every time? Is there a way not to repeat the Settings?

Re: SubChart’s Series disappear

Posted: Fri Aug 07, 2020 9:15 am
by Christopher
Hello,
xsLiu wrote:
Fri Aug 07, 2020 5:35 am
Firstly, I want the proportional scales (HorizRange / ChartWidth, please see SubChart_SizePostion in UAxis_Iso unit. Not axes label values) of SubChart’s abscissa axis and TheChart’s horizontal axis are the same.
I'm not sure what you mean exactly by 'proportional scales', but the way I understand it would be to add something like this (but not necessarily in this particular place in the code):

Code: Select all

  if SubChart <> nil then
    begin
      SubChart := TSubChartTool(SubChartTool).Charts[0].Chart;
      { Make SubChart to be isometric axis, and its Axis Scales of horizontal and vertical Axes are the same with TheChart's Axis Scales, respectively. }
      SubChart_SizePostion(TheChart, SubChart);
      // Reset_ChartTheme(SubChart);

      SubChart.Axes.Bottom.SetMinMax(TheChart.Axes.Top.Minimum, TheChart.Axes.Top.Maximum);
    end;
xsLiu wrote:
Fri Aug 07, 2020 5:35 am
Secondly, based on the proportional scale of horizontal / abscissa axis (they are the same) and the range (Maximum - Minimum) of SubChart’s abscissa axis, we can get SubChart’s width.
Here I'm afraid I see things even less clearly - I can't see any direct mathmatical/logical necessary relationship between the scale of a Chart's axis and the size of the Chart.

Re: SubChart’s Series disappear

Posted: Fri Aug 07, 2020 9:30 am
by Christopher
Hello,
xsLiu wrote:
Fri Aug 07, 2020 5:35 am
That means that we have to reset every characteristics as expected, such as Series Color, Font Size, when applied a theme every time? Is there a way not to repeat the Settings?
TheChart and SubChart are two separate Charts - changing the Axis font size of one, for example, does not automatically change the Axis font size of the other. What you can do, however, is use Chart TEN (template) files to binary-export varaible values from one Chart to another - there's an exmple of this in the TeeNew demo:
Tee9new_2020-08-07_11-29-15.png
Tee9new_2020-08-07_11-29-15.png (176.35 KiB) Viewed 28682 times

Re: SubChart’s Series disappear

Posted: Sun Aug 09, 2020 4:19 am
by 16586272
I'm not sure what you mean exactly by 'proportional scales', but the way I understand it would be to add something like this (but not necessarily in this particular place in the code):
What I’m trying to achieve is for the SubChart to have the same scales as TheChart. For example, in the case of the image attached, have the length of a and b to be exactly the same, and the length of c and d to be the same, since they represent the same number of units.

Re: SubChart’s Series disappear

Posted: Mon Aug 10, 2020 7:51 am
by Christopher
xsLiu wrote:
Sun Aug 09, 2020 4:19 am
What I’m trying to achieve is for the SubChart to have the same scales as TheChart. For example, in the case of the image attached, have the length of a and b to be exactly the same, and the length of c and d to be the same, since they represent the same number of units.
Just to get the issue clear in my mind, if that's okay - in the image you post the two axes already have the same scales (an interval of 50 units on the left axes, and an interval of 200 units on the top and bottom axes), so I think you must be referring to the *pixel length* between, say, 350 and 400 or 200 and 400 on the different axes - is that correct?

Re: SubChart’s Series disappear

Posted: Wed Aug 12, 2020 11:52 am
by 16586272
Yes, that’s correct.

Re: SubChart’s Series disappear

Posted: Wed Aug 12, 2020 2:40 pm
by Christopher
Hello,
xsLiu wrote:
Wed Aug 12, 2020 11:52 am
Yes, that’s correct.
Okay - for clarity I've produced a new unit which attempts to make axes increments the same pixel length for both Chart and SubChart:

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;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
     VCLTee.EditChar.EditChart(Self, Chart1);
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;
    pixelYUnit:=(Chart1.Axes.Left.Maximum-Chart1.Axes.Left.Minimum)/charRect.Height;

    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;

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(0.3);
      subX2:=SubChart.Axes.Left.CalcYPosValue(0.35);

      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(0.3);
      charX2:=Chart1.Axes.Left.CalcYPosValue(0.35);

      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);
var t:Integer;
    rnd:Double;
begin
    SubChartTool:=TSubChartTool.Create(Self);
    Chart1.Tools.Add(SubChartTool);

    SubChart:=SubChartTool.Charts.AddChart('SubChart');
    SubChart.View3D:=false;
    SubChart.Height:=300;
    SubChart.Width:=400;
    SubChart.Top:=10;
    SubChart.Left:=Chart1.Width-SubChart.Width-10;

    Chart1.OnAfterDraw:=Chart1AfterDraw;
    SubChart.OnAfterDraw:=SubChartAfterDraw;

    Chart1.AddSeries(TLineSeries);
    SubChart.AddSeries(TLineSeries);

    for t:=0 to 20 do
    begin
        rnd:=Random();
        Chart1[0].Add(rnd);
        SubChart[0].Add(rnd);
    end;

    Chart1.Legend.Visible:=false;

    Chart1.Axes.Left.Increment:=0.05;
    SubChart.Axes.Left.Increment:=0.05;

    Chart1.Axes.Bottom.Increment:=1;
    SubChart.Axes.Bottom.Increment:=1;

    SubChart.Title.Visible:=true;
    SubChart.Title.Text.Add('SubTeeChart');
end;

end.
Running this gives me:
TestChart_2020-08-12_16-35-32.png
TestChart_2020-08-12_16-35-32.png (70.03 KiB) Viewed 28482 times
and then clicking on Button2 gives me:
TestChart_2020-08-12_16-35-19.png
TestChart_2020-08-12_16-35-19.png (64.17 KiB) Viewed 28482 times

Re: SubChart’s Series disappear

Posted: Thu Aug 13, 2020 1:28 am
by 16586272
Yes, it works well.
If Charts have Margins (MarginTop, MarginBottom, MarginLeft, MarginRight) and Axes have Offsets (MinimumOffset, MaximumOffset), how to modify the code ?
Thanks a lot.