mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-29 12:10:31 +02:00
TAChart: Avoid crash of chart if an axis is destroyed. Add chart properties HorAxis and VertAxis.
git-svn-id: trunk@60162 -
This commit is contained in:
parent
ceb99f5f2e
commit
59e51e3587
@ -244,7 +244,7 @@ type
|
||||
{ TAxisCoeffHelper }
|
||||
|
||||
TAxisCoeffHelper = object
|
||||
FAxis: TChartAxis;
|
||||
FAxisIsFlipped: Boolean;
|
||||
FImageLo, FImageHi: Integer;
|
||||
FLo, FHi: Integer;
|
||||
FMin, FMax: PDouble;
|
||||
@ -252,7 +252,7 @@ type
|
||||
function CalcScale(ASign: Integer): Double;
|
||||
constructor Init(AAxis: TChartAxis; AImageLo, AImageHi: Integer;
|
||||
AMarginLo, AMarginHi, ARequiredMarginLo, ARequiredMarginHi, AMinDataSpace: Integer;
|
||||
HasMarksInMargin: Boolean; AMin, AMax: PDouble);
|
||||
AHasMarksInMargin, AAxisIsVertical: Boolean; AMin, AMax: PDouble);
|
||||
procedure UpdateMinMax(AConv: TAxisConvFunc);
|
||||
end;
|
||||
|
||||
@ -1246,11 +1246,9 @@ end;
|
||||
|
||||
constructor TAxisCoeffHelper.Init(AAxis: TChartAxis; AImageLo, AImageHi: Integer;
|
||||
AMarginLo, AMarginHi, ARequiredMarginLo, ARequiredMarginHi, AMinDataSpace: Integer;
|
||||
HasMarksInMargin: Boolean; AMin, AMax: PDouble);
|
||||
AHasMarksInMargin, AAxisIsVertical: Boolean; AMin, AMax: PDouble);
|
||||
begin
|
||||
Assert(AAxis <> nil);
|
||||
|
||||
FAxis := AAxis;
|
||||
FAxisIsFlipped := (AAxis <> nil) and AAxis.IsFlipped;
|
||||
FImageLo := AImageLo;
|
||||
FImageHi := AImageHi;
|
||||
FMin := AMin;
|
||||
@ -1258,8 +1256,8 @@ begin
|
||||
FLo := FImageLo + AMarginLo;
|
||||
FHi := FImageHi + AMarginHi;
|
||||
|
||||
if HasMarksInMargin then begin
|
||||
if FAxis.IsVertical then begin
|
||||
if AHasMarksInMargin then begin
|
||||
if AAxisIsVertical then begin
|
||||
if (FHi + AMinDataSpace >= FLo) then
|
||||
EnsureGuaranteedSpace(FHi, FLo, FImageHi, FImageLo,
|
||||
ARequiredMarginHi, ARequiredMarginLo, AMinDataSpace);
|
||||
@ -1277,7 +1275,7 @@ begin
|
||||
Result := ASign
|
||||
else
|
||||
Result := (FHi - FLo) / (FMax^ - FMin^);
|
||||
if FAxis.IsFlipped then
|
||||
if FAxisIsFlipped then
|
||||
Result := -Result;
|
||||
end;
|
||||
|
||||
@ -1290,7 +1288,7 @@ procedure TAxisCoeffHelper.UpdateMinMax(AConv: TAxisConvFunc);
|
||||
begin
|
||||
FMin^ := AConv(FImageLo);
|
||||
FMax^ := AConv(FImageHi);
|
||||
if FAxis.IsFlipped then
|
||||
if FAxisIsFlipped then
|
||||
Exchange(FMin^, FMax^);
|
||||
end;
|
||||
|
||||
|
@ -556,10 +556,18 @@ begin
|
||||
end;
|
||||
|
||||
function TCustomChartSeries.IsRotated: Boolean;
|
||||
var
|
||||
x_normal, y_normal: Boolean;
|
||||
x_axis: TChartAxis = nil;
|
||||
y_axis: TChartAxis = nil;
|
||||
begin
|
||||
Result :=
|
||||
(AxisIndexX >= 0) and FChart.AxisList[AxisIndexX].IsVertical and
|
||||
(AxisIndexY >= 0) and not FChart.AxisList[AxisIndexY].IsVertical;
|
||||
if InRange(AxisIndexX, 0, FChart.AxisList.Count-1) then
|
||||
x_axis := FChart.AxisList[AxisIndexX];
|
||||
if InRange(AxisIndexY, 0, FChart.AxisList.Count-1) then
|
||||
y_axis := FChart.AxisList[AxisIndexY];
|
||||
x_normal := (x_axis = nil) or (not x_axis.IsVertical);
|
||||
y_normal := (y_axis = nil) or y_axis.IsVertical;
|
||||
Result := (not x_normal) and (not y_normal);
|
||||
end;
|
||||
|
||||
function TCustomChartSeries.LegendTextSingle: String;
|
||||
@ -1427,8 +1435,9 @@ begin
|
||||
lmpNegative: isNeg := true;
|
||||
lmpInside: isNeg := Source[AIndex]^.Y >= ref;
|
||||
end;
|
||||
if (IsRotated and ParentChart.IsRightToLeft) xor GetAxisY.Inverted then
|
||||
isNeg := not isNeg;
|
||||
if Assigned(GetAxisY) then
|
||||
if (IsRotated and ParentChart.IsRightToLeft) xor GetAxisY.Inverted then
|
||||
isNeg := not isNeg;
|
||||
Result := DIR[IsRotated, isNeg];
|
||||
end;
|
||||
|
||||
|
@ -252,10 +252,12 @@ type
|
||||
AReader: TReader; const AClassName: String; var AClass: TComponentClass);
|
||||
function GetChartHeight: Integer;
|
||||
function GetChartWidth: Integer;
|
||||
function GetHorAxis: TChartAxis;
|
||||
function GetMargins(ADrawer: IChartDrawer): TRect;
|
||||
function GetRenderingParams: TChartRenderingParams;
|
||||
function GetSeriesCount: Integer;
|
||||
function GetToolset: TBasicChartToolset;
|
||||
function GetVertAxis: TChartAxis;
|
||||
procedure HideReticule; deprecated 'Use DatapointCrosshairTool instead';
|
||||
|
||||
procedure SetAntialiasingMode(AValue: TChartAntialiasingMode);
|
||||
@ -385,6 +387,7 @@ type
|
||||
property ClipRect: TRect read FClipRect;
|
||||
property CurrentExtent: TDoubleRect read FCurrentExtent;
|
||||
property ExtentBroadcaster: TBroadcaster read FExtentBroadcaster;
|
||||
property HorAxis: TChartAxis read GetHorAxis;
|
||||
property IsZoomed: Boolean read FIsZoomed;
|
||||
property LogicalExtent: TDoubleRect read FLogicalExtent write SetLogicalExtent;
|
||||
property MinDataSpace: Integer
|
||||
@ -396,6 +399,7 @@ type
|
||||
read GetRenderingParams write SetRenderingParams;
|
||||
property ReticulePos: TPoint read FReticulePos write SetReticulePos; deprecated 'Use DatapointCrosshairTool instead';
|
||||
property SeriesCount: Integer read GetSeriesCount;
|
||||
property VertAxis: TChartAxis read GetVertAxis;
|
||||
property XGraphMax: Double read FCurrentExtent.b.X;
|
||||
property XGraphMin: Double read FCurrentExtent.a.X;
|
||||
property YGraphMax: Double read FCurrentExtent.b.Y;
|
||||
@ -588,15 +592,16 @@ var
|
||||
rX, rY: TAxisCoeffHelper;
|
||||
begin
|
||||
rX.Init(
|
||||
BottomAxis, FClipRect.Left, FClipRect.Right, AMargin.Left, -AMargin.Right,
|
||||
HorAxis, FClipRect.Left, FClipRect.Right, AMargin.Left, -AMargin.Right,
|
||||
AChartMargins.Left, AChartMargins.Right, AMinDataSpace,
|
||||
(AMargin.Left <> AChartMargins.Left) or (AMargin.Right <> AChartMargins.Right),
|
||||
@FCurrentExtent.a.X, @FCurrentExtent.b.X);
|
||||
false, @FCurrentExtent.a.X, @FCurrentExtent.b.X);
|
||||
rY.Init(
|
||||
LeftAxis, FClipRect.Bottom, FClipRect.Top, -AMargin.Bottom, AMargin.Top,
|
||||
VertAxis, FClipRect.Bottom, FClipRect.Top, -AMargin.Bottom, AMargin.Top,
|
||||
AChartMargins.Bottom, AChartMargins.Top, AMinDataSpace,
|
||||
(AMargin.Top <> AChartMargins.Top) or (AMargin.Bottom <> AChartMargins.Bottom),
|
||||
@FCurrentExtent.a.Y, @FCurrentExtent.b.Y);
|
||||
true, @FCurrentExtent.a.Y, @FCurrentExtent.b.Y);
|
||||
|
||||
|
||||
FScale.X := rX.CalcScale(1);
|
||||
FScale.Y := rY.CalcScale(-1);
|
||||
@ -1213,6 +1218,12 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TChart.GetHorAxis: TChartAxis;
|
||||
begin
|
||||
Result := BottomAxis;
|
||||
if Result = nil then Result := GetAxisByAlign(calTop);
|
||||
end;
|
||||
|
||||
function TChart.GetLegendItems(AIncludeHidden: Boolean): TChartLegendItems;
|
||||
var
|
||||
s: TBasicChartSeries;
|
||||
@ -1269,6 +1280,12 @@ begin
|
||||
Result := FBuiltinToolset;
|
||||
end;
|
||||
|
||||
function TChart.GetVertAxis: TChartAxis;
|
||||
begin
|
||||
Result := LeftAxis;
|
||||
if Result = nil then Result := GetAxisByAlign(calRight);
|
||||
end;
|
||||
|
||||
function TChart.GraphToImage(const AGraphPoint: TDoublePoint): TPoint;
|
||||
begin
|
||||
Result := Point(XGraphToImage(AGraphPoint.X), YGraphToImage(AGraphPoint.Y));
|
||||
|
Loading…
Reference in New Issue
Block a user