diff --git a/components/tachart/tachartaxis.pas b/components/tachart/tachartaxis.pas index 3dac633bf5..499e34fbe8 100644 --- a/components/tachart/tachartaxis.pas +++ b/components/tachart/tachartaxis.pas @@ -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; diff --git a/components/tachart/tacustomseries.pas b/components/tachart/tacustomseries.pas index 2e4e605d24..5325334597 100644 --- a/components/tachart/tacustomseries.pas +++ b/components/tachart/tacustomseries.pas @@ -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; diff --git a/components/tachart/tagraph.pas b/components/tachart/tagraph.pas index 1360d0725c..016ccc8489 100644 --- a/components/tachart/tagraph.pas +++ b/components/tachart/tagraph.pas @@ -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));