Recent

Author Topic: Can I get the position and size of an axis title?  (Read 5011 times)

CM630

  • Hero Member
  • *****
  • Posts: 1681
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Can I get the position and size of an axis title?
« Reply #15 on: April 21, 2026, 07:29:22 am »
Indeed, inversion works with Transformations.
But it occurs that GetIndexOfFirstVisibleMark returns a wrong result when a transformation with .Scale ≠ |1|.

Code: Pascal  [Select][+][-]
  1. ...
  2. procedure TForm1.Button1Click(Sender:TObject);
  3. begin
  4.   ChartAxisTransformations1LinearAxisTransform1.Scale := 1; //Returns 1, as it should
  5.   Chart1.Invalidate;
  6.   Application.ProcessMessages;
  7.   ShowMessage (IntToStr(  Chart1.BottomAxis.GetIndexOfFirstVisibleMark));
  8. end;
  9.  
  10. procedure TForm1.Button2Click(Sender:TObject);
  11. begin
  12.   ChartAxisTransformations1LinearAxisTransform1.Scale := 0.1;
  13.   Chart1.Invalidate;
  14.   Application.ProcessMessages ;
  15.   ShowMessage (IntToStr(Chart1.BottomAxis.GetIndexOfFirstVisibleMark)); //Returns 6 instead of 1
  16. end;
  17.  
  18. ...
  19.  
  20.  
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

CM630

  • Hero Member
  • *****
  • Posts: 1681
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Can I get the position and size of an axis title?
« Reply #16 on: May 11, 2026, 03:31:19 pm »
Some changes in TAChartAxis seem to make things better:

Code: Pascal  [Select][+][-]
  1. function TChartAxis.GetIndexOfFirstVisibleMark(aOffset: double = 0; aScale: double=1): Integer;
  2. var
  3.   coord: Integer;
  4. begin
  5.   for Result := 0 to High(FMarkValues) do begin
  6.     coord := FHelper.GraphToImage(FMarkValues[Result].FValue*aScale + aOffset);
  7.     if FHelper.IsInClipRange(coord) then
  8.       exit;
  9.   end;
  10.   Result := -1;
  11. end;
  12.  
  13. function TChartAxis.GetIndexOfLastVisibleMark(aOffset: double = 0; aScale: double=1): Integer;
  14. var
  15.   coord: Integer;
  16. begin
  17.   for Result := High(FMarkValues) downto 0 do begin
  18.     coord := FHelper.GraphToImage(FMarkValues[Result].FValue*aScale + aOffset);
  19.     if FHelper.IsInClipRange(coord) then
  20.       exit;
  21.   end;
  22.   Result := -1;
  23. end;    

Usage:
Code: Pascal  [Select][+][-]
  1.   ShowMessage (IntToStr(Chart1.BottomAxis.GetIndexOfFirstVisibleMark(ChartAxisTransformations1LinearAxisTransform1.Offset,ChartAxisTransformations1LinearAxisTransform1.Scale)));
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

CM630

  • Hero Member
  • *****
  • Posts: 1681
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Can I get the position and size of an axis title?
« Reply #17 on: May 12, 2026, 08:38:48 am »
This should be even better:

Code: Pascal  [Select][+][-]
  1. function TChartAxis.GetIndexOfFirstVisibleMark: Integer;
  2. var
  3.   coord: Integer;
  4.   mScale : double = 1;
  5.   mOffset : double = 0;
  6.   i: integer = 0;
  7. begin
  8.   if (FTransformations <> Nil) and (FTransformations.List.Count >0)  then
  9.   begin
  10.     for i:=0 to FTransformations.List.Count - 1 do
  11.       if ((TObject(Transformations.List.Items[i]) is TLinearAxisTransform)) and (TLinearAxisTransform(Transformations.List.Items[i]).Enabled = True) then
  12.       begin
  13.         mScale := mScale * TLinearAxisTransform(Transformations.List.Items[i]).Scale;
  14.         mOffset := mOffset * TLinearAxisTransform(Transformations.List.Items[i]).Scale + TLinearAxisTransform(Transformations.List.Items[i]).Offset;
  15.       end;
  16.   end;
  17.  
  18.   for Result := 0 to High(FMarkValues) do begin
  19.     coord := FHelper.GraphToImage(FMarkValues[Result].FValue*mScale + mOffset);
  20.     if FHelper.IsInClipRange(coord) then
  21.       exit;
  22.   end;
  23.   Result := -1;
  24. end;
  25.  
  26. function TChartAxis.GetIndexOfLastVisibleMark: Integer;
  27. var
  28.   coord: Integer;
  29.   mScale : double = 1;
  30.   mOffset : double = 0;
  31.   i: integer = 0;
  32. begin
  33.   if (FTransformations <> Nil) and (FTransformations.List.Count >0)  then
  34.   begin
  35.     for i:=0 to FTransformations.List.Count - 1 do
  36.       if ((TObject(Transformations.List.Items[i]) is TLinearAxisTransform)) and (TLinearAxisTransform(Transformations.List.Items[i]).Enabled = True) then
  37.       begin
  38.         mScale := mScale * TLinearAxisTransform(Transformations.List.Items[i]).Scale;
  39.         mOffset := mOffset * TLinearAxisTransform(Transformations.List.Items[i]).Scale + TLinearAxisTransform(Transformations.List.Items[i]).Offset;
  40.       end;
  41.   end;
  42.  
  43.   for Result := High(FMarkValues) downto 0 do begin
  44.     coord := FHelper.GraphToImage(FMarkValues[Result].FValue * mScale + mOffset);
  45.     if FHelper.IsInClipRange(coord) then
  46.       exit;
  47.   end;
  48.   Result := -1;
  49. end;  
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

wp

  • Hero Member
  • *****
  • Posts: 13508
Re: Can I get the position and size of an axis title?
« Reply #18 on: Today at 12:05:48 am »
Please check out the new version of TChartAxis.GetIndexOfFirst/LastVisibleAxisMark in the Laz/main repository. The issue was that the indices were searched by conversion of the label values from graph to image coordinates, but this is correct only when no axis transform is involved because label values always are in axis coordinates - the conversion from axis to graph coordinates was missing in my old code. The full combination of all involved axis transformations, in the correct order, can be found from the GetTransform method of the axis.

In the attachment you can find a small project which combines a logarithmic and a linear (inverting) axis transformation (it works correctly only with the new TAChart revision).

 

TinyPortal © 2005-2018