TAChart: Extract TAxisCoeffHelper object

git-svn-id: trunk@27068 -
This commit is contained in:
ask 2010-08-12 12:11:25 +00:00
parent 7778ac45a5
commit 2fd8c5370e
2 changed files with 72 additions and 41 deletions

View File

@ -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';

View File

@ -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