mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-22 13:39:30 +02:00
TAChart: Extract TAxisCoeffHelper object
git-svn-id: trunk@27068 -
This commit is contained in:
parent
7778ac45a5
commit
2fd8c5370e
@ -232,6 +232,23 @@ type
|
||||
read FOnVisitSources write FOnVisitSources;
|
||||
end;
|
||||
|
||||
TAxisConvFunc = function (AX: Integer): Double of object;
|
||||
|
||||
{ TAxisCoeffHelper }
|
||||
|
||||
TAxisCoeffHelper = object
|
||||
FAxis: TChartAxis;
|
||||
FImageLo, FImageHi, FMarginLo, FMarginHi: Integer;
|
||||
FLo, FHi: Integer;
|
||||
FMin, FMax: PDouble;
|
||||
constructor Init(
|
||||
AAxis: TChartAxis; AImageLo, AImageHi, AMarginLo, AMarginHi: Integer;
|
||||
AMin, AMax: PDouble);
|
||||
function CalcScale(ASign: Integer): Double;
|
||||
function CalcOffset(AScale: Double): Double;
|
||||
procedure UpdateMinMax(AConv: TAxisConvFunc);
|
||||
end;
|
||||
|
||||
function SideByAlignment(
|
||||
var ARect: TRect; AAlignment: TChartAxisAlignment; ADelta: Integer): Integer;
|
||||
function TransformByAxis(
|
||||
@ -838,6 +855,44 @@ begin
|
||||
a.FAlignment := AXIS_INDEX[AIndex];
|
||||
end;
|
||||
|
||||
{ TAxisCoeffHelper }
|
||||
|
||||
constructor TAxisCoeffHelper.Init(
|
||||
AAxis: TChartAxis; AImageLo, AImageHi, AMarginLo, AMarginHi: Integer;
|
||||
AMin, AMax: PDouble);
|
||||
begin
|
||||
FAxis := AAxis;
|
||||
FImageLo := AImageLo;
|
||||
FImageHi := AImageHi;
|
||||
FMarginLo := AMarginLo;
|
||||
FMarginHi := AMarginHi;
|
||||
FMin := AMin;
|
||||
FMax := AMax;
|
||||
FLo := FImageLo + FMarginLo;
|
||||
FHi := FImageHi + FMarginHi;
|
||||
end;
|
||||
|
||||
function TAxisCoeffHelper.CalcScale(ASign: Integer): Double;
|
||||
begin
|
||||
if (FMax^ = FMin^) or (Sign(FHi - FLo) <> ASign) then exit(1.0);
|
||||
if (FAxis <> nil) and FAxis.Inverted then
|
||||
Exchange(FLo, FHi);
|
||||
Result := (FHi - FLo) / (FMax^ - FMin^);
|
||||
end;
|
||||
|
||||
function TAxisCoeffHelper.CalcOffset(AScale: Double): Double;
|
||||
begin
|
||||
Result := (FLo + FHi) / 2 - AScale * (FMin^ + FMax^) / 2;
|
||||
end;
|
||||
|
||||
procedure TAxisCoeffHelper.UpdateMinMax(AConv: TAxisConvFunc);
|
||||
begin
|
||||
FMin^ := AConv(FImageLo);
|
||||
FMax^ := AConv(FImageHi);
|
||||
if (FAxis <> nil) and FAxis.Inverted then
|
||||
Exchange(FMin^, FMax^);
|
||||
end;
|
||||
|
||||
procedure SkipObsoleteAxisProperties;
|
||||
const
|
||||
TRANSFORM_NOTE = 'Obsolete, use Transformations instead';
|
||||
|
@ -521,45 +521,21 @@ begin
|
||||
end;
|
||||
|
||||
procedure TChart.CalculateTransformationCoeffs(const AMargin: TRect);
|
||||
type
|
||||
TConvFunc = function (AX: Integer): Double of object;
|
||||
|
||||
procedure CalcOneCoord(
|
||||
AAxis: TChartAxis; AConv: TConvFunc; var AGraphMin, AGraphMax: Double;
|
||||
AImageLo, AImageHi, AMarginLo, AMarginHi, ASign: Integer;
|
||||
out AScale, AOffset: Double);
|
||||
var
|
||||
lo, hi: Integer;
|
||||
begin
|
||||
lo := AImageLo + AMarginLo;
|
||||
hi := AImageHi + AMarginHi;
|
||||
|
||||
if (AGraphMax = AGraphMin) or (Sign(hi - lo) <> ASign) then begin
|
||||
AScale := 1;
|
||||
AOffset := 0;
|
||||
exit;
|
||||
end;
|
||||
|
||||
if (AAxis <> nil) and AAxis.Inverted then
|
||||
Exchange(lo, hi);
|
||||
|
||||
AScale := (hi - lo) / (AGraphMax - AGraphMin);
|
||||
AOffset := hi - AScale * AGraphMax;
|
||||
AGraphMin := AConv(AImageLo);
|
||||
AGraphMax := AConv(AImageHi);;
|
||||
if (AAxis <> nil) and AAxis.Inverted then
|
||||
Exchange(AGraphMin, AGraphMax);
|
||||
end;
|
||||
|
||||
var
|
||||
rX, rY: TAxisCoeffHelper;
|
||||
begin
|
||||
CalcOneCoord(
|
||||
BottomAxis, @XImageToGraph, FCurrentExtent.a.X, FCurrentExtent.b.X,
|
||||
FClipRect.Left, FClipRect.Right, AMargin.Left, -AMargin.Right, 1,
|
||||
FScale.X, FOffset.X);
|
||||
CalcOneCoord(
|
||||
LeftAxis, @YImageToGraph, FCurrentExtent.a.Y, FCurrentExtent.b.Y,
|
||||
FClipRect.Bottom, FClipRect.Top, -AMargin.Bottom, AMargin.Top, -1,
|
||||
FScale.Y, FOffset.Y);
|
||||
rX.Init(
|
||||
BottomAxis, FClipRect.Left, FClipRect.Right, AMargin.Left, -AMargin.Right,
|
||||
@FCurrentExtent.a.X, @FCurrentExtent.b.X);
|
||||
rY.Init(
|
||||
LeftAxis, FClipRect.Bottom, FClipRect.Top, -AMargin.Bottom, AMargin.Top,
|
||||
@FCurrentExtent.a.Y, @FCurrentExtent.b.Y);
|
||||
FScale.X := rX.CalcScale(1);
|
||||
FScale.Y := rY.CalcScale(-1);
|
||||
FOffset.X := rX.CalcOffset(FScale.X);
|
||||
FOffset.Y := rY.CalcOffset(FScale.Y);
|
||||
rX.UpdateMinMax(@XImageToGraph);
|
||||
rY.UpdateMinMax(@YImageToGraph);
|
||||
end;
|
||||
|
||||
procedure TChart.Clean(ACanvas: TCanvas; ARect: TRect);
|
||||
@ -637,14 +613,14 @@ begin
|
||||
end;
|
||||
|
||||
AxisList.PrepareGroups;
|
||||
AxisList.Measure(ACanvas, FCurrentExtent, true, axisMargin);
|
||||
AxisList.Measure(ACanvas, CurrentExtent, true, axisMargin);
|
||||
axisMargin[calLeft] := Max(axisMargin[calLeft], Depth);
|
||||
axisMargin[calBottom] := Max(axisMargin[calBottom], Depth);
|
||||
for a := Low(a) to High(a) do
|
||||
SideByAlignment(FClipRect, a, -axisMargin[a]);
|
||||
|
||||
CalculateTransformationCoeffs(GetMargins(ACanvas));
|
||||
AxisList.Measure(ACanvas, FCurrentExtent, false, axisMargin);
|
||||
AxisList.Measure(ACanvas, CurrentExtent, false, axisMargin);
|
||||
|
||||
// Background
|
||||
with ACanvas do begin
|
||||
@ -657,7 +633,7 @@ begin
|
||||
Rectangle(Left, Top, Right + 1, Bottom + 1);
|
||||
end;
|
||||
|
||||
AxisList.Draw(ACanvas, FCurrentExtent, Self, FClipRect);
|
||||
AxisList.Draw(ACanvas, CurrentExtent, Self, FClipRect);
|
||||
// Z axis
|
||||
if Depth > 0 then
|
||||
with FClipRect do
|
||||
|
Loading…
Reference in New Issue
Block a user