mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-20 14:19:17 +02:00
TAChart: Improve drawing of area series
* Extract NormalizeRect procedure * Fix and simplify TAreaSeries.Draw git-svn-id: trunk@20651 -
This commit is contained in:
parent
59b06381b8
commit
a1248af92d
@ -137,6 +137,8 @@ function GetIntervals(AMin, AMax: Double; AInverted: Boolean): TDoubleDynArray;
|
|||||||
function LineIntersectsRect(
|
function LineIntersectsRect(
|
||||||
var AA, AB: TDoublePoint; const ARect: TDoubleRect): Boolean;
|
var AA, AB: TDoublePoint; const ARect: TDoubleRect): Boolean;
|
||||||
|
|
||||||
|
procedure NormalizeRect(var ARect: TRect);
|
||||||
|
|
||||||
function PointDist(const A, B: TPoint): Integer; inline;
|
function PointDist(const A, B: TPoint): Integer; inline;
|
||||||
function PointDistX(const A, B: TPoint): Integer; inline;
|
function PointDistX(const A, B: TPoint): Integer; inline;
|
||||||
function PointDistY(const A, B: TPoint): Integer; inline;
|
function PointDistY(const A, B: TPoint): Integer; inline;
|
||||||
@ -369,6 +371,16 @@ begin
|
|||||||
Result := true;
|
Result := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure NormalizeRect(var ARect: TRect);
|
||||||
|
begin
|
||||||
|
with ARect do begin
|
||||||
|
if Left > Right then
|
||||||
|
Exchange(Left, Right);
|
||||||
|
if Top > Bottom then
|
||||||
|
Exchange(Top, Bottom);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function PointDist(const A, B: TPoint): Integer;
|
function PointDist(const A, B: TPoint): Integer;
|
||||||
begin
|
begin
|
||||||
Result := Sqr(A.X - B.X) + Sqr(A.Y - B.Y);
|
Result := Sqr(A.X - B.X) + Sqr(A.Y - B.Y);
|
||||||
|
@ -194,8 +194,6 @@ type
|
|||||||
ASender: TChartSeries; ACanvas: TCanvas; AIndex: Integer;
|
ASender: TChartSeries; ACanvas: TCanvas; AIndex: Integer;
|
||||||
ACenter: TPoint) of object;
|
ACenter: TPoint) of object;
|
||||||
|
|
||||||
{ TLineSerie }
|
|
||||||
|
|
||||||
{ TLineSeries }
|
{ TLineSeries }
|
||||||
|
|
||||||
TLineSeries = class(TBasicLineSeries)
|
TLineSeries = class(TBasicLineSeries)
|
||||||
@ -1041,10 +1039,7 @@ begin
|
|||||||
with imageBar do begin
|
with imageBar do begin
|
||||||
TopLeft := ParentChart.GraphToImage(graphBar.a);
|
TopLeft := ParentChart.GraphToImage(graphBar.a);
|
||||||
BottomRight := ParentChart.GraphToImage(graphBar.b);
|
BottomRight := ParentChart.GraphToImage(graphBar.b);
|
||||||
if Left > Right then
|
NormalizeRect(imageBar);
|
||||||
Exchange(Left, Right);
|
|
||||||
if Top > Bottom then
|
|
||||||
Exchange(Top, Bottom);
|
|
||||||
|
|
||||||
// Draw a line instead of an empty rectangle.
|
// Draw a line instead of an empty rectangle.
|
||||||
if Bottom = Top then Dec(Top);
|
if Bottom = Top then Dec(Top);
|
||||||
@ -1262,90 +1257,70 @@ end;
|
|||||||
|
|
||||||
procedure TAreaSeries.Draw(ACanvas: TCanvas);
|
procedure TAreaSeries.Draw(ACanvas: TCanvas);
|
||||||
var
|
var
|
||||||
i, xi2a, ymin: Integer;
|
pts: array [0..4] of TPoint;
|
||||||
i1, i2: TPoint;
|
numPts: Integer;
|
||||||
g1, g2: TDoublePoint;
|
|
||||||
|
|
||||||
procedure DrawPart;
|
procedure PushPoint(const A: TPoint);
|
||||||
begin
|
begin
|
||||||
ACanvas.Polygon([Point(i1.X, ymin), i1, i2, Point(i2.X, ymin)]);
|
pts[numPts] := A;
|
||||||
|
Inc(numPts);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
i, ax, bx, ymin: Integer;
|
||||||
|
a, b: TDoublePoint;
|
||||||
|
ext, ext2: TDoubleRect;
|
||||||
|
imageRect: TRect;
|
||||||
begin
|
begin
|
||||||
if Count = 0 then exit;
|
if Count = 0 then exit;
|
||||||
|
|
||||||
ACanvas.Pen.Mode := pmCopy;
|
|
||||||
ACanvas.Pen.Style := psSolid;
|
|
||||||
ACanvas.Pen.Width := 1;
|
|
||||||
ACanvas.Brush.Assign(AreaBrush);
|
ACanvas.Brush.Assign(AreaBrush);
|
||||||
|
ACanvas.Pen.Assign(AreaLinesPen);
|
||||||
|
|
||||||
|
ext := ParentChart.CurrentExtent;
|
||||||
|
ext2 := ext;
|
||||||
|
ExpandRange(ext2.a.X, ext2.b.X, 0.1);
|
||||||
|
ExpandRange(ext2.a.Y, ext2.b.Y, 1.0);
|
||||||
|
|
||||||
ymin := ParentChart.ClipRect.Bottom - 1;
|
ymin := ParentChart.ClipRect.Bottom - 1;
|
||||||
|
|
||||||
for i := 0 to Count - 2 do begin
|
for i := 0 to Count - 2 do begin
|
||||||
GetCoords(i, g1, i1);
|
a := DoublePoint(Source[i]^);
|
||||||
GetCoords(i + 1, g2, i2);
|
b := DoublePoint(Source[i + 1]^);
|
||||||
|
if a.X > b.X then begin
|
||||||
ACanvas.Pen.Color:= clBlack;
|
Exchange(a.X, b.X);
|
||||||
ACanvas.Brush.Color:= ColorOrDefault(Source[i]^.Color);
|
Exchange(a.Y, b.Y);
|
||||||
|
|
||||||
// top line is totally inside the viewport
|
|
||||||
if
|
|
||||||
ParentChart.IsPointInViewPort(g1) and ParentChart.IsPointInViewPort(g2)
|
|
||||||
then begin
|
|
||||||
if FStairs then begin
|
|
||||||
if FInvertedStairs then
|
|
||||||
ACanvas.Polygon([Point(i1.X, ymin), i1, i2, Point(i2.X, ymin)])
|
|
||||||
else
|
|
||||||
ACanvas.Polygon([
|
|
||||||
Point(i1.X, ymin), i1, Point(i2.X, i1.Y), Point(i2.X, ymin)])
|
|
||||||
end else
|
|
||||||
DrawPart;
|
|
||||||
continue;
|
|
||||||
end;
|
end;
|
||||||
|
if (a.X > ext.b.X) or (b.X < ext.a.X) then continue;
|
||||||
with ParentChart do
|
if Stairs then begin
|
||||||
if // top line is totally outside the viewport
|
if InvertedStairs then
|
||||||
(g1.X < XGraphMin) and (g2.X < XGraphMin) or
|
a.Y := b.Y
|
||||||
(g1.X > XGraphMax) and (g2.X > XGraphMax) or
|
else
|
||||||
(g1.Y < YGraphMin) and (g2.Y < YGraphMin)
|
b.Y := a.Y;
|
||||||
then
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if g1.Y > g2.Y then begin
|
|
||||||
Exchange(g1, g2);
|
|
||||||
Exchange(i1.X, i2.X); Exchange(i1.Y, i2.Y);
|
|
||||||
end;
|
end;
|
||||||
|
ax := ParentChart.XGraphToImage(Max(a.X, ext2.a.X));
|
||||||
|
bx := ParentChart.XGraphToImage(Min(b.X, ext2.b.X));
|
||||||
|
|
||||||
with ParentChart do
|
if LineIntersectsRect(a, b, ext2) then begin
|
||||||
if g1.Y = g2.Y then begin
|
numPts := 0;
|
||||||
if g1.X > g2.X then
|
PushPoint(Point(ax, ymin));
|
||||||
Exchange(g1, g2);
|
if a.Y = ext2.b.Y then
|
||||||
if g1.X < XGraphMin then i1.X := ClipRect.Left;
|
PushPoint(Point(ax, ParentChart.YGraphToImage(a.Y)));
|
||||||
if g2.X > XGraphMax then i2.X := ClipRect.Right;
|
PushPoint(ParentChart.GraphToImage(a));
|
||||||
end
|
PushPoint(ParentChart.GraphToImage(b));
|
||||||
else if g1.X = g2.X then begin
|
if b.Y = ext2.b.Y then
|
||||||
if g1.Y < YGraphMin then i1.Y := ymin;
|
PushPoint(Point(bx, ParentChart.YGraphToImage(b.Y)));
|
||||||
if g2.Y > YGraphMax then i2.Y := ClipRect.Top;
|
PushPoint(Point(bx, ymin));
|
||||||
end
|
ACanvas.Polygon(pts, false, 0, numPts);
|
||||||
else if LineInViewPort(g1, g2) then begin
|
end
|
||||||
xi2a := i2.X;
|
else begin
|
||||||
i1 := GraphToImage(g1);
|
if a.Y > ext.b.Y then begin
|
||||||
i2 := GraphToImage(g2);
|
imageRect := Rect(ax, ParentChart.ClipRect.Top - 1, bx, ymin);
|
||||||
{if i2.Y <= ymin then} begin
|
NormalizeRect(imageRect);
|
||||||
ACanvas.Polygon([
|
ACanvas.Rectangle(imageRect);
|
||||||
Point(i1.X, ymin), i1, i2, Point(xi2a, ymin), Point(xi2a, ymin)]);
|
|
||||||
continue;
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else if g2.Y >= YGraphMax then begin
|
|
||||||
i1.Y := ymin;
|
|
||||||
i2.Y := ymin;
|
|
||||||
i1.X := EnsureRange(i1.X, ClipRect.Left, ClipRect.Right);
|
|
||||||
i2.X := EnsureRange(i2.X, ClipRect.Left, ClipRect.Right);
|
|
||||||
end;
|
end;
|
||||||
DrawPart;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
DrawLabels(ACanvas, false);
|
DrawLabels(ACanvas, false);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user