### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Scale: Missing Min and Max indication when Chart.Margins.Left/Right=0  (Read 741 times)

#### CM630

• Hero Member
• Posts: 941
• Не съм сигурен, че те разбирам.
##### Scale: Missing Min and Max indication when Chart.Margins.Left/Right=0
« on: January 12, 2021, 05:53:28 pm »

When I place a TAchart on a form and execute the code below the minimum and maximum values of the X scale (0 and 0,4) are not displayed.
It occurs that this is caused by Chart.Margins.Left:=0; and
Chart.Margins.Right:=0;. If I set Chart.Margins.Left:=1; and Chart.Margins.Right:=1; the problem is gone.
Is there a way to have a normal scale with Chart.Margins.Left/Right=0; ?

Code: Pascal  [Select][+][-]
1. procedure TForm1.FormCreate(Sender: TObject);
2. begin
3.   Chart.Extent.UseXMax:=True;
4.   Chart.Extent.UseXMin:=True;
5.   Chart.Extent.UseYMax:=True;
6.   Chart.Extent.UseYMin:=True;
7.   Chart.Extent.XMin:=0;
8.   Chart.Extent.XMax:=0.4;
9.   Chart.Extent.YMin:=0;
10.   Chart.Extent.YMax:=0.4;
11.   Chart.Margins.Top:=0;
12.   Chart.Margins.Bottom:=0;
13.   Chart.MarginsExternal.Left:=20;
14.   chart.LeftAxis.Margin:=0;
15.   Chart.LeftAxis.Title.Margins.Left:=0;
16.   Chart.LeftAxis.Title.Distance:=0;
17.
18.
19.   //Next two problem remove the Mn and Max values of the X scale.
20.   Chart.Margins.Left:=0;
21.   Chart.Margins.Right:=0;
22. end;
« Last Edit: January 12, 2021, 09:44:53 pm by CM630 »
Лазар 2,0,12; W10 64bit; FPC3,2,0; rev 64642

#### wp

• Hero Member
• Posts: 8367
##### Re: Scale: Missing Min and Max indication when Chart.Margins.Left/Right=0
« Reply #1 on: January 12, 2021, 06:36:13 pm »
Maybe there is some round-off error when the label positions are calculated. You know: in floating point calculations 0 is not necessarily equal to 0. It works for me when I set Chart.Extent.XMin = -1E-12. I cannot comment on Xmax which is working for me out of the box, but maybe you must apply a tiny offset there too (add it in this case)
« Last Edit: January 12, 2021, 07:14:42 pm by wp »
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

#### CM630

• Hero Member
• Posts: 941
• Не съм сигурен, че те разбирам.
##### Re: Scale: Missing Min and Max indication when Chart.Margins.Left/Right=0
« Reply #2 on: January 12, 2021, 09:44:11 pm »
I am aware that float integers are never integers, though I am not sure if 0 and 2 are the only exceptions.
But for some reason when Chart.Margins.Right/Left are changed zero<-> nonzero the scale is recalculated, and when Chart.Margins.Top/Bottom are changed the scale is not recalculated, as it can be seen from the attached snippet.
Лазар 2,0,12; W10 64bit; FPC3,2,0; rev 64642

#### wp

• Hero Member
• Posts: 8367
##### Re: Scale: Missing Min and Max indication when Chart.Margins.Left/Right=0
« Reply #3 on: January 12, 2021, 11:20:28 pm »
Calculation of the scaling factors is a quite complex iterative process, because when the available chart size changes (for example by changing Margins), the labels may change and thus change the available chart size in turn and so on.

Trying to fix this labeling issue is an operation in the heart of TAChart, and the chance to break something is very high. The last time I worked in this context I was busy for weeks. So please, either accept the situation or work around it by expanding the labeled axis range by a tiny epsilon as explained above.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

#### CM630

• Hero Member
• Posts: 941
• Не съм сигурен, че те разбирам.
##### Re: Scale: Missing Min and Max indication when Chart.Margins.Left/Right=0
« Reply #4 on: January 13, 2021, 08:55:49 am »

Thank you for the assistance.
...work around it by expanding the labeled axis range by a tiny epsilon as explained above...
If I get you right, the tiny epsilon has to be applied for each value manually, until a result is achieved, so it is not applicable for dynamically changing scales. So I will stick to
Code: Pascal  [Select][+][-]
1.   Chart.Margins.Left:=1;
2.   Chart.Margins.Right:=1;
Лазар 2,0,12; W10 64bit; FPC3,2,0; rev 64642

#### wp

• Hero Member
• Posts: 8367
##### Re: Scale: Missing Min and Max indication when Chart.Margins.Left/Right=0
« Reply #5 on: January 13, 2021, 09:47:51 am »
Sorry, I don't understand what you want to achieve. Force the axis to begin and end at a given value and to place the first/last labels immediately at the begin/end of the axis? In this case the axis limits must be input by the user, and I don't see a problem to subtract/add an epsilon. Here is an example in which the user can enter the axis limit in edit controls:

Code: Pascal  [Select][+][-]
1. uses
2.   TAChartUtils;
3.
4. procedure TForm1.Button1Click(Sender: TObject);
5. const
6.   EPS = 1E-9;
7. var
8.   ext: TDoubleRect;
9. begin
10.   ext.a.x := StrToFloat(EditXMin.Text) - EPS;
11.   ext.b.x := StrToFloat(EditXMax.Text) + EPS;
12.   ext.a.y := StrToFloat(EditYMin.Text) - EPS;
13.   ext.b.y := StrToFloat(EditYMax.Text) + EPS;
14.   Chart1.Extent.FixTo(ext);
15. end;
But this works only when the first and/or last labels are integer multiples of the interval length that the chart determines. Suppose the user wants the axis to begin at 0 and to end at 0.39. Then the final label will not be drawn when the interval length is determined to be 0.02, 0.05, 0.1, for example.

Automatic labeling is very complex, and will probably fail if you have certain restrictions in mind. In this case, calculate the labels yourself and store them in a ChartListSource which you attach to the Marks.Source of the axis.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

#### CM630

• Hero Member
• Posts: 941
• Не съм сигурен, че те разбирам.
##### Re: Scale: Missing Min and Max indication when Chart.Margins.Left/Right=0
« Reply #6 on: January 14, 2021, 08:05:02 am »

I think I've got it now: When Chart.Margins.Left:=1; TaChart considers Chart.Extent.XMin:=0 for 0 - ε, and when Chart.Margins.Left:=0; it considers it for 0 + ε. And because Chart.Extent.XMin:=0+ε > 0, the 0 is not shown on the scale, because it is out of it.

I have tried to apply
Code: Pascal  [Select][+][-]
1.   ext.a.x := StrToFloat(EditXMin.Text) - EPS;
2.   ext.b.x := StrToFloat(EditXMax.Text) + EPS;
3.   ext.a.y := StrToFloat(EditYMin.Text) - EPS;
4.   ext.b.y := StrToFloat(EditYMax.Text) + EPS;
5.
It works for the 0 but not for the 0,4. I suppose that it can be handled with Chart.BottomAxis.Marks.Source := TListChartSource; but there is another complication- I have to buffer the desired values of the extents, because I cannot read them back from the chart.
So,it seems there is a solution, but for now, I will stick to
Code: Pascal  [Select][+][-]
1.   Chart.Margins.Left:=0;
2.   Chart.Margins.Right:=0;
3.
Thanks once again!
« Last Edit: January 14, 2021, 08:06:59 am by CM630 »
Лазар 2,0,12; W10 64bit; FPC3,2,0; rev 64642