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
chart margin and the space reserved for series marks.
</descr>
<seealso>
<link id="TChart.LogicalExtent">LogicalExtent</link>
<seealso><link id="TChart.LogicalExtent">LogicalExtent</link>
</seealso>
</element>
<element name="TChart.XGraphMax">

View File

@ -91,7 +91,7 @@ type
ACalc: TTransformFunc; AStep: Integer);
end;
TPointsDrawFuncHelper = class(TDrawFuncHelper)
TPointsDrawFuncHelper = class(TCustomDrawFuncHelper)
protected
procedure ForEachPoint(AXg, AXMax: Double; AOnMoveTo, AOnLineTo: TOnPoint); override;
public
@ -262,8 +262,6 @@ procedure TDrawFuncHelper.ForEachPoint(
var
hint: Integer;
xa, xg1, xa1, dx: Double;
fxg: array of double;
i, j: Integer;
begin
if FGraphStep = 0 then exit;
@ -303,7 +301,7 @@ constructor TPointsDrawFuncHelper.Create(
ASeries: TBasicPointSeries; AMinX, AMaxX: Double; ACalc: TTransformFunc;
AStep: Integer);
begin
inherited Create(ASeries, nil, ACalc, AStep);
inherited Create(ASeries, ACalc, AStep);
FExtent.a.X := Min(AMinX, AMaxX);
FExtent.b.X := Max(AMaxX, AMinX);
end;
@ -318,7 +316,10 @@ begin
if FGraphStep = 0 then exit;
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);
n := Length(ser.FGraphPoints);

View File

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

View File

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

View File

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