TAChart: Activate NearestPointTargets in TFieldSeries.

git-svn-id: trunk@53945 -
This commit is contained in:
wp 2017-01-14 23:53:03 +00:00
parent 8af43e0c0b
commit 2f7921bcf1
3 changed files with 73 additions and 9 deletions

View File

@ -44,6 +44,7 @@ type
function CopyPoints( function CopyPoints(
APoints: array of TPoint; AStartIndex, ANumPts: Integer): TPointArray; APoints: array of TPoint; AStartIndex, ANumPts: Integer): TPointArray;
function DotProduct(A, B: TDoublePoint): Double;
function DoublePoint(AX, AY: Double): TDoublePoint; inline; overload; function DoublePoint(AX, AY: Double): TDoublePoint; inline; overload;
function DoublePoint(const AP: TPoint): TDoublePoint; inline; overload; function DoublePoint(const AP: TPoint): TDoublePoint; inline; overload;
function DoubleRect(AX1, AY1, AX2, AY2: Double): TDoubleRect; inline; function DoubleRect(AX1, AY1, AX2, AY2: Double): TDoubleRect; inline;
@ -76,6 +77,8 @@ 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;
function PointLineDist(const P, A, B: TPoint): Integer; function PointLineDist(const P, A, B: TPoint): Integer;
function ProjToLine(const P, A, B: TDoublePoint): TDoublePoint; overload;
function ProjToLine(const P, A, B: TPoint): TPoint; overload;
function ProjToRect( function ProjToRect(
const APt: TDoublePoint; const ARect: TDoubleRect): TDoublePoint; const APt: TDoublePoint; const ARect: TDoubleRect): TDoublePoint;
function RectIntersectsRect( function RectIntersectsRect(
@ -124,6 +127,11 @@ begin
Result[i] := APoints[i + AStartIndex]; Result[i] := APoints[i + AStartIndex];
end; end;
function DotProduct(A, B: TDoublePoint): Double;
begin
Result := A.X * B.X + A.Y + B.Y;
end;
function DoublePoint(AX, AY: Double): TDoublePoint; inline; function DoublePoint(AX, AY: Double): TDoublePoint; inline;
begin begin
Result.X := AX; Result.X := AX;
@ -561,6 +569,26 @@ begin
end; end;
end; end;
function ProjToLine(const P, A,B: TDoublePoint): TDoublePoint;
var
v, s: TDoublePoint;
begin
if P = A then
Result := A
else if P = B then
Result := B
else begin
s := B - A;
v := P - A;
Result := A + s * (DotProduct(v, s) / DotProduct(s, s));
end;
end;
function ProjToLine(const P, A, B: TPoint): TPoint;
begin
Result := RoundPoint(ProjToLine(DoublePoint(P), DoublePoint(A), DoublePoint(B)));
end;
function ProjToRect( function ProjToRect(
const APt: TDoublePoint; const ARect: TDoubleRect): TDoublePoint; const APt: TDoublePoint; const ARect: TDoubleRect): TDoublePoint;
begin begin

View File

@ -1357,8 +1357,10 @@ begin
end else begin end else begin
for i := 0 to Count - 1 do for i := 0 to Count - 1 do
if GetVectorPoints(i, p1, p2) then begin if GetVectorPoints(i, p1, p2) then begin
p1 := DoublePoint(AxisToGraphX(p1.X), AxisToGraphY(p1.Y)); p1 := AxisToGraph(p1);
p2 := DoublePoint(AxisToGraphX(p2.X), AxisToGraphY(p2.Y)); p2 := AxisToGraph(p2);
//p1 := DoublePoint(AxisToGraphX(p1.X), AxisToGraphY(p1.Y));
//p2 := DoublePoint(AxisToGraphX(p2.X), AxisToGraphY(p2.Y));
lPen.Color := GetColor(i); lPen.Color := GetColor(i);
DrawVector(ADrawer, p1, p2, lPen); DrawVector(ADrawer, p1, p2, lPen);
end; end;
@ -1422,13 +1424,16 @@ end;
function TFieldSeries.GetNearestPoint(const AParams: TNearestPointParams; function TFieldSeries.GetNearestPoint(const AParams: TNearestPointParams;
out AResults: TNearestPointResults): Boolean; out AResults: TNearestPointResults): Boolean;
var var
dist, i: Integer; dist, d, i, xidx, yidx: Integer;
pt1, pt2: TPoint; pt1, pt2: TPoint;
sp1, sp2: TDoublePoint; sp1, sp2: TDoublePoint;
R: TRect; R: TRect;
img: TPoint;
begin begin
AResults.FDist := Sqr(AParams.FRadius) + 1; AResults.FDist := Sqr(AParams.FRadius) + 1;
AResults.FIndex := -1; AResults.FIndex := -1;
AResults.FXIndex := 0;
AResults.FYIndex := 0;
for i := 0 to Count - 1 do begin for i := 0 to Count - 1 do begin
if not GetVectorPoints(i, sp1, sp2) then if not GetVectorPoints(i, sp1, sp2) then
Continue; Continue;
@ -1438,16 +1443,44 @@ begin
// At first we check if the point is in the rect spanned by the vector. // At first we check if the point is in the rect spanned by the vector.
R := Rect(pt1.x, pt1.y, pt2.x, pt2.y); R := Rect(pt1.x, pt1.y, pt2.x, pt2.y);
NormalizeRect(R); NormalizeRect(R);
R.TopLeft := R.TopLeft - Point(AParams.FRadius, AParams.FRadius); ExpandRect(R, Point(AParams.FRadius, AParams.FRadius));
R.BottomRight := R.BottomRight + Point(AParams.FRadius, AParams.FRadius);
if not IsPointInRect(AParams.FPoint, R) then continue; if not IsPointInRect(AParams.FPoint, R) then continue;
// Calculate distance of point from line
dist := PointLineDist(AParams.FPoint, pt1, pt2); dist := MaxInt;
xidx := -1;
yidx := -1;
if (nptPoint in AParams.FTargets) then begin
dist := AParams.FDistFunc(AParams.FPoint, pt1);
xidx := 0;
yidx := 0;
img := pt1;
end;
if (AParams.FTargets * [nptXList, nptYList] <> []) then begin
d := AParams.FDistFunc(AParams.FPoint, pt2);
if d < dist then begin
dist := d;
xidx := 1;
yidx := 1;
img := pt2;
end;
end;
if (nptCustom in AParams.FTargets) then begin
d := PointLineDist(AParams.FPoint, pt1, pt2); // distance of point from line
if d < dist then begin
dist := d;
xidx := -1;
yidx := -1;
img := ProjToLine(AParams.FPoint, pt1, pt2);
end;
end;
if dist >= AParams.FRadius then continue; if dist >= AParams.FRadius then continue;
AResults.FDist := dist; AResults.FDist := dist;
AResults.FIndex := i; AResults.FIndex := i;
AResults.FImg := (pt1 + pt2) div 2; AResults.FXIndex := xidx;
AResults.FValue := Source.Item[i]^.Point; AResults.FYIndex := yidx;
AResults.FImg := img;
AResults.FValue := Source[i]^.Point;
break; break;
end; end;
Result := AResults.FIndex >= 0; Result := AResults.FIndex >= 0;

View File

@ -411,6 +411,7 @@ type
strict protected strict protected
FNearestGraphPoint: TDoublePoint; FNearestGraphPoint: TDoublePoint;
FPointIndex: Integer; FPointIndex: Integer;
FXIndex: Integer;
FYIndex: Integer; FYIndex: Integer;
FSeries: TBasicChartSeries; FSeries: TBasicChartSeries;
procedure FindNearestPoint(APoint: TPoint); procedure FindNearestPoint(APoint: TPoint);
@ -426,6 +427,7 @@ type
property NearestGraphPoint: TDoublePoint read FNearestGraphPoint; property NearestGraphPoint: TDoublePoint read FNearestGraphPoint;
property PointIndex: Integer read FPointIndex; property PointIndex: Integer read FPointIndex;
property Series: TBasicChartSeries read FSeries; property Series: TBasicChartSeries read FSeries;
property XIndex: Integer read FXIndex;
property YIndex: Integer read FYIndex; property YIndex: Integer read FYIndex;
published published
property AffectedSeries: String property AffectedSeries: String
@ -1676,6 +1678,7 @@ begin
if best.FDist = MaxInt then exit; if best.FDist = MaxInt then exit;
FSeries := bestS; FSeries := bestS;
FPointIndex := best.FIndex; FPointIndex := best.FIndex;
FXIndex := best.FXIndex;
FYIndex := best.FYIndex; FYIndex := best.FYIndex;
FNearestGraphPoint := FChart.ImageToGraph(best.FImg); FNearestGraphPoint := FChart.ImageToGraph(best.FImg);
end; end;