Page 1 of 1
adaptive use of Distance parameter
Posted: Sat Oct 05, 2024 8:16 pm
by 17598411
I am trying to make dynamic use of the new Axis.Title.Distance parameter. My code creates simple Cartesian graphs dynamically, so I know the LeftAxis's Minimum, Maximum, and Increment only at run time. I'd like to use Distance to move the title out just enough to clear the widest label. Simple code working from the precision required for Minimum, Maximum, and Increment doesn't work, because the labels might be '0', '10', ..., '90' when Minimum is -0.002 and Maximum is 95.768. After the Minimum, Maximum, and Increment have been set, is there an easy way to pull out the labels as a tStringList or, even better, are the labels already found inside a program-accessible tRect?
Re: adaptive use of Distance parameter
Posted: Mon Oct 07, 2024 3:46 am
by 17598411
I didn't mean to suggest that there was no way to get the width of the Labels column.
Code: Select all
function LabelsWidth(Chart: tCustomChart; Axis: tChartAxis): integer;
(* compute the width (in pixels) of the labels of this vertical axis.
This code ASSUMES that the longest label (in chars) will be the widest
(in pixels) *)
var
MaxLength: integer;
ThisLabelValue: real;
strLabel, strLongest: string;
SavedFont: tTeeFont;
begin (* LabelsWidth *)
SavedFont := tTeeFont.Create();
try (* must clean up SavedFont *)
MaxLength := 0;
with Axis do
begin (* Axis *)
if Minimum > 0 then
ThisLabelValue := trunc(Minimum / Increment) * Increment
else if Minimum > -Increment then
ThisLabelValue := -Increment
else
ThisLabelValue := - (trunc(abs(Minimum) / Increment) + 1) * Increment;
// here with LabelValue one Increment LESS THAN actual first label
while ThisLabelValue <= Maximum - Increment do
begin (* test next label *)
ThisLabelValue := ThisLabelValue + Increment;
strLabel := FloatToStrF(ThisLabelValue, ffGeneral, 15, 0);
if length(strLabel) > MaxLength then
begin (* found longest to date *)
strLongest := strLabel;
MaxLength := length(strLabel)
end (* found longest to date *);
end (* test next label *);
SavedFont.Assign(Chart.Canvas.Font);
Chart.Canvas.Font.Assign(LabelsFont);
Result := Chart.Canvas.TextWidth(strLongest);
Chart.Canvas.Font.Assign(SavedFont)
end (* Axis *)
finally (* must clean up SavedFont *)
SavedFont.Destroy
end (* must clean up SavedFont *)
end (* LabelsWidth *);
obviously works, but I'd like to be reassured that the same result is not trivially available from the API.
Re: adaptive use of Distance parameter
Posted: Mon Oct 07, 2024 7:41 pm
by 17598411
Distance seems to work differently on custom axes from the way it works on native axes. My demo code is in the usual place; the pertinent part of the code (starting at line 118 of
ScaleTestMain) is
Code: Select all
DistanceCorrection := StrToIntDef(lbedDistanceCorrection.Text, 0);
with chartTest do
begin (* chartTest *)
with LeftAxis do
begin (* LeftAxis *)
SetMinAndMax(LeftAxis, StrToFloat(lbedMinimum.Text), StrToFloat(lbedMaximum.Text));
PositionPercent := StrToIntDef(lbedFPositionPercent.Text, -1);
SetIncrement(LeftAxis);
Texts.MarginToAxis := StrToIntDef(lbedFMarginToAxis.Text, 0);
LeftFLabelsWidth := LabelsWidth(chartTest, LeftAxis);
lbLeftFLabelsWidth.Caption := Format('L °F labels width = %d', [LeftFLabelsWidth]);
Title.Distance := LeftFLabelsWidth - DistanceCorrection
end (* LeftAxis *);
with LeftCelsiusScale do
begin (* LeftCelsiusScale *)
AdjustLimits;
PositionPercent := StrToIntDef(lbedCPositionPercent.Text, 0);
Texts.MarginToAxis := StrToIntDef(lbedCLabelsMargin.Text, 0);
LeftCLabelsWidth := LabelsWidth(chartTest, LeftCelsiusScale);
lbLeftCLabelsWidth.Caption := Format('L °C labels width = %d', [LeftCLabelsWidth]);
Title.Distance := LeftCLabelsWidth - DistanceCorrection
end (* LeftCelsiusScale *);
and the pertinent part of the resulting form is
- Screenshot 2024-10-07 123342.jpg (124.75 KiB) Viewed 24431 times
Here the
°F title is obviously closer to the red labels than the
°C title is to the blue labels, even though the widths of the two label columns are the same. What am I missing?
Re: adaptive use of Distance parameter
Posted: Tue Oct 08, 2024 6:43 pm
by 17598411
In previous post, it was impolite of me to not explicitly say where my demo code is. It is at
https://www.fenichel.net/programs/ScaleTest.zip
Re: adaptive use of Distance parameter
Posted: Thu Oct 10, 2024 2:44 pm
by yeray
Hello,
I've found you've set the LeftAxis.LabelsSize
to 12
at design time, which affects the calculations of the margins to be applied.
Setting it to 0
as per default seems to fix the issue for me here.
It was tricky to find it.
If you think you've found a bug, arranging a simple example project we can run as-is here, with the minimum code to reproduce that specific issue, helps a lot and minimizes the time to the resolution.
Thanks in advance.
Re: adaptive use of Distance parameter
Posted: Thu Oct 10, 2024 7:43 pm
by 17598411
I thought that the <Axis>.Labels.Font.Size slider in the Chart Editor
- chart editor.jpg (54.52 KiB) Viewed 22822 times
was connected to the <Axis>.LabelSize entry in the Object Inspector
- object inspector.jpg (123.04 KiB) Viewed 22822 times
Now I'm curious: What is the Object Inspector entry for?
Re: adaptive use of Distance parameter
Posted: Fri Oct 11, 2024 7:49 am
by yeray
Hello,
These are two different properties:
TChartAxis.LabelsFont.Size
and
TChartAxis.LabelsSize
.
Both can be found in the object inspector:
- LabelsFontSize_LabelsSize_inspector.png (23.22 KiB) Viewed 22504 times
And also in the editor:
- LabelsSize_editor.png (27.14 KiB) Viewed 22504 times
- LabelsFontSize_editor.png (26.68 KiB) Viewed 22504 times