TAChart: Fix too late updating of variables FLoBounds and FUpBounds of TBasicChartSeries. Patch by Marcin Wiazowski. Issue #34935.

git-svn-id: trunk@60216 -
This commit is contained in:
wp 2019-01-25 17:26:19 +00:00
parent 764ceb2e97
commit 6ae52eb288
2 changed files with 18 additions and 3 deletions

View File

@ -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;

View File

@ -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;