diff --git a/components/tachart/tachartaxis.pas b/components/tachart/tachartaxis.pas index 4914c309b6..36b5eec9e1 100644 --- a/components/tachart/tachartaxis.pas +++ b/components/tachart/tachartaxis.pas @@ -110,6 +110,7 @@ type FInverted: Boolean; FMinors: TChartMinorAxisList; FOnMarkToText: TChartAxisMarkToTextEvent; + FRange: TChartRange; FTitle: TChartAxisTitle; FTransformations: TChartAxisTransformations; FZPosition: TChartDistance; @@ -122,6 +123,7 @@ type procedure SetMarks(AValue: TChartAxisMarks); procedure SetMinors(AValue: TChartMinorAxisList); procedure SetOnMarkToText(AValue: TChartAxisMarkToTextEvent); + procedure SetRange(AValue: TChartRange); procedure SetTitle(AValue: TChartAxisTitle); procedure SetTransformations(AValue: TChartAxisTransformations); procedure SetZPosition(AValue: TChartDistance); @@ -155,6 +157,7 @@ type property Inverted: boolean read FInverted write SetInverted default false; property Marks: TChartAxisMarks read GetMarks write SetMarks; property Minors: TChartMinorAxisList read FMinors write SetMinors; + property Range: TChartRange read FRange write SetRange; property TickLength default DEF_TICK_LENGTH; property Title: TChartAxisTitle read FTitle write SetTitle; property Transformations: TChartAxisTransformations @@ -233,6 +236,8 @@ type var ARect: TRect; AAlignment: TChartAxisAlignment; ADelta: Integer); function TransformByAxis( AAxisList: TChartAxisList; AIndex: Integer): TChartAxisTransformations; + procedure UpdateBoundsByAxisRange( + AAxisList: TChartAxisList; AIndex: Integer; var AMin, AMax: Double); implementation @@ -277,6 +282,18 @@ begin Result := VIdentityTransform; end; +procedure UpdateBoundsByAxisRange( + AAxisList: TChartAxisList; AIndex: Integer; var AMin, AMax: Double); +begin + if not InRange(AIndex, 0, AAxisList.Count - 1) then exit; + with AAxisList[AIndex].Range do begin + if UseMin then + AMin := Min; + if UseMax then + AMax := Max; + end; +end; + { TChartAxisEnumerator } function TChartAxisEnumerator.GetCurrent: TChartAxis; @@ -407,6 +424,7 @@ begin FListener := TListener.Create(@FTransformations, @StyleChanged); FMarks := TChartAxisMarks.Create(ACollection.Owner as TCustomChart); FMinors := TChartMinorAxisList.Create(Self); + FRange := TChartRange.Create(ACollection.Owner as TCustomChart); TickLength := DEF_TICK_LENGTH; FTitle := TChartAxisTitle.Create(ACollection.Owner as TCustomChart); end; @@ -414,6 +432,7 @@ end; destructor TChartAxis.Destroy; begin FreeAndNil(FTitle); + FreeAndNil(FRange); FreeAndNil(FMinors); FreeAndNil(FListener); FreeAndNil(FHelper); @@ -710,6 +729,13 @@ begin StyleChanged(Self); end; +procedure TChartAxis.SetRange(AValue: TChartRange); +begin + if FRange = AValue then exit; + FRange.Assign(AValue); + StyleChanged(Range); +end; + procedure TChartAxis.SetTitle(AValue: TChartAxisTitle); begin FTitle.Assign(AValue); diff --git a/components/tachart/tacustomseries.pas b/components/tachart/tacustomseries.pas index 43e1f47a92..ab1f49f3b6 100644 --- a/components/tachart/tacustomseries.pas +++ b/components/tachart/tacustomseries.pas @@ -307,6 +307,8 @@ procedure TCustomChartSeries.GetGraphBounds(var ABounds: TDoubleRect); begin GetBounds(ABounds); with ABounds do begin + UpdateBoundsByAxisRange(FChart.AxisList, AxisIndexX, a.X, b.X); + UpdateBoundsByAxisRange(FChart.AxisList, AxisIndexY, a.Y, b.Y); TransformByAxis(FChart.AxisList, AxisIndexX).UpdateBounds(a.X, b.X); TransformByAxis(FChart.AxisList, AxisIndexY).UpdateBounds(a.Y, b.Y); if IsRotated then begin diff --git a/components/tachart/taseries.pas b/components/tachart/taseries.pas index 0854a8d4bd..9d1491aa9f 100644 --- a/components/tachart/taseries.pas +++ b/components/tachart/taseries.pas @@ -1222,7 +1222,7 @@ var ic: IChartTCanvasDrawer; begin if Supports(ADrawer, IChartTCanvasDrawer, ic) and Assigned(FOnDraw) then - FOnDraw(ic.Canvas, FChart.ClipRect); + FOnDraw(ic.Canvas, FChart.ClipRect); end; procedure TUserDrawnSeries.GetBounds(var ABounds: TDoubleRect); diff --git a/components/tachart/tatypes.pas b/components/tachart/tatypes.pas index 8599a4f043..4bdeeb6e71 100644 --- a/components/tachart/tatypes.pas +++ b/components/tachart/tatypes.pas @@ -307,6 +307,25 @@ type EExtentError = class(EChartError); + TChartRange = class(TChartElement) + private + FBounds: array [1..2] of Double; + FUseBounds: array [1..2] of Boolean; + + function GetBounds(AIndex: Integer): Double; + function GetUseBounds(AIndex: integer): Boolean; + function IsBoundsStored(AIndex: Integer): Boolean; + procedure SetBounds(AIndex: Integer; const AValue: Double); + procedure SetUseBounds(AIndex: Integer; AValue: Boolean); + public + procedure CheckBoundsOrder; + published + property Max: Double index 2 read GetBounds write SetBounds stored IsBoundsStored; + property Min: Double index 1 read GetBounds write SetBounds stored IsBoundsStored; + property UseMax: Boolean index 2 read GetUseBounds write SetUseBounds default false; + property UseMin: Boolean index 1 read GetUseBounds write SetUseBounds default false; + end; + { TChartExtent } TChartExtent = class(TChartElement) @@ -316,20 +335,20 @@ type function GetBounds(AIndex: Integer): Double; function GetUseBounds(AIndex: integer): Boolean; - function IsBoundsStored(AIndex: Integer): boolean; + function IsBoundsStored(AIndex: Integer): Boolean; procedure SetBounds(AIndex: Integer; const AValue: Double); procedure SetUseBounds(AIndex: Integer; AValue: Boolean); public procedure CheckBoundsOrder; published - property XMin: Double index 1 read GetBounds write SetBounds stored IsBoundsStored; - property YMin: Double index 2 read GetBounds write SetBounds stored IsBoundsStored; - property XMax: Double index 3 read GetBounds write SetBounds stored IsBoundsStored; - property YMax: Double index 4 read GetBounds write SetBounds stored IsBoundsStored; - property UseXMin: Boolean index 1 read GetUseBounds write SetUseBounds default false; - property UseYMin: Boolean index 2 read GetUseBounds write SetUseBounds default false; property UseXMax: Boolean index 3 read GetUseBounds write SetUseBounds default false; + property UseXMin: Boolean index 1 read GetUseBounds write SetUseBounds default false; property UseYMax: Boolean index 4 read GetUseBounds write SetUseBounds default false; + property UseYMin: Boolean index 2 read GetUseBounds write SetUseBounds default false; + property XMax: Double index 3 read GetBounds write SetBounds stored IsBoundsStored; + property XMin: Double index 1 read GetBounds write SetBounds stored IsBoundsStored; + property YMax: Double index 4 read GetBounds write SetBounds stored IsBoundsStored; + property YMin: Double index 2 read GetBounds write SetBounds stored IsBoundsStored; end; TRectArray = array [1..4] of Integer; @@ -1015,18 +1034,46 @@ begin StyleChanged(Self); end; -{ TChartExtent } +{ TChartRange } -function TChartExtent.GetUseBounds(AIndex: Integer): Boolean; +procedure TChartRange.CheckBoundsOrder; +begin + if UseMin and UseMax and (Min >= Max) then begin + UseMin := false; + UseMax := false; + raise EExtentError.Create('ChartRange: Min >= Max'); + end; +end; + +function TChartRange.GetBounds(AIndex: Integer): Double; +begin + Result := FBounds[AIndex]; +end; + +function TChartRange.GetUseBounds(AIndex: integer): Boolean; begin Result := FUseBounds[AIndex]; end; -function TChartExtent.IsBoundsStored(AIndex: Integer): boolean; +function TChartRange.IsBoundsStored(AIndex: Integer): Boolean; begin - Result := FExtent.coords[AIndex] <> 0; + Result := FBounds[AIndex] <> 0; end; +procedure TChartRange.SetBounds(AIndex: Integer; const AValue: Double); +begin + FBounds[AIndex] := AValue; + StyleChanged(Self); +end; + +procedure TChartRange.SetUseBounds(AIndex: Integer; AValue: Boolean); +begin + FUseBounds[AIndex] := AValue; + StyleChanged(Self); +end; + +{ TChartExtent } + procedure TChartExtent.CheckBoundsOrder; begin if UseXMin and UseXMax and (XMin >= XMax) then begin @@ -1046,10 +1093,14 @@ begin Result := FExtent.coords[AIndex]; end; -procedure TChartExtent.SetUseBounds(AIndex: Integer; AValue: Boolean); +function TChartExtent.GetUseBounds(AIndex: Integer): Boolean; begin - FUseBounds[AIndex] := AValue; - StyleChanged(Self); + Result := FUseBounds[AIndex]; +end; + +function TChartExtent.IsBoundsStored(AIndex: Integer): Boolean; +begin + Result := FExtent.coords[AIndex] <> 0; end; procedure TChartExtent.SetBounds(AIndex: Integer; const AValue: Double); @@ -1058,6 +1109,12 @@ begin StyleChanged(Self); end; +procedure TChartExtent.SetUseBounds(AIndex: Integer; AValue: Boolean); +begin + FUseBounds[AIndex] := AValue; + StyleChanged(Self); +end; + { TChartMargins } procedure TChartMargins.Assign(Source: TPersistent);