diff --git a/components/tachart/tacustomsource.pas b/components/tachart/tacustomsource.pas index 4fdd288d4b..f119afb477 100644 --- a/components/tachart/tacustomsource.pas +++ b/components/tachart/tacustomsource.pas @@ -45,6 +45,7 @@ type FOptions: TAxisIntervalParamOptions; FOwner: TPersistent; FStepValues: TDoubleDynArray; + FTolerance: Cardinal; function NiceStepsIsStored: Boolean; procedure ParseNiceSteps; procedure SetCount(AValue: Integer); @@ -52,6 +53,7 @@ type procedure SetMinLength(AValue: Integer); procedure SetNiceSteps(const AValue: String); procedure SetOptions(AValue: TAxisIntervalParamOptions); + procedure SetTolerance(AValue: Cardinal); strict protected procedure Changed; virtual; protected @@ -68,6 +70,7 @@ type read FNiceSteps write SetNiceSteps stored NiceStepsIsStored; property Options: TAxisIntervalParamOptions read FOptions write SetOptions default DEF_INTERVAL_OPTIONS; + property Tolerance: Cardinal read FTolerance write SetTolerance default 0; end; type @@ -360,6 +363,13 @@ begin Changed; end; +procedure TChartAxisIntervalParams.SetTolerance(AValue: Cardinal); +begin + if FTolerance = AValue then exit; + FTolerance := AValue; + Changed; +end; + { TChartDataItem } function TChartDataItem.GetY(AIndex: Integer): Double; diff --git a/components/tachart/taintervalsources.pas b/components/tachart/taintervalsources.pas index e01026039a..75dbf859bf 100644 --- a/components/tachart/taintervalsources.pas +++ b/components/tachart/taintervalsources.pas @@ -32,7 +32,7 @@ type strict private FParams: TChartAxisIntervalParams; procedure RoundToImage( - AParams: TValuesInRangeParams; var AValues: TChartValueTextArray); + const AParams: TValuesInRangeParams; var AValues: TChartValueTextArray); procedure SetParams(AValue: TChartAxisIntervalParams); strict protected procedure CalculateIntervals( @@ -274,21 +274,26 @@ begin end; procedure TIntervalChartSource.RoundToImage( - AParams: TValuesInRangeParams; var AValues: TChartValueTextArray); -const - MAX_DIGITS = 17; + const AParams: TValuesInRangeParams; var AValues: TChartValueTextArray); + + function A2I(AX: Double): Integer; inline; + begin + Result := AParams.FGraphToImage(AParams.FAxisToGraph(AX)); + end; + var - i, x, d: Integer; + i, x: Integer; v, p, rv: Double; begin + if AParams.FIntervals.Tolerance = 0 then exit; for i := 0 to High(AValues) do begin v := AValues[i].FValue; if v = 0 then continue; - x := AParams.ToImage(v); - p := Power(10, Floor(Log10(Abs(v))) - MAX_DIGITS); - for d := 1 to MAX_DIGITS do begin + x := A2I(v); + p := Power(10, Floor(Log10(Abs(v)) - Log10(High(Int64)) + 1)); + while true do begin rv := Round(v / p) * p; - if AParams.ToImage(rv) <> x then break; + if Cardinal(Abs(A2I(rv) - x)) >= AParams.FIntervals.Tolerance then break; v := rv; p *= 10; end; diff --git a/components/tachart/test/SourcesTest.pas b/components/tachart/test/SourcesTest.pas index 08cf5c9c00..c0898fecb0 100644 --- a/components/tachart/test/SourcesTest.pas +++ b/components/tachart/test/SourcesTest.pas @@ -457,6 +457,7 @@ begin AssertValueEquals([20, 30, 40, 50, 60, 70], r); src.Params.Options := [aipUseCount]; src.Params.Count := 7; + src.Params.Tolerance := 1; src.ValuesInRange(p, r); AssertValueEquals([24, 30, 36, 41, 47, 52, 58, 63, 69, 75], r); finally