diff --git a/components/tachart/tacustomseries.pas b/components/tachart/tacustomseries.pas index 37d6031714..36234c41b5 100644 --- a/components/tachart/tacustomseries.pas +++ b/components/tachart/tacustomseries.pas @@ -1792,6 +1792,19 @@ begin if not Marks.IsMarkLabelsVisible or not Marks.AutoMargins then exit; if Count = 0 then exit; + {FLoBound and FUpBound fields may be outdated here (if axis' range has been + changed after the last series' painting). FLoBound and FUpBound will be fully + updated later, in a PrepareGraphPoints() call. But we need them now. If data + source is sorted, obtaining FLoBound and FUpBound is very fast (binary search) - + so we call FindExtentInterval() with True as the second parameter. If data + source is not sorted, obtaining FLoBound and FUpBound requires enumerating all + the data points to see, if they are in the current chart's viewport. But this + is exactly what we are going to do in the loop below, so obtaining true FLoBound + and FUpBound values makes no sense in this case - so we call FindExtentInterval() + with False as the second parameter, thus setting FLoBound to 0 and FUpBound to + Count-1} + FindExtentInterval(ParentChart.CurrentExtent, Source.IsSorted); + for i := FLoBound to FUpBound do begin gp := GetGraphPoint(i); if not ParentChart.IsPointInViewPort(gp) then continue; diff --git a/components/tachart/tagraph.pas b/components/tachart/tagraph.pas index 016ccc8489..beb1cb1c37 100644 --- a/components/tachart/tagraph.pas +++ b/components/tachart/tagraph.pas @@ -322,7 +322,7 @@ type {$ENDIF} procedure Notification( AComponent: TComponent; AOperation: TOperation); override; - procedure PrepareAxis(ADrawer: IChartDrawer); + procedure PrepareAxis(ADrawer: IChartDrawer); function PrepareLegend( ADrawer: IChartDrawer; var AClipRect: TRect): TChartLegendDrawingData; procedure SetBiDiMode(AValue: TBiDiMode); override; @@ -1465,10 +1465,12 @@ var prevExt: TDoubleRect; axis: TChartAxis; scDepth: Integer; + scSeriesMargins: TRect; scChartMargins: TRect; scMinDataSpace: Integer; begin scDepth := ADrawer.Scale(Depth); + scSeriesMargins := GetMargins(ADrawer); scChartMargins.Left := ADrawer.Scale(Margins.Left); scChartMargins.Right := ADrawer.Scale(Margins.Right); scChartMargins.Top := ADrawer.Scale(Margins.Top); @@ -1478,7 +1480,7 @@ begin if not AxisVisible then begin FClipRect.Left += scDepth; FClipRect.Bottom -= scDepth; - CalculateTransformationCoeffs(GetMargins(ADrawer), scChartMargins, scMinDataSpace); + CalculateTransformationCoeffs(scSeriesMargins, scChartMargins, scMinDataSpace); exit; end; @@ -1499,7 +1501,7 @@ begin SideByAlignment(FClipRect, aa, -axisMargin[aa]); prevExt := FCurrentExtent; FCurrentExtent := FLogicalExtent; - CalculateTransformationCoeffs(GetMargins(ADrawer), scChartMargins, scMinDataSpace); + CalculateTransformationCoeffs(scSeriesMargins, scChartMargins, scMinDataSpace); if prevExt = FCurrentExtent then break; prevExt := FCurrentExtent; end;