TAChart: Extract TDrawFuncHelper.XRange helper function.

+ Fix GetNearestPoint for rotated function series.

git-svn-id: trunk@38729 -
This commit is contained in:
ask 2012-09-18 04:17:20 +00:00
parent 272eb740df
commit cf75819f6e

View File

@ -366,6 +366,7 @@ type
strict private strict private
type type
TOnPoint = procedure (AXg, AXa: Double) of object; TOnPoint = procedure (AXg, AXa: Double) of object;
TImageToGraph = function (AX: Integer): Double of object;
var var
FAxisToGraphXr, FAxisToGraphYr, FGraphToAxisXr: TTransformFunc; FAxisToGraphXr, FAxisToGraphYr, FGraphToAxisXr: TTransformFunc;
FCalc: TTransformFunc; FCalc: TTransformFunc;
@ -374,6 +375,7 @@ type
FDrawer: IChartDrawer; FDrawer: IChartDrawer;
FExtent: TDoubleRect; FExtent: TDoubleRect;
FGraphStep: Double; FGraphStep: Double;
FImageToGraph: TImageToGraph;
FNearestPointParams: ^TNearestPointParams; FNearestPointParams: ^TNearestPointParams;
FNearestPointResults: ^TNearestPointResults; FNearestPointResults: ^TNearestPointResults;
FMakeDP: TMakeDoublePoint; FMakeDP: TMakeDoublePoint;
@ -386,6 +388,7 @@ type
procedure ForEachPoint(AXg, AXMax: Double; AOnMoveTo, AOnLineTo: TOnPoint); procedure ForEachPoint(AXg, AXMax: Double; AOnMoveTo, AOnLineTo: TOnPoint);
procedure LineTo(AXg, AXa: Double); procedure LineTo(AXg, AXa: Double);
procedure MoveTo(AXg, AXa: Double); procedure MoveTo(AXg, AXa: Double);
function XRange: TDoubleInterval;
public public
constructor Create( constructor Create(
ASeries: TCustomChartSeries; ADomainExclusions: ASeries: TCustomChartSeries; ADomainExclusions:
@ -569,32 +572,24 @@ begin
FAxisToGraphYr := @AxisToGraphX; FAxisToGraphYr := @AxisToGraphX;
FGraphToAxisXr := @GraphToAxisY; FGraphToAxisXr := @GraphToAxisY;
FMakeDP := @DoublePointRotated; FMakeDP := @DoublePointRotated;
FGraphStep := FChart.YImageToGraph(-AStep) - FChart.YImageToGraph(0); FImageToGraph := @FChart.YImageToGraph;
AStep := -AStep;
end end
else begin else begin
FAxisToGraphXr := @AxisToGraphX; FAxisToGraphXr := @AxisToGraphX;
FAxisToGraphYr := @AxisToGraphY; FAxisToGraphYr := @AxisToGraphY;
FGraphToAxisXr := @GraphToAxisX; FGraphToAxisXr := @GraphToAxisX;
FMakeDP := @DoublePoint; FMakeDP := @DoublePoint;
FGraphStep := FChart.XImageToGraph(AStep) - FChart.XImageToGraph(0); FImageToGraph := @FChart.XImageToGraph;
end; end;
FGraphStep := FImageToGraph(AStep) - FImageToGraph(0);
end; end;
procedure TDrawFuncHelper.DrawFunction(ADrawer: IChartDrawer); procedure TDrawFuncHelper.DrawFunction(ADrawer: IChartDrawer);
var
xg, xmax: Double;
begin begin
FDrawer := ADrawer; FDrawer := ADrawer;
with FSeries do with XRange do
if IsRotated then begin ForEachPoint(FStart, FEnd, @MoveTo, @LineTo);
xg := FExtent.a.Y;
xmax := FExtent.b.Y;
end
else begin
xg := FExtent.a.X;
xmax := FExtent.b.X;
end;
ForEachPoint(xg, xmax, @MoveTo, @LineTo);
end; end;
procedure TDrawFuncHelper.ForEachPoint( procedure TDrawFuncHelper.ForEachPoint(
@ -631,24 +626,20 @@ function TDrawFuncHelper.GetNearestPoint(
const AParams: TNearestPointParams; const AParams: TNearestPointParams;
out AResults: TNearestPointResults): Boolean; out AResults: TNearestPointResults): Boolean;
var var
xg, xmax: Double; x, r: Integer;
begin begin
AResults.FIndex := -1; AResults.FIndex := -1;
AResults.FDist := Sqr(AParams.FRadius) + 1; AResults.FDist := Sqr(AParams.FRadius) + 1;
with AParams do
if FSeries.IsRotated then begin
xg := Max(FExtent.a.Y, FChart.YImageToGraph(FPoint.Y - FRadius));
xmax := Min(FExtent.b.Y, FChart.YImageToGraph(FPoint.Y + FRadius));
end
else begin
xg := Max(FExtent.a.X, FChart.XImageToGraph(FPoint.X - FRadius));
xmax := Min(FExtent.b.X, FChart.XImageToGraph(FPoint.X + FRadius));
end;
FNearestPointParams := @AParams; FNearestPointParams := @AParams;
FNearestPointResults := @AResults; FNearestPointResults := @AResults;
ForEachPoint(xg, xmax, @CheckForNearestPoint, @CheckForNearestPoint);
x := TPointBoolArr(AParams.FPoint)[FSeries.IsRotated];
r := IfThen(FSeries.IsRotated, -1, 1) * AParams.FRadius;
with XRange do
ForEachPoint(
Max(FImageToGraph(x - r), FStart),
Min(FImageToGraph(x + r), FEnd),
@CheckForNearestPoint, @CheckForNearestPoint);
Result := AResults.FDist < Sqr(AParams.FRadius) + 1; Result := AResults.FDist < Sqr(AParams.FRadius) + 1;
end; end;
@ -677,6 +668,14 @@ begin
FDrawer.MoveTo(FChart.GraphToImage(FPrev)); FDrawer.MoveTo(FChart.GraphToImage(FPrev));
end; end;
function TDrawFuncHelper.XRange: TDoubleInterval;
begin
if FSeries.IsRotated then
Result := DoubleInterval(FExtent.a.Y, FExtent.b.Y)
else
Result := DoubleInterval(FExtent.a.X, FExtent.b.X);
end;
{ TBasicFuncSeries } { TBasicFuncSeries }
procedure TBasicFuncSeries.AfterAdd; procedure TBasicFuncSeries.AfterAdd;
@ -791,9 +790,8 @@ function TFuncSeries.GetNearestPoint(
const AParams: TNearestPointParams; const AParams: TNearestPointParams;
out AResults: TNearestPointResults): Boolean; out AResults: TNearestPointResults): Boolean;
begin begin
Result := false;
AResults.FIndex := -1; AResults.FIndex := -1;
if not Assigned(OnCalculate) then exit; if not Assigned(OnCalculate) then exit(false);
with TDrawFuncHelper.Create(Self, DomainExclusions, @DoCalculate, Step) do with TDrawFuncHelper.Create(Self, DomainExclusions, @DoCalculate, Step) do
try try