mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-07 04:09:35 +01:00
TAChart: Activate NearestPointTargets in TFieldSeries.
git-svn-id: trunk@53945 -
This commit is contained in:
parent
8af43e0c0b
commit
2f7921bcf1
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user