mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-29 19:52:26 +02:00
TAChart: Pre-filter points outside of the current extent in TLineSeries.Draw
git-svn-id: trunk@25921 -
This commit is contained in:
parent
1e84a4ad0a
commit
160c2dc205
@ -408,20 +408,20 @@ var
|
|||||||
// For extremely long series (10000 points or more), the Canvas.Line
|
// For extremely long series (10000 points or more), the Canvas.Line
|
||||||
// call becomes a bottleneck. So represent a serie as a sequence of polylines.
|
// call becomes a bottleneck. So represent a serie as a sequence of polylines.
|
||||||
// This achieves approximately 3x speedup for the typical case.
|
// This achieves approximately 3x speedup for the typical case.
|
||||||
SetLength(points, 2 * Count);
|
SetLength(points, 2 * Length(gp));
|
||||||
SetLength(breaks, Count + 1);
|
SetLength(breaks, Length(gp) + 1);
|
||||||
case LineType of
|
case LineType of
|
||||||
ltFromPrevious: begin
|
ltFromPrevious: begin
|
||||||
for i := 0 to Count - 2 do
|
for i := 0 to High(gp) - 1 do
|
||||||
CacheLine(gp[i], gp[i + 1]);
|
CacheLine(gp[i], gp[i + 1]);
|
||||||
end;
|
end;
|
||||||
ltFromOrigin: begin
|
ltFromOrigin: begin
|
||||||
orig := AxisToGraph(ZeroDoublePoint);
|
orig := AxisToGraph(ZeroDoublePoint);
|
||||||
for i := 0 to Count - 1 do
|
for i := 0 to High(gp) do
|
||||||
CacheLine(orig, gp[i]);
|
CacheLine(orig, gp[i]);
|
||||||
end;
|
end;
|
||||||
ltStepXY, ltStepYX: begin
|
ltStepXY, ltStepYX: begin
|
||||||
for i := 0 to Count - 2 do begin
|
for i := 0 to High(gp) - 1 do begin
|
||||||
if (LineType = ltStepXY) xor IsRotated then
|
if (LineType = ltStepXY) xor IsRotated then
|
||||||
m := DoublePoint(gp[i + 1].X, gp[i].Y)
|
m := DoublePoint(gp[i + 1].X, gp[i].Y)
|
||||||
else
|
else
|
||||||
@ -451,33 +451,44 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
i: Integer;
|
i, lb, ub: Integer;
|
||||||
ai: TPoint;
|
ai: TPoint;
|
||||||
ext: TDoubleRect;
|
ext: TDoubleRect;
|
||||||
begin
|
begin
|
||||||
|
// Do not draw anything if the series extent does not intersect CurrentExtent.
|
||||||
ext.a := AxisToGraph(Source.Extent.a);
|
ext.a := AxisToGraph(Source.Extent.a);
|
||||||
ext.b := AxisToGraph(Source.Extent.b);
|
ext.b := AxisToGraph(Source.Extent.b);
|
||||||
if LineType = ltFromOrigin then
|
if LineType = ltFromOrigin then
|
||||||
ExpandRect(ext, AxisToGraph(ZeroDoublePoint));
|
ExpandRect(ext, AxisToGraph(ZeroDoublePoint));
|
||||||
if not RectIntersectsRect(ext, ParentChart.CurrentExtent) then exit;
|
if not RectIntersectsRect(ext, ParentChart.CurrentExtent) then exit;
|
||||||
|
|
||||||
SetLength(gp, Count);
|
// Find an interval of x-values intersecting the CurrentExtent.
|
||||||
|
// Requires monotonic (but not necessarily increasing) axis transformation.
|
||||||
|
lb := 0;
|
||||||
|
ub := Count - 1;
|
||||||
|
if LineType <> ltFromOrigin then begin
|
||||||
|
Source.FindBounds(GraphToAxisX(ext.a.X), GraphToAxisX(ext.b.X), lb, ub);
|
||||||
|
lb := Max(lb - 1, 0);
|
||||||
|
ub := Min(ub + 1, Count - 1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
SetLength(gp, ub - lb + 1);
|
||||||
if (AxisIndexX < 0) and (AxisIndexY < 0) then
|
if (AxisIndexX < 0) and (AxisIndexY < 0) then
|
||||||
// Optimization: bypass transformations in the default case.
|
// Optimization: bypass transformations in the default case.
|
||||||
for i := 0 to Count - 1 do
|
for i := lb to ub do
|
||||||
with Source[i]^ do
|
with Source[i]^ do
|
||||||
gp[i] := DoublePoint(X, Y)
|
gp[i - lb] := DoublePoint(X, Y)
|
||||||
else
|
else
|
||||||
for i := 0 to Count - 1 do
|
for i := lb to ub do
|
||||||
gp[i] := GetGraphPoint(i);
|
gp[i - lb] := GetGraphPoint(i);
|
||||||
|
|
||||||
DrawLines;
|
DrawLines;
|
||||||
DrawLabels(ACanvas);
|
DrawLabels(ACanvas);
|
||||||
|
|
||||||
if FShowPoints then
|
if FShowPoints then
|
||||||
for i := 0 to Count - 1 do begin
|
for i := lb to ub do begin
|
||||||
if not ParentChart.IsPointInViewPort(gp[i]) then continue;
|
if not ParentChart.IsPointInViewPort(gp[i - lb]) then continue;
|
||||||
ai := ParentChart.GraphToImage(gp[i]);
|
ai := ParentChart.GraphToImage(gp[i - lb]);
|
||||||
FPointer.Draw(ACanvas, ai, GetColor(i));
|
FPointer.Draw(ACanvas, ai, GetColor(i));
|
||||||
if Assigned(FOnDrawPointer) then
|
if Assigned(FOnDrawPointer) then
|
||||||
FOnDrawPointer(Self, ACanvas, i, ai);
|
FOnDrawPointer(Self, ACanvas, i, ai);
|
||||||
|
@ -61,6 +61,7 @@ type
|
|||||||
public
|
public
|
||||||
class procedure CheckFormat(const AFormat: String);
|
class procedure CheckFormat(const AFormat: String);
|
||||||
function Extent: TDoubleRect; virtual;
|
function Extent: TDoubleRect; virtual;
|
||||||
|
procedure FindBounds(AXMin, AXMax: Double; out ALB, AUB: Integer);
|
||||||
function FormatItem(const AFormat: String; AIndex: Integer): String;
|
function FormatItem(const AFormat: String; AIndex: Integer): String;
|
||||||
function IsSorted: Boolean; virtual;
|
function IsSorted: Boolean; virtual;
|
||||||
procedure ValuesInRange(
|
procedure ValuesInRange(
|
||||||
@ -306,6 +307,18 @@ begin
|
|||||||
Result := FExtent;
|
Result := FExtent;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomChartSource.FindBounds(
|
||||||
|
AXMin, AXMax: Double; out ALB, AUB: Integer);
|
||||||
|
begin
|
||||||
|
EnsureOrder(AXMin, AXMax);
|
||||||
|
ALB := 0;
|
||||||
|
while (ALB < Count) and (Item[ALB]^.X < AXMin) do
|
||||||
|
Inc(ALB);
|
||||||
|
AUB := Count - 1;
|
||||||
|
while (AUB > 0) and (Item[AUB]^.X < AXMax) do
|
||||||
|
Inc(AUB);
|
||||||
|
end;
|
||||||
|
|
||||||
function TCustomChartSource.FormatItem(
|
function TCustomChartSource.FormatItem(
|
||||||
const AFormat: String; AIndex: Integer): String;
|
const AFormat: String; AIndex: Integer): String;
|
||||||
const
|
const
|
||||||
|
Loading…
Reference in New Issue
Block a user