mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 10:59:11 +02:00
TAChart: DataTools follow the connection lines of TLineSeries. Keep TLineSeries.LineType when ShowLines is toggled.
git-svn-id: trunk@63048 -
This commit is contained in:
parent
455c23e3f7
commit
e4de3e6dec
@ -77,7 +77,8 @@ function NextNumberSeq(
|
|||||||
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;
|
||||||
function PointLineDist(const P, A, B: TPoint): Integer;
|
function PointLineDist(const P, A, B: TPoint): Integer; overload;
|
||||||
|
function PointLineDist(const P, A,B: TPoint; out Q: TPoint; out Inside: Boolean): Integer; overload;
|
||||||
function ProjToLine(const P, A, B: TDoublePoint): TDoublePoint; overload;
|
function ProjToLine(const P, A, B: TDoublePoint): TDoublePoint; overload;
|
||||||
function ProjToLine(const P, A, B: TPoint): TPoint; overload;
|
function ProjToLine(const P, A, B: TPoint): TPoint; overload;
|
||||||
function ProjToRect(
|
function ProjToRect(
|
||||||
@ -580,6 +581,36 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function PointLineDist(const P, A,B: TPoint; out Q: TPoint;
|
||||||
|
out Inside: Boolean): Integer;
|
||||||
|
var
|
||||||
|
v, w: TPoint;
|
||||||
|
dot: Int64;
|
||||||
|
lv: Integer;
|
||||||
|
|
||||||
|
aq, bq: Integer;
|
||||||
|
begin
|
||||||
|
if A = B then begin
|
||||||
|
Result := PointDist(A, P);
|
||||||
|
Inside := false;
|
||||||
|
Q := A;
|
||||||
|
end else begin
|
||||||
|
v := B - A;
|
||||||
|
w := P - A;
|
||||||
|
dot := Int64(v.x) * w.x + Int64(v.y) * w.y;
|
||||||
|
lv := PointDist(A, B);
|
||||||
|
Q := (v * dot) div lv;
|
||||||
|
Result := PointDist(Q, w);
|
||||||
|
|
||||||
|
// Check whether the projection point Q is inside the A-B line.
|
||||||
|
// In this case the lengths AQ and BQ are shorter than AB.
|
||||||
|
aq := sqr(Q.x) + sqr(Q.y); // note: Q is seen from A, not from origin.
|
||||||
|
bq := PointDist(v, Q);
|
||||||
|
Inside := (aq <= lv) and (bq <= lv);
|
||||||
|
Q := Q + A;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function ProjToLine(const P, A,B: TDoublePoint): TDoublePoint;
|
function ProjToLine(const P, A,B: TDoublePoint): TDoublePoint;
|
||||||
var
|
var
|
||||||
v, s: TDoublePoint;
|
v, s: TDoublePoint;
|
||||||
|
@ -241,6 +241,7 @@ type
|
|||||||
private
|
private
|
||||||
FLinePen: TPen;
|
FLinePen: TPen;
|
||||||
FLineType: TLineType;
|
FLineType: TLineType;
|
||||||
|
FOldLineType: TLineType;
|
||||||
FOnDrawPointer: TSeriesPointerDrawEvent;
|
FOnDrawPointer: TSeriesPointerDrawEvent;
|
||||||
FColorEach: TColorEachMode;
|
FColorEach: TColorEachMode;
|
||||||
|
|
||||||
@ -263,6 +264,8 @@ type
|
|||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure Draw(ADrawer: IChartDrawer); override;
|
procedure Draw(ADrawer: IChartDrawer); override;
|
||||||
|
function GetNearestPoint(const AParams: TNearestPointParams;
|
||||||
|
out AResults: TNearestPointResults): Boolean; override;
|
||||||
published
|
published
|
||||||
property AxisIndexX;
|
property AxisIndexX;
|
||||||
property AxisIndexY;
|
property AxisIndexY;
|
||||||
@ -436,6 +439,7 @@ begin
|
|||||||
FLinePen.OnChange := @StyleChanged;
|
FLinePen.OnChange := @StyleChanged;
|
||||||
FPointer := TSeriesPointer.Create(FChart);
|
FPointer := TSeriesPointer.Create(FChart);
|
||||||
SetPropDefaults(Self, ['LineType']);
|
SetPropDefaults(Self, ['LineType']);
|
||||||
|
FOldLineType := FLineType;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TLineSeries.Destroy;
|
destructor TLineSeries.Destroy;
|
||||||
@ -772,6 +776,67 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TLineSeries.GetNearestPoint(const AParams: TNearestPointParams;
|
||||||
|
out AResults: TNearestPointResults): Boolean;
|
||||||
|
var
|
||||||
|
pointIndex, levelIndex: Integer;
|
||||||
|
ip1, ip2, q: TPoint;
|
||||||
|
d, dmin: Integer;
|
||||||
|
isInside: Boolean;
|
||||||
|
ext: TDoubleRect;
|
||||||
|
begin
|
||||||
|
Result := false;
|
||||||
|
AResults.FDist := sqr(AParams.FRadius) + 1;
|
||||||
|
AResults.FIndex := -1;
|
||||||
|
AResults.FXIndex := 0;
|
||||||
|
AResults.FYIndex := 0;
|
||||||
|
|
||||||
|
Result := inherited;
|
||||||
|
|
||||||
|
if Result or (LineType <> ltFromPrevious) or
|
||||||
|
not ((nptCustom in AParams.FTargets) and (nptCustom in ToolTargets))
|
||||||
|
then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
with Extent do begin
|
||||||
|
ext.a := AxisToGraph(a);
|
||||||
|
ext.b := AxisToGraph(b);
|
||||||
|
end;
|
||||||
|
NormalizeRect(ext);
|
||||||
|
// Do not do anything if the series extent does not intersect CurrentExtent.
|
||||||
|
if not RectIntersectsRect(ext, ParentChart.CurrentExtent) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
// Iterate through all points of the series and - if nptYList is in Targets -
|
||||||
|
// at all stack levels.
|
||||||
|
PrepareGraphPoints(ext, true);
|
||||||
|
dmin := AResults.FDist;
|
||||||
|
for levelIndex := 0 to Source.YCount-1 do begin
|
||||||
|
ip1 := ParentChart.GraphToImage(FGraphPoints[0]);
|
||||||
|
for pointIndex := 1 to FUpBound - FLoBound do begin
|
||||||
|
ip2 := ParentChart.GraphToImage(FGraphPoints[pointIndex]);
|
||||||
|
d := PointLineDist(AParams.FPoint, ip1, ip2, q, isInside);
|
||||||
|
if isInside and (d < dmin) then begin
|
||||||
|
dmin := d;
|
||||||
|
AResults.FIndex := -1; //pointIndex + FLoBound;
|
||||||
|
AResults.FYIndex := levelIndex;
|
||||||
|
AResults.FImg := q;
|
||||||
|
AResults.FValue := ParentChart.ImageToGraph(q);
|
||||||
|
end;
|
||||||
|
ip1 := ip2;
|
||||||
|
end;
|
||||||
|
if not ((nptYList in AParams.FTargets) and (nptYList in ToolTargets)) then
|
||||||
|
break;
|
||||||
|
UpdateGraphPoints(levelIndex, FStacked);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if dmin < AResults.FDist then
|
||||||
|
begin
|
||||||
|
AResults.FDist := d;
|
||||||
|
Result := true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TLineSeries.GetSeriesColor: TColor;
|
function TLineSeries.GetSeriesColor: TColor;
|
||||||
begin
|
begin
|
||||||
Result := FLinePen.Color;
|
Result := FLinePen.Color;
|
||||||
@ -803,6 +868,7 @@ procedure TLineSeries.SetLineType(AValue: TLineType);
|
|||||||
begin
|
begin
|
||||||
if FLineType = AValue then exit;
|
if FLineType = AValue then exit;
|
||||||
FLineType := AValue;
|
FLineType := AValue;
|
||||||
|
FOldLineType := FLineType;
|
||||||
UpdateParentChart;
|
UpdateParentChart;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -815,9 +881,11 @@ procedure TLineSeries.SetShowLines(Value: Boolean);
|
|||||||
begin
|
begin
|
||||||
if ShowLines = Value then exit;
|
if ShowLines = Value then exit;
|
||||||
if Value then
|
if Value then
|
||||||
FLineType := ltFromPrevious
|
FLineType := FOldLineType
|
||||||
else
|
else begin
|
||||||
|
FOldLineType := FLineType;
|
||||||
FLineType := ltNone;
|
FLineType := ltNone;
|
||||||
|
end;
|
||||||
UpdateParentChart;
|
UpdateParentChart;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1874,7 +1874,7 @@ begin
|
|||||||
best.FDist := MaxInt;
|
best.FDist := MaxInt;
|
||||||
for s in CustomSeries(FChart, FAffectedSeries.AsBooleans(FChart.SeriesCount)) do
|
for s in CustomSeries(FChart, FAffectedSeries.AsBooleans(FChart.SeriesCount)) do
|
||||||
if
|
if
|
||||||
InBoundaryBox(s) and s.GetNearestPoint(p, cur) and
|
InBoundaryBox(s) and s.Active and s.GetNearestPoint(p, cur) and
|
||||||
PtInRect(FChart.ClipRect, cur.FImg) and (cur.FDist < best.FDist)
|
PtInRect(FChart.ClipRect, cur.FImg) and (cur.FDist < best.FDist)
|
||||||
then begin
|
then begin
|
||||||
bestS := s;
|
bestS := s;
|
||||||
|
Loading…
Reference in New Issue
Block a user