TAChart: Extract GetIntervals function

git-svn-id: trunk@20403 -
This commit is contained in:
ask 2009-06-04 15:08:28 +00:00
parent ee6572eea6
commit b13a1bbcb0
2 changed files with 53 additions and 67 deletions

View File

@ -126,6 +126,8 @@ procedure Exchange(var A, B: TDoublePoint); overload;
// True if float ranges [A, B] and [C, D] have at least one common point. // True if float ranges [A, B] and [C, D] have at least one common point.
function FloatRangesOverlap(A, B, C, D: Double): Boolean; inline; function FloatRangesOverlap(A, B, C, D: Double): Boolean; inline;
function GetIntervals(AMin, AMax: Double; AInverted: Boolean): TDoubleDynArray;
function PointDist(const A, B: TPoint): Integer; inline; function PointDist(const A, B: TPoint): Integer; inline;
function PointDistX(const A, B: TPoint): Integer; inline; function PointDistX(const A, B: TPoint): Integer; inline;
function PointDistY(const A, B: TPoint): Integer; inline; function PointDistY(const A, B: TPoint): Integer; inline;
@ -266,6 +268,39 @@ begin
Result := (A <= D) and (C <= B); Result := (A <= D) and (C <= B);
end; end;
function GetIntervals(AMin, AMax: Double; AInverted: Boolean): TDoubleDynArray;
const
INV_TO_SCALE: array [Boolean] of TAxisScale = (asIncreasing, asDecreasing);
K = 1e-10;
var
start, step, m: Double;
markCount: Integer;
begin
CalculateIntervals(AMin, AMax, INV_TO_SCALE[AInverted], start, step);
AMin -= step * K;
AMax += step * K;
m := start;
markCount := 0;
while true do begin
if InRange(m, AMin, AMax) then
Inc(markCount)
else if markCount > 0 then
break;
m += step;
end;
SetLength(Result, markCount);
m := start;
markCount := 0;
while true do begin
if InRange(m, AMin, AMax) then begin
Result[markCount] := m;
Inc(markCount);
end
else if markCount > 0 then
break;
m += step;
end;
end;
function PointDist(const A, B: TPoint): Integer; function PointDist(const A, B: TPoint): Integer;
begin begin

View File

@ -372,7 +372,6 @@ uses
const const
CAPTION_DIST = 4; CAPTION_DIST = 4;
INV_TO_SCALE: array [Boolean] of TAxisScale = (asIncreasing, asDecreasing);
FONT_SLOPE_VERTICAL = 45 * 10; FONT_SLOPE_VERTICAL = 45 * 10;
function MarkToText(AMark: Double): String; function MarkToText(AMark: Double): String;
@ -710,62 +709,27 @@ procedure TChartAxis.Draw(
ACanvas.TextOut(AX + dx, y - sz.cy div 2, markText) ACanvas.TextOut(AX + dx, y - sz.cy div 2, markText)
end; end;
procedure DrawVertical; procedure DoDraw(AMin, AMax: Double);
var var
mark, step: Double; i, coord: Integer;
x: Integer; marks: TDoubleDynArray;
begin begin
if AExtent.a.Y = AExtent.b.Y then exit; if AMin = AMax then exit;
CalculateIntervals( marks := GetIntervals(AMin, AMax, Inverted);
AExtent.a.Y, AExtent.b.Y, INV_TO_SCALE[Inverted], mark, step); coord := SideByAlignment(ARect, Alignment, FSize);
x := SideByAlignment(ARect, Alignment, FSize); for i := 0 to High(marks) do
case INV_TO_SCALE[Inverted] of if IsVertical then
asIncreasing: DrawYMark(coord, marks[i])
while mark <= AExtent.b.Y + step * 10e-10 do begin else
if mark >= AExtent.a.Y then DrawXMark(coord, marks[i]);
DrawYMark(x, mark);
mark += step;
end;
asDecreasing:
while mark >= AExtent.a.Y - step * 10e-10 do begin
if mark <= AExtent.b.Y then
DrawYMark(x, mark);
mark -= step;
end;
end;
end;
procedure DrawHorizontal;
var
mark, step: Double;
y: Integer;
begin
if AExtent.a.X = AExtent.b.X then exit;
CalculateIntervals(
AExtent.a.X, AExtent.b.X, INV_TO_SCALE[Inverted], mark, step);
y := SideByAlignment(ARect, Alignment, FSize);
case INV_TO_SCALE[Inverted] of
asIncreasing:
while mark <= AExtent.b.X + step * 10e-10 do begin
if mark >= AExtent.a.X then
DrawXMark(y, mark);
mark += step;
end;
asDecreasing:
while mark >= AExtent.a.X - step * 10e-10 do begin
if mark <= AExtent.b.X then
DrawXMark(y, mark);
mark -= step;
end;
end;
end; end;
begin begin
if not Visible then exit; if not Visible then exit;
if IsVertical then if IsVertical then
DrawVertical DoDraw(AExtent.a.Y, AExtent.b.Y)
else else
DrawHorizontal; DoDraw(AExtent.a.X, AExtent.b.X);
end; end;
procedure TChartAxis.DrawTitle( procedure TChartAxis.DrawTitle(
@ -824,27 +788,14 @@ procedure TChartAxis.Measure(
procedure CalcVertSize; procedure CalcVertSize;
var var
mark, step: Double; i, maxWidth: Integer;
maxWidth: Integer; marks: TDoubleDynArray;
begin begin
if AExtent.a.Y = AExtent.b.Y then exit; if AExtent.a.Y = AExtent.b.Y then exit;
maxWidth := 0; maxWidth := 0;
CalculateIntervals( marks := GetIntervals(AExtent.a.Y, AExtent.b.Y, Inverted);
AExtent.a.Y, AExtent.b.Y, INV_TO_SCALE[Inverted], mark, step); for i := 0 to High(marks) do
case INV_TO_SCALE[Inverted] of maxWidth := Max(ACanvas.TextWidth(MarkToText(marks[i])), maxWidth);
asIncreasing:
while mark <= AExtent.b.Y + step * 10e-10 do begin
if mark >= AExtent.a.Y then
maxWidth := Max(ACanvas.TextWidth(MarkToText(mark)), maxWidth);
mark += step;
end;
asDecreasing:
while mark >= AExtent.a.Y - step * 10e-10 do begin
if mark <= AExtent.b.Y then
maxWidth := Max(ACanvas.TextWidth(MarkToText(mark)), maxWidth);
mark -= step;
end;
end;
// CalculateTransformationCoeffs changes axis interval, so it is possibile // CalculateTransformationCoeffs changes axis interval, so it is possibile
// that a new mark longer then existing ones is introduced. // that a new mark longer then existing ones is introduced.
// That will change marks width and reduce view area, // That will change marks width and reduce view area,