mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-19 09:09:32 +02:00
TAChart: Override TBarSeries.GetNearestPoint to accept clicks inside the bar, new property ToolTarget (http://forum.lazarus.freepascal.org/index.php/topic,35342.0.html)
git-svn-id: trunk@53896 -
This commit is contained in:
parent
8aaec43f37
commit
363f930d54
@ -34,7 +34,8 @@ type
|
||||
TNearestPointResults = record
|
||||
FDist: Integer;
|
||||
FImg: TPoint;
|
||||
FIndex: Integer;
|
||||
FIndex: Integer; // Point index
|
||||
FYIndex: Integer; // Index to be used in Source.GetY()
|
||||
FValue: TDoublePoint;
|
||||
end;
|
||||
|
||||
@ -1239,6 +1240,7 @@ begin
|
||||
if dist >= AResults.FDist then continue;
|
||||
AResults.FDist := dist;
|
||||
AResults.FIndex := i;
|
||||
AResults.FYIndex := 0; // to do: find yindex of stacked series
|
||||
AResults.FImg := pt;
|
||||
AResults.FValue := sp;
|
||||
end;
|
||||
|
@ -34,8 +34,11 @@ type
|
||||
|
||||
TBarWidthStyle = (bwPercent, bwPercentMin);
|
||||
|
||||
|
||||
TBarSeries = class;
|
||||
|
||||
TBarToolTarget = (bttDatapoint, bttBar);
|
||||
|
||||
TBeforeDrawBarEvent = procedure (
|
||||
ASender: TBarSeries; ACanvas: TCanvas; const ARect: TRect;
|
||||
APointIndex, AStackIndex: Integer; var ADoDefaultDrawing: Boolean
|
||||
@ -50,6 +53,7 @@ type
|
||||
FBarPen: TPen;
|
||||
FBarWidthPercent: Integer;
|
||||
FBarWidthStyle: TBarWidthStyle;
|
||||
FToolTarget: TBarToolTarget;
|
||||
FOnBeforeDrawBar: TBeforeDrawBarEvent;
|
||||
FZeroLevel: Double;
|
||||
|
||||
@ -78,6 +82,8 @@ type
|
||||
function GetBarWidth(AIndex: Integer): Integer;
|
||||
procedure Draw(ADrawer: IChartDrawer); override;
|
||||
function Extent: TDoubleRect; override;
|
||||
function GetNearestPoint(const AParams: TNearestPointParams;
|
||||
out AResults: TNearestPointResults): Boolean; override;
|
||||
published
|
||||
property AxisIndexX;
|
||||
property AxisIndexY;
|
||||
@ -95,6 +101,8 @@ type
|
||||
read GetSeriesColor write SetSeriesColor stored false default clRed;
|
||||
property Source;
|
||||
property Styles;
|
||||
property ToolTarget: TBarToolTarget
|
||||
read FToolTarget write FToolTarget default bttDataPoint;
|
||||
property UseReticule;
|
||||
property ZeroLevel: Double
|
||||
read FZeroLevel write SetZeroLevel stored IsZeroLevelStored;
|
||||
@ -1122,6 +1130,73 @@ begin
|
||||
GetLegendItemsRect(AItems, BarBrush);
|
||||
end;
|
||||
|
||||
function TBarSeries.GetNearestPoint(const AParams: TNearestPointParams;
|
||||
out AResults: TNearestPointResults): Boolean;
|
||||
var
|
||||
pointIndex: Integer;
|
||||
graphClickPt: TDoublePoint;
|
||||
sp, p: TDoublePoint;
|
||||
ofs, w: Double;
|
||||
heights: TDoubleDynArray;
|
||||
y, z: Double;
|
||||
stackindex: Integer;
|
||||
begin
|
||||
if FToolTarget = bttDatapoint then
|
||||
begin
|
||||
Result := inherited;
|
||||
exit;
|
||||
end;
|
||||
|
||||
Result := false;
|
||||
AResults.FDist := Sqr(AParams.FRadius) + 1;
|
||||
AResults.FIndex := -1;
|
||||
|
||||
if IsRotated then
|
||||
z := AxisToGraphX(ZeroLevel)
|
||||
else
|
||||
z := AxisToGraphY(ZeroLevel);
|
||||
SetLength(heights, Source.YCount + 1);
|
||||
|
||||
// clicked point in image coordinates
|
||||
graphClickPt := ParentChart.ImageToGraph(AParams.FPoint);
|
||||
if IsRotated then
|
||||
Exchange(graphclickpt.X, graphclickpt.Y);
|
||||
|
||||
// Iterate through all points of the series
|
||||
for pointIndex := 0 to Count - 1 do begin
|
||||
sp := Source[pointindex]^.Point;
|
||||
if IsNan(sp) then
|
||||
continue;
|
||||
BarOffsetWidth(sp.X, pointindex, ofs, w);
|
||||
sp.X := sp.X + ofs;
|
||||
if not InRange(graphClickPt.X, sp.X - w, sp.X + w) then
|
||||
continue;
|
||||
heights[0] := z;
|
||||
heights[1] := NumberOr(sp.Y, z);
|
||||
for stackIndex := 1 to Source.YCount-1 do begin
|
||||
y := NumberOr(Source[pointindex]^.YList[stackIndex - 1], 0);
|
||||
heights[stackIndex + 1] := heights[stacKindex] + y;
|
||||
end;
|
||||
for stackindex := 0 to High(heights)-1 do
|
||||
if ((heights[stackindex] < heights[stackindex + 1]) and
|
||||
InRange(graphClickPt.Y, heights[stackindex], heights[stackIndex + 1]))
|
||||
or
|
||||
((heights[stackindex + 1] < heights[stackindex]) and
|
||||
InRange(graphClickPt.Y, heights[stackindex + 1], heights[stackIndex]))
|
||||
then begin
|
||||
AResults.FDist := 0;
|
||||
AResults.FIndex := pointindex;
|
||||
AResults.FYIndex := stackIndex;
|
||||
AResults.FValue := DoublePoint(Source[pointindex]^.X, Source[pointindex]^.GetY(stackIndex));
|
||||
if IsRotated then
|
||||
Exchange(AResults.FValue.X, AResults.FValue.Y);
|
||||
AResults.FImg := ParentChart.GraphToImage(AResults.FValue);
|
||||
Result := true;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TBarSeries.GetSeriesColor: TColor;
|
||||
begin
|
||||
Result := FBarBrush.Color;
|
||||
|
@ -411,6 +411,7 @@ type
|
||||
strict protected
|
||||
FNearestGraphPoint: TDoublePoint;
|
||||
FPointIndex: Integer;
|
||||
FYIndex: Integer;
|
||||
FSeries: TBasicChartSeries;
|
||||
procedure FindNearestPoint(APoint: TPoint);
|
||||
property MouseInsideOnly: Boolean
|
||||
@ -423,6 +424,7 @@ type
|
||||
property NearestGraphPoint: TDoublePoint read FNearestGraphPoint;
|
||||
property PointIndex: Integer read FPointIndex;
|
||||
property Series: TBasicChartSeries read FSeries;
|
||||
property YIndex: Integer read FYIndex;
|
||||
published
|
||||
property AffectedSeries: String
|
||||
read GetAffectedSeries write SetAffectedSeries;
|
||||
@ -497,6 +499,7 @@ type
|
||||
FOnHintLocation: TChartToolHintLocationEvent;
|
||||
FPrevPointIndex: Integer;
|
||||
FPrevSeries: TBasicChartSeries;
|
||||
FPrevYIndex: Integer;
|
||||
FUseApplicationHint: Boolean;
|
||||
FUseDefaultHintText: Boolean;
|
||||
procedure HideHint;
|
||||
@ -1603,6 +1606,7 @@ begin
|
||||
FAffectedSeries.Init;
|
||||
SetPropDefaults(Self, ['GrabRadius']);
|
||||
FPointIndex := -1;
|
||||
FYIndex := 0;
|
||||
end;
|
||||
|
||||
procedure TDataPointTool.FindNearestPoint(APoint: TPoint);
|
||||
@ -1664,6 +1668,7 @@ begin
|
||||
if best.FDist = MaxInt then exit;
|
||||
FSeries := bestS;
|
||||
FPointIndex := best.FIndex;
|
||||
FYIndex := best.FYIndex;
|
||||
FNearestGraphPoint := FChart.ImageToGraph(best.FImg);
|
||||
end;
|
||||
|
||||
@ -1836,12 +1841,15 @@ begin
|
||||
HideHint;
|
||||
exit;
|
||||
end;
|
||||
if (FPrevSeries = Series) and (FPrevPointIndex = PointIndex) then
|
||||
if (FPrevSeries = Series) and (FPrevPointIndex = PointIndex) and
|
||||
(FPrevYIndex = YIndex)
|
||||
then
|
||||
exit;
|
||||
if FPrevSeries = nil then
|
||||
SetCursor;
|
||||
FPrevSeries := Series;
|
||||
FPrevPointIndex := PointIndex;
|
||||
FPrevYIndex := YIndex;
|
||||
h := GetHintText;
|
||||
APoint := FChart.ClientToScreen(APoint);
|
||||
if Assigned(OnHintPosition) then
|
||||
|
Loading…
Reference in New Issue
Block a user