From 489724243bd9bfa31d2be9a5402cef3e44a846cf Mon Sep 17 00:00:00 2001 From: wp Date: Thu, 26 Mar 2015 16:59:12 +0000 Subject: [PATCH] TAChart: Fix paned charts to draw axis lines only in data range. git-svn-id: trunk@48510 - --- components/tachart/tachartaxis.pas | 59 +++++++++++++++++++++---- components/tachart/tachartaxisutils.pas | 31 +++++++------ 2 files changed, 68 insertions(+), 22 deletions(-) diff --git a/components/tachart/tachartaxis.pas b/components/tachart/tachartaxis.pas index 9ccfa75310..5ec98f0158 100644 --- a/components/tachart/tachartaxis.pas +++ b/components/tachart/tachartaxis.pas @@ -87,7 +87,8 @@ type FMarkValues: TChartValueTextArray; FTitlePos: Integer; procedure GetMarkValues; - procedure VisitSource(ASource: TCustomChartSource; var AData); +// procedure VisitSource(ASource: TCustomChartSource; var AData); + procedure VisitSource_Extent(ASource: TCustomChartSource; var AData); private FAxisRect: TRect; FGroupIndex: Integer; @@ -95,6 +96,7 @@ type function MakeValuesInRangeParams(AMin, AMax: Double): TValuesInRangeParams; strict private FAlignment: TChartAxisAlignment; + FAtDataOnly: Boolean; FAxisPen: TChartAxisPen; FGroup: Integer; FHelper: TAxisDrawHelper; @@ -115,6 +117,7 @@ type function GetValue(AIndex: Integer): TChartValueText; inline; function GetValueCount: Integer; inline; function PositionIsStored: Boolean; + procedure SetAtDataOnly(AValue: Boolean); procedure SetAxisPen(AValue: TChartAxisPen); procedure SetGroup(AValue: Integer); procedure SetInverted(AValue: Boolean); @@ -164,6 +167,7 @@ type published property Alignment default calLeft; property Arrow; + property AtDataOnly: Boolean read FAtDataOnly write SetAtDataOnly default false; property AxisPen: TChartAxisPen read FAxisPen write SetAxisPen; property Group: Integer read FGroup write SetGroup default 0; // Inverts the axis scale from increasing to decreasing. @@ -566,8 +570,9 @@ var i: Integer; d: TValuesInRangeParams; vis: TChartOnVisitSources; - t: TChartValueText; axisMin, axisMax: Double; + ex: TDoubleRect; + v: Boolean; begin with FHelper do begin axisMin := GetTransform.GraphToAxis(FValueMin); @@ -579,16 +584,26 @@ begin SetLength(FMarkValues, 0); vis := TChartAxisList(Collection).OnVisitSources; if Marks.AtDataOnly and Assigned(vis) then begin - vis(@VisitSource, Self, d); +// vis(@VisitSource, Self, d); // FIXME: Intersect axisMin/Max with the union of series extents. - end - else - Marks.SourceDef.ValuesInRange(d, FMarkValues); + + v := IsVertical; + ex := EmptyExtent; + vis(@VisitSource_Extent, self, ex); + UpdateBounds(TDoublePointBoolArr(ex.a)[v], TDoublePointBoolArr(ex.b)[v]); + d.FMin := TDoublePointBoolArr(ex.a)[IsVertical]; + d.FMax := TDoublePointBoolArr(ex.b)[IsVertical]; + if IsNaN(d.FMin) or IsNaN(d.FMax) then begin + d.FMax := 1.0; d.FMin := 0.0; + end else + if (d.FMin = d.FMax) then d.FMax := d.FMin + 1.0; + end; + Marks.SourceDef.ValuesInRange(d, FMarkValues); with FHelper do begin FValueMin := GetTransform.AxisToGraph(axisMin); FValueMax := GetTransform.AxisToGraph(axisMax); - FMinForMarks := GetTransform.AxisToGraph(d.FMin); - FMaxForMarks := GetTransform.AxisToGraph(d.FMax); + FMinForMarks := Min(FMinForMarks, GetTransform.AxisToGraph(d.FMin)); + FMaxForMarks := Max(FMaxForMarks, GetTransform.AxisToGraph(d.FMax)); end; if Assigned(FOnMarkToText) then @@ -808,6 +823,9 @@ begin FHelper.FTransf := ATransf; FHelper.FZOffset.Y := Min(ZPosition, AMaxZPosition); FHelper.FZOffset.X := -FHelper.FZOffset.Y; + FHelper.FAtDataOnly := AtDataOnly; + FHelper.FMaxForMarks := -infinity; + FHelper.FMinForMarks := infinity; end; procedure TChartAxis.SetAlignment(AValue: TChartAxisAlignment); @@ -817,6 +835,13 @@ begin StyleChanged(Self); end; +procedure TChartAxis.SetAtDataOnly(AValue: Boolean); +begin + if FAtDataOnly = AValue then exit; + FAtDataOnly := AValue; + StyleChanged(self); +end; + procedure TChartAxis.SetAxisPen(AValue: TChartAxisPen); begin FAxisPen.Assign(AValue); @@ -963,6 +988,7 @@ begin end; end; +{ procedure TChartAxis.VisitSource(ASource: TCustomChartSource; var AData); var ext: TDoubleRect; @@ -974,6 +1000,23 @@ begin p.FMax := Min(TDoublePointBoolArr(ext.b)[IsVertical], p.FMax); Marks.SourceDef.ValuesInRange(p, FMarkValues); end; +} + +procedure TChartAxis.VisitSource_Extent(ASource: TCustomChartSource; var AData); +var + ex: TDoubleRect; +begin + ex := ASource.Extent; + if IsInfinite(ex.a.x) or IsInfinite(ex.a.y) or + IsInfinite(ex.b.x) or IsInfinite(ex.b.y) + then + exit; + + TDoubleRect(AData).a.x := Min(ex.a.x, TDoubleRect(AData).a.x); + TDoubleRect(AData).b.x := Max(ex.b.x, TDoubleRect(AData).b.x); + TDoubleRect(AData).a.y := Min(ex.a.y, TDoubleRect(AData).a.y); + TDoubleRect(AData).b.y := Max(ex.b.y, TDoubleRect(AData).b.y); +end; { TChartAxisList } diff --git a/components/tachart/tachartaxisutils.pas b/components/tachart/tachartaxisutils.pas index 8690ba9fee..f8b381ba01 100644 --- a/components/tachart/tachartaxisutils.pas +++ b/components/tachart/tachartaxisutils.pas @@ -208,6 +208,7 @@ type procedure LineZ(AP1, AP2: TPoint); inline; function TryApplyStripes: Boolean; inline; public + FAtDataOnly: Boolean; FAxis: TChartBasicAxis; FAxisTransf: TTransformFunc; FClipRangeDelta: Integer; @@ -402,19 +403,20 @@ end; procedure TAxisDrawHelperX.DrawAxisLine(APen: TChartPen; AFixedCoord: Integer); var - p: TPoint; + p1, p2: TPoint; begin if FAxis.IsFlipped then begin - p := Point(FClipRect^.Left, AFixedCoord); + p1 := Point(IfThen(FAtDataOnly, GraphToImage(FMaxForMarks), FClipRect^.Left), AFixedCoord); + p2 := Point(IfThen(FAtDataOnly, GraphToImage(FMinForMarks), FClipRect^.Right), AFixedCoord); if FAxis.Arrow.Visible then - p.X -= FDrawer.Scale(FAxis.Arrow.Length); - InternalAxisLine(APen, p, Point(FClipRect^.Right, AFixedCoord), 0); + p1.X -= FDrawer.Scale(FAxis.Arrow.Length); end else begin - p := Point(FClipRect^.Right, AFixedCoord); + p1 := Point(IfThen(FAtDataOnly, GraphToImage(FMinForMarks), FClipRect^.Left), AFixedCoord); + p2 := Point(IfThen(FAtDataOnly, GraphToImage(FMaxForMarks), FClipRect^.Right), AFixedCoord); if FAxis.Arrow.Visible then - p.X += FDrawer.Scale(FAxis.Arrow.Length); - InternalAxisLine(APen, Point(FClipRect^.Left, AFixedCoord), p, 0); + p2.X += FDrawer.Scale(FAxis.Arrow.Length); end; + InternalAxisLine(APen, p1, p2, 0); end; procedure TAxisDrawHelperX.DrawLabelAndTick( @@ -467,19 +469,20 @@ end; procedure TAxisDrawHelperY.DrawAxisLine(APen: TChartPen; AFixedCoord: Integer); var - p: TPoint; + p1, p2: TPoint; begin if FAxis.IsFlipped then begin - p := Point(AFixedCoord, FClipRect^.Bottom); + p1 := Point(AFixedCoord, IfThen(FAtDataOnly, GraphToImage(FMaxForMarks), FClipRect^.Bottom)); + p2 := Point(AFixedCoord, IfThen(FAtDataOnly, GraphToImage(FMinForMarks), FClipRect^.Top)); if FAxis.Arrow.Visible then - p.Y += FDrawer.Scale(FAxis.Arrow.Length); - InternalAxisLine(APen, p, Point(AFixedCoord, FClipRect^.Top), -Pi / 2); + p1.Y += FDrawer.Scale(FAxis.Arrow.Length); end else begin - p := Point(AFixedCoord, FClipRect^.Top); + p1 := Point(AFixedCoord, IfThen(FAtDataOnly, GraphToImage(FMinForMarks), FClipRect^.Bottom)); + p2 := Point(AFixedCoord, IfThen(FAtDataOnly, GraphToImage(FMaxForMarks), FClipRect^.Top)); if FAxis.Arrow.Visible then - p.Y -= FDrawer.Scale(FAxis.Arrow.Length); - InternalAxisLine(APen, Point(AFixedCoord, FClipRect^.Bottom), p, -Pi / 2); + p2.Y -= FDrawer.Scale(FAxis.Arrow.Length); end; + InternalAxisLine(APen, p1, p2, -Pi / 2); end; procedure TAxisDrawHelperY.DrawLabelAndTick(