TAChart: Some optimization of TCubicSplineSeries painting after r60785 #3c24b3ee10. Less hints and warnings.

git-svn-id: trunk@60787 -
This commit is contained in:
wp 2019-03-27 22:30:36 +00:00
parent e36ca85ceb
commit 2c3ac872b4
5 changed files with 42 additions and 30 deletions

View File

@ -285,8 +285,7 @@ For example, <link id="TASeries.TPieSeries">pie series</link> displays a separat
In addition to the viewport requested for zooming it also contains the inner In addition to the viewport requested for zooming it also contains the inner
chart margin and the space reserved for series marks. chart margin and the space reserved for series marks.
</descr> </descr>
<seealso> <seealso><link id="TChart.LogicalExtent">LogicalExtent</link>
<link id="TChart.LogicalExtent">LogicalExtent</link>
</seealso> </seealso>
</element> </element>
<element name="TChart.XGraphMax"> <element name="TChart.XGraphMax">

View File

@ -91,7 +91,7 @@ type
ACalc: TTransformFunc; AStep: Integer); ACalc: TTransformFunc; AStep: Integer);
end; end;
TPointsDrawFuncHelper = class(TDrawFuncHelper) TPointsDrawFuncHelper = class(TCustomDrawFuncHelper)
protected protected
procedure ForEachPoint(AXg, AXMax: Double; AOnMoveTo, AOnLineTo: TOnPoint); override; procedure ForEachPoint(AXg, AXMax: Double; AOnMoveTo, AOnLineTo: TOnPoint); override;
public public
@ -262,8 +262,6 @@ procedure TDrawFuncHelper.ForEachPoint(
var var
hint: Integer; hint: Integer;
xa, xg1, xa1, dx: Double; xa, xg1, xa1, dx: Double;
fxg: array of double;
i, j: Integer;
begin begin
if FGraphStep = 0 then exit; if FGraphStep = 0 then exit;
@ -303,7 +301,7 @@ constructor TPointsDrawFuncHelper.Create(
ASeries: TBasicPointSeries; AMinX, AMaxX: Double; ACalc: TTransformFunc; ASeries: TBasicPointSeries; AMinX, AMaxX: Double; ACalc: TTransformFunc;
AStep: Integer); AStep: Integer);
begin begin
inherited Create(ASeries, nil, ACalc, AStep); inherited Create(ASeries, ACalc, AStep);
FExtent.a.X := Min(AMinX, AMaxX); FExtent.a.X := Min(AMinX, AMaxX);
FExtent.b.X := Max(AMaxX, AMinX); FExtent.b.X := Max(AMaxX, AMinX);
end; end;
@ -318,7 +316,10 @@ begin
if FGraphStep = 0 then exit; if FGraphStep = 0 then exit;
if not (FSeries is TBasicPointSeries) then if not (FSeries is TBasicPointSeries) then
raise EChartError.Create('[TPointsDrawFuncHelper.ForEachPoint] Series must be a TBasicPointSeries'); raise EChartError.CreateFmt(
'[%s.ForEachPoint] Series %s must be a TBasicPointSeries',
[ClassName, NameOrClassName(FSeries)]
);
ser := TBasicPointSeriesAccess(FSeries); ser := TBasicPointSeriesAccess(FSeries);
n := Length(ser.FGraphPoints); n := Length(ser.FGraphPoints);

View File

@ -199,6 +199,7 @@ type
TCubicSplineSeries = class(TBasicPointSeries) TCubicSplineSeries = class(TBasicPointSeries)
strict private strict private
FBadDataPen: TBadDataChartPen; FBadDataPen: TBadDataChartPen;
FCachedExtent: TDoubleRect;
FOptions: TCubicSplineOptions; FOptions: TCubicSplineOptions;
FSplineType: TCubicSplineType; FSplineType: TCubicSplineType;
FPen: TChartPen; FPen: TChartPen;
@ -226,6 +227,7 @@ type
var var
FSplines: array of TSpline; FSplines: array of TSpline;
procedure FreeSplines; procedure FreeSplines;
procedure GetSplineXRange(ASpline: TSpline; out AXMin, AXMax: Double);
function IsUnorderedVisible: Boolean; inline; function IsUnorderedVisible: Boolean; inline;
procedure PrepareCoeffs; procedure PrepareCoeffs;
procedure SetBadDataPen(AValue: TBadDataChartPen); procedure SetBadDataPen(AValue: TBadDataChartPen);
@ -1376,7 +1378,6 @@ procedure TCubicSplineSeries.Draw(ADrawer: IChartDrawer);
procedure DrawSpline(ASpline: TSpline); procedure DrawSpline(ASpline: TSpline);
var var
ext: TDoubleRect;
xmin, xmax: Double; xmin, xmax: Double;
begin begin
ADrawer.SetBrushParams(bsClear, clTAColor); ADrawer.SetBrushParams(bsClear, clTAColor);
@ -1388,10 +1389,7 @@ procedure TCubicSplineSeries.Draw(ADrawer: IChartDrawer);
if not Pen.EffVisible then exit; if not Pen.EffVisible then exit;
ADrawer.Pen := Pen; ADrawer.Pen := Pen;
end; end;
ext := FChart.CurrentExtent; GetSplineXRange(ASpline, xmin, xmax);
xmin := IfThen(csoExtrapolateLeft in FOptions, ext.a.x, Max(ext.a.x, ASpline.FX[0]));
xmax := IfThen(csoExtrapolateRight in Options, ext.b.x, Min(ext.b.x, ASpline.FX[High(ASpline.FX)]));
with TPointsDrawFuncHelper.Create(Self, xmin, xmax, @ASpline.Calculate, Step) do with TPointsDrawFuncHelper.Create(Self, xmin, xmax, @ASpline.Calculate, Step) do
try try
DrawFunction(ADrawer); DrawFunction(ADrawer);
@ -1427,12 +1425,19 @@ var
extChg: Boolean = false; extChg: Boolean = false;
s: TSpline; s: TSpline;
begin begin
Result := Source.BasicExtent; // was: inherited Extent; Result := Source.BasicExtent;
if SplineType = cstHermiteMonotone then if SplineType = cstHermiteMonotone then
exit; exit;
if not (FCachedExtent = EmptyExtent) then begin
Result := FCachedExtent;
exit;
end;
if FSplines = nil then if FSplines = nil then
PrepareCoeffs; PrepareCoeffs;
if FSplines = nil then exit; if FSplines = nil then
exit;
for s in FSplines do begin for s in FSplines do begin
if s.IsFewPoints then continue; if s.IsFewPoints then continue;
minv := Result.a.Y; minv := Result.a.Y;
@ -1446,6 +1451,7 @@ begin
Result.a.Y := extY.FStart; Result.a.Y := extY.FStart;
Result.b.Y := extY.FEnd; Result.b.Y := extY.FEnd;
end; end;
FCachedExtent := Result;
end; end;
procedure TCubicSplineSeries.FreeSplines; procedure TCubicSplineSeries.FreeSplines;
@ -1455,6 +1461,7 @@ begin
for s in FSplines do for s in FSplines do
s.Free; s.Free;
FSplines := nil; FSplines := nil;
FCachedExtent := EmptyExtent;
end; end;
procedure TCubicSplineSeries.GetLegendItems(AItems: TChartLegendItems); procedure TCubicSplineSeries.GetLegendItems(AItems: TChartLegendItems);
@ -1482,7 +1489,6 @@ var
s: TSpline; s: TSpline;
r: TNearestPointResults; r: TNearestPointResults;
xmin, xmax: Double; xmin, xmax: Double;
ext: TDoubleRect;
begin begin
Result := inherited GetNearestPoint(AParams, AResults); Result := inherited GetNearestPoint(AParams, AResults);
if (not Result) and (nptCustom in ToolTargets) and (nptCustom in AParams.FTargets) if (not Result) and (nptCustom in ToolTargets) and (nptCustom in AParams.FTargets)
@ -1490,12 +1496,11 @@ begin
if IsEmpty then exit; if IsEmpty then exit;
if not RequestValidChartScaling then exit; if not RequestValidChartScaling then exit;
ext := FChart.CurrentExtent;
for s in FSplines do begin for s in FSplines do begin
if s.IsFewPoints or (s.FIsUnorderedX and not IsUnorderedVisible) then if s.IsFewPoints or (s.FIsUnorderedX and not IsUnorderedVisible) then
continue; continue;
xmin := IfThen(csoExtrapolateLeft in FOptions, ext.a.x, Max(ext.a.x, s.FX[0]));
xmax := IfThen(csoExtrapolateRight in Options, ext.b.x, Min(ext.b.x, s.FX[High(s.FX)])); GetSplineXRange(s, xmin, xmax);
with TPointsDrawFuncHelper.Create(Self, xmin, xmax, @s.Calculate, Step) do with TPointsDrawFuncHelper.Create(Self, xmin, xmax, @s.Calculate, Step) do
try try
if not GetNearestPoint(AParams, r) or if not GetNearestPoint(AParams, r) or
@ -1512,6 +1517,22 @@ begin
end; end;
end; end;
procedure TCubicSplineSeries.GetSplineXRange(ASpline: TSpline;
out AXMin, AXMax: Double);
var
ext: TDoubleRect;
begin
ext := FChart.CurrentExtent;
AXmin := IfThen(
(csoExtrapolateLeft in FOptions) and (ASpline = FSplines[0]),
ext.a.x, Max(ext.a.x, AxisToGraphX(ASpline.FX[0]))
);
AXmax := IfThen(
(csoExtrapolateRight in FOptions) and (ASpline = FSplines[High(FSplines)]),
ext.b.x, Min(ext.b.x, AxisToGraphX(ASpline.FX[High(ASpline.FX)]))
);
end;
function TCubicSplineSeries.IsUnorderedVisible: Boolean; function TCubicSplineSeries.IsUnorderedVisible: Boolean;
begin begin
Result := (csoDrawUnorderedX in Options) and BadDataPen.EffVisible; Result := (csoDrawUnorderedX in Options) and BadDataPen.EffVisible;

View File

@ -465,7 +465,6 @@ var
procedure DrawArc3D(ASlice: TPieSlice; AInside: Boolean); procedure DrawArc3D(ASlice: TPieSlice; AInside: Boolean);
var var
i, numSteps: Integer; i, numSteps: Integer;
a: Double;
p: Array of TPoint; p: Array of TPoint;
angle1, angle2: Double; angle1, angle2: Double;
clr: TColor; clr: TColor;
@ -627,14 +626,12 @@ var
var var
prevLabelPoly: TPointArray = nil; prevLabelPoly: TPointArray = nil;
ps: TPieSlice; ps: TPieSlice;
r: TPoint;
begin begin
if IsEmpty then exit; if IsEmpty then exit;
Marks.SetAdditionalAngle(0); Marks.SetAdditionalAngle(0);
Measure(ADrawer); Measure(ADrawer);
innerRadius := CalcInnerRadius; innerRadius := CalcInnerRadius;
r := FixAspectRatio(Point(FRadius, FRadius));
if Depth > 0 then begin if Depth > 0 then begin
scaled_depth := ADrawer.Scale(Depth); scaled_depth := ADrawer.Scale(Depth);

View File

@ -78,10 +78,6 @@ type
procedure SetSeriesColor(AValue: TColor); procedure SetSeriesColor(AValue: TColor);
procedure SetUseZeroLevel(AValue: Boolean); procedure SetUseZeroLevel(AValue: Boolean);
procedure SetZeroLevel(AValue: Double); procedure SetZeroLevel(AValue: Double);
strict protected
function GetLabelDataPoint(AIndex, AYIndex: Integer): TDoublePoint; override;
function ToolTargetDistance(const AParams: TNearestPointParams;
AGraphPt: TDoublePoint; APointIdx, AXIdx, AYIdx: Integer): Integer; override;
protected protected
procedure BarOffsetWidth( procedure BarOffsetWidth(
AX: Double; AIndex: Integer; out AOffset, AWidth: Double); AX: Double; AIndex: Integer; out AOffset, AWidth: Double);
@ -90,9 +86,12 @@ type
procedure DrawHexPrism(ADrawer: IChartDrawer; const ARect: TRect; ADepth: Integer); procedure DrawHexPrism(ADrawer: IChartDrawer; const ARect: TRect; ADepth: Integer);
procedure DrawPyramidBar(ADrawer: IChartDrawer; const ARect: TRect; ADepth: Integer); procedure DrawPyramidBar(ADrawer: IChartDrawer; const ARect: TRect; ADepth: Integer);
procedure DrawRectBar(ADrawer: IChartDrawer; const ARect: TRect; ADepth: Integer); procedure DrawRectBar(ADrawer: IChartDrawer; const ARect: TRect; ADepth: Integer);
function GetLabelDataPoint(AIndex, AYIndex: Integer): TDoublePoint; override;
procedure GetLegendItems(AItems: TChartLegendItems); override; procedure GetLegendItems(AItems: TChartLegendItems); override;
function GetSeriesColor: TColor; override; function GetSeriesColor: TColor; override;
function GetZeroLevel: Double; override; function GetZeroLevel: Double; override;
function ToolTargetDistance(const AParams: TNearestPointParams;
AGraphPt: TDoublePoint; APointIdx, AXIdx, AYIdx: Integer): Integer; override;
procedure UpdateMargins(ADrawer: IChartDrawer; var AMargins: TRect); override; procedure UpdateMargins(ADrawer: IChartDrawer; var AMargins: TRect); override;
public public
procedure Assign(ASource: TPersistent); override; procedure Assign(ASource: TPersistent); override;
@ -1157,7 +1156,6 @@ procedure TBarSeries.Draw(ADrawer: IChartDrawer);
var var
pointIndex, stackIndex: Integer; pointIndex, stackIndex: Integer;
scaled_depth: Integer; scaled_depth: Integer;
scaled_depth2: Integer;
procedure DrawBar(const AR: TRect); procedure DrawBar(const AR: TRect);
var var
@ -1165,9 +1163,6 @@ var
defaultDrawing: Boolean = true; defaultDrawing: Boolean = true;
c: TColor; c: TColor;
ic: IChartTCanvasDrawer; ic: IChartTCanvasDrawer;
pts: TPointArray;
a, b, cx, cy, factor: Double;
h: Integer;
begin begin
ADrawer.Pen := BarPen; ADrawer.Pen := BarPen;
ADrawer.Brush := BarBrush; ADrawer.Brush := BarBrush;
@ -1239,7 +1234,6 @@ begin
ExpandRange(ext2.a.Y, ext2.b.Y, 1.0); ExpandRange(ext2.a.Y, ext2.b.Y, 1.0);
scaled_depth := ADrawer.Scale(Depth); scaled_depth := ADrawer.Scale(Depth);
scaled_depth2 := scaled_depth div 2;
if UseZeroLevel then if UseZeroLevel then
zero := ZeroLevel zero := ZeroLevel
else else