mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-10 01:36:16 +02:00
TAChart: Use IChartDrawer to draw labels
git-svn-id: trunk@29531 -
This commit is contained in:
parent
e3c19880f0
commit
829ea72a9d
@ -479,8 +479,7 @@ var
|
||||
ADrawer.PrepareSimplePen(TickColor);
|
||||
LineZ(ATickRect.TopLeft, ATickRect.BottomRight);
|
||||
ALabelCenter += AZOffset;
|
||||
Marks.DrawLabel(
|
||||
ADrawer.Canvas, ALabelCenter, ALabelCenter, AText, prevLabelPoly);
|
||||
Marks.DrawLabel(ADrawer, ALabelCenter, ALabelCenter, AText, prevLabelPoly);
|
||||
end;
|
||||
|
||||
procedure DrawXMark(AY: Integer; AMark: Double; const AText: String);
|
||||
@ -492,13 +491,13 @@ var
|
||||
if Grid.Visible then begin
|
||||
ADrawer.Pen := Grid;
|
||||
ADrawer.SetBrushParams(bsClear, clTAColor);
|
||||
TryApplyStripes(ADrawer, stripeIndex);
|
||||
BarZ(prevCoord + 1, AClipRect.Top + 1, x, AClipRect.Bottom);
|
||||
if TryApplyStripes(ADrawer, stripeIndex) then
|
||||
BarZ(prevCoord + 1, AClipRect.Top + 1, x, AClipRect.Bottom);
|
||||
LineZ(Point(x, AClipRect.Top), Point(x, AClipRect.Bottom));
|
||||
prevCoord := x;
|
||||
end;
|
||||
|
||||
d := TickLength + Marks.CenterOffset(ADrawer.Canvas, AText).cy;
|
||||
d := TickLength + Marks.CenterOffset(ADrawer, AText).cy;
|
||||
if Alignment = calTop then
|
||||
d := -d;
|
||||
DrawLabelAndTick(
|
||||
@ -514,13 +513,13 @@ var
|
||||
if Grid.Visible then begin
|
||||
ADrawer.Pen := Grid;
|
||||
ADrawer.SetBrushParams(bsClear, clTAColor);
|
||||
TryApplyStripes(ADrawer, stripeIndex);
|
||||
BarZ(AClipRect.Left + 1, prevCoord, AClipRect.Right, y);
|
||||
if TryApplyStripes(ADrawer, stripeIndex) then
|
||||
BarZ(AClipRect.Left + 1, prevCoord, AClipRect.Right, y);
|
||||
LineZ(Point(AClipRect.Left, y), Point(AClipRect.Right, y));
|
||||
prevCoord := y;
|
||||
end;
|
||||
|
||||
d := TickLength + Marks.CenterOffset(ADrawer.Canvas, AText).cx;
|
||||
d := TickLength + Marks.CenterOffset(ADrawer, AText).cx;
|
||||
if Alignment = calLeft then
|
||||
d := -d;
|
||||
DrawLabelAndTick(
|
||||
@ -544,7 +543,7 @@ begin
|
||||
end;
|
||||
if Grid.Visible and TryApplyStripes(ADrawer, stripeIndex) then
|
||||
if IsVertical then
|
||||
BarZ(AClipRect.Left + 1, AClipRect.Top, AClipRect.Right, prevCoord)
|
||||
BarZ(AClipRect.Left + 1, AClipRect.Top + 1, AClipRect.Right, prevCoord)
|
||||
else
|
||||
BarZ(prevCoord + 1, AClipRect.Top + 1, AClipRect.Right, AClipRect.Bottom);
|
||||
end;
|
||||
@ -566,7 +565,7 @@ begin
|
||||
calBottom: p.Y := FTitleRect.Bottom + d;
|
||||
end;
|
||||
p += AZOffset;
|
||||
Title.DrawLabel(ADrawer.Canvas, p, p, Title.Caption, dummy);
|
||||
Title.DrawLabel(ADrawer, p, p, Title.Caption, dummy);
|
||||
end;
|
||||
|
||||
function TChartAxis.GetDisplayName: string;
|
||||
@ -650,7 +649,7 @@ procedure TChartAxis.Measure(
|
||||
if AFirstPass then
|
||||
t += SOME_DIGIT;
|
||||
d := IfThen(Marks.DistanceToCenter, 2, 1);
|
||||
with Marks.MeasureLabel(ADrawer.Canvas, t) do begin
|
||||
with Marks.MeasureLabel(ADrawer, t) do begin
|
||||
Result.cx := Max(cx div d, Result.cx);
|
||||
Result.cy := Max(cy div d, Result.cy);
|
||||
end;
|
||||
@ -663,7 +662,7 @@ procedure TChartAxis.Measure(
|
||||
begin
|
||||
if not Title.Visible or (Title.Caption = '') then
|
||||
exit(0);
|
||||
sz := Title.MeasureLabel(ADrawer.Canvas, Title.Caption);
|
||||
sz := Title.MeasureLabel(ADrawer, Title.Caption);
|
||||
|
||||
Result := IfThen(IsVertical, sz.cx, sz.cy) + Title.Distance;
|
||||
end;
|
||||
|
@ -24,8 +24,8 @@ interface
|
||||
|
||||
uses
|
||||
Classes, Graphics, SysUtils,
|
||||
TAChartAxis, TAChartUtils, TACustomSource, TAGraph, TALegend, TASources,
|
||||
TAStyles, TATypes;
|
||||
TAChartAxis, TAChartUtils, TACustomSource, TADrawUtils, TAGraph, TALegend,
|
||||
TASources, TAStyles, TATypes;
|
||||
|
||||
const
|
||||
DEF_AXIS_INDEX = -1;
|
||||
@ -202,7 +202,7 @@ type
|
||||
procedure PrepareGraphPoints(
|
||||
const AExtent: TDoubleRect; AFilterByExtent: Boolean);
|
||||
procedure UpdateGraphPoints(AIndex: Integer);
|
||||
procedure UpdateMargins(ACanvas: TCanvas; var AMargins: TRect); override;
|
||||
procedure UpdateMargins(ADrawer: IChartDrawer; var AMargins: TRect); override;
|
||||
procedure UpdateMinXRange;
|
||||
property UseReticule: Boolean
|
||||
read FUseReticule write SetUseReticule default false;
|
||||
@ -744,6 +744,7 @@ end;
|
||||
procedure TBasicPointSeries.DrawLabels(ACanvas: TCanvas);
|
||||
var
|
||||
prevLabelPoly: TPointArray;
|
||||
drawer: IChartDrawer;
|
||||
|
||||
procedure DrawLabel(
|
||||
const AText: String; const ADataPoint: TPoint; ADir: TLabelDirection);
|
||||
@ -754,14 +755,15 @@ var
|
||||
center: TPoint;
|
||||
begin
|
||||
if AText = '' then exit;
|
||||
center := ADataPoint + OFFSETS[ADir] * Marks.CenterOffset(ACanvas, AText);
|
||||
Marks.DrawLabel(ACanvas, ADataPoint, center, AText, prevLabelPoly);
|
||||
center := ADataPoint + OFFSETS[ADir] * Marks.CenterOffset(drawer, AText);
|
||||
Marks.DrawLabel(drawer, ADataPoint, center, AText, prevLabelPoly);
|
||||
end;
|
||||
|
||||
var
|
||||
g: TDoublePoint;
|
||||
i: Integer;
|
||||
begin
|
||||
drawer := TCanvasDrawer.Create(ACanvas);
|
||||
if not Marks.IsMarkLabelsVisible then exit;
|
||||
for i := 0 to Count - 1 do begin
|
||||
g := GetGraphPoint(i);
|
||||
@ -898,7 +900,8 @@ begin
|
||||
FGraphPoints[i - FLoBound].Y += AxisToGraphY(Source[i]^.YList[AIndex]);
|
||||
end;
|
||||
|
||||
procedure TBasicPointSeries.UpdateMargins(ACanvas: TCanvas; var AMargins: TRect);
|
||||
procedure TBasicPointSeries.UpdateMargins(
|
||||
ADrawer: IChartDrawer; var AMargins: TRect);
|
||||
const
|
||||
LABEL_TO_BORDER = 4;
|
||||
var
|
||||
@ -916,7 +919,7 @@ begin
|
||||
|
||||
dir := GetLabelDirection(i);
|
||||
d := IfThen(Marks.DistanceToCenter, 2, 1);
|
||||
with Marks.MeasureLabel(ACanvas, labelText) do
|
||||
with Marks.MeasureLabel(ADrawer, labelText) do
|
||||
dist := IfThen(dir in [ldLeft, ldRight], cx, cy) div d;
|
||||
m[dir] := Max(m[dir], dist + Marks.Distance + LABEL_TO_BORDER);
|
||||
end;
|
||||
|
@ -55,13 +55,16 @@ type
|
||||
{ IChartDrawer }
|
||||
|
||||
IChartDrawer = interface
|
||||
procedure AddToFontOrientation(ADelta: Integer);
|
||||
procedure ClippingStart(const AClipRect: TRect);
|
||||
procedure ClippingStart;
|
||||
procedure ClippingStop;
|
||||
procedure FillRect(AX1, AY1, AX2, AY2: Integer);
|
||||
function GetCanvas: TCanvas;
|
||||
function HasCanvas: Boolean;
|
||||
procedure Line(AX1, AY1, AX2, AY2: Integer);
|
||||
procedure Line(const AP1, AP2: TPoint);
|
||||
procedure Polygon(const APoints: array of TPoint);
|
||||
procedure PrepareSimplePen(AColor: TChartColor);
|
||||
procedure RadialPie(
|
||||
AX1, AY1, AX2, AY2: Integer;
|
||||
@ -113,6 +116,8 @@ type
|
||||
procedure SetFont(AFont: TFPCustomFont);
|
||||
procedure SetPen(APen: TFPCustomPen);
|
||||
public
|
||||
procedure AddToFontOrientation(ADelta: Integer);
|
||||
procedure ClippingStart;
|
||||
procedure ClippingStart(const AClipRect: TRect);
|
||||
procedure ClippingStop;
|
||||
constructor Create(ACanvas: TCanvas);
|
||||
@ -121,6 +126,7 @@ type
|
||||
function HasCanvas: Boolean;
|
||||
procedure Line(AX1, AY1, AX2, AY2: Integer);
|
||||
procedure Line(const AP1, AP2: TPoint);
|
||||
procedure Polygon(const APoints: array of TPoint);
|
||||
procedure PrepareSimplePen(AColor: TChartColor);
|
||||
procedure RadialPie(
|
||||
AX1, AY1, AX2, AY2: Integer;
|
||||
@ -323,12 +329,23 @@ end;
|
||||
|
||||
{ TCanvasDrawer }
|
||||
|
||||
procedure TCanvasDrawer.AddToFontOrientation(ADelta: Integer);
|
||||
begin
|
||||
with FCanvas.Font do
|
||||
Orientation := Orientation + ADelta;
|
||||
end;
|
||||
|
||||
procedure TCanvasDrawer.ClippingStart(const AClipRect: TRect);
|
||||
begin
|
||||
FCanvas.ClipRect := AClipRect;
|
||||
FCanvas.Clipping := true;
|
||||
end;
|
||||
|
||||
procedure TCanvasDrawer.ClippingStart;
|
||||
begin
|
||||
FCanvas.Clipping := true;
|
||||
end;
|
||||
|
||||
procedure TCanvasDrawer.ClippingStop;
|
||||
begin
|
||||
FCanvas.Clipping := false;
|
||||
@ -364,6 +381,11 @@ begin
|
||||
FCanvas.Line(AP1, AP2);
|
||||
end;
|
||||
|
||||
procedure TCanvasDrawer.Polygon(const APoints: array of TPoint);
|
||||
begin
|
||||
FCanvas.Polygon(APoints);
|
||||
end;
|
||||
|
||||
procedure TCanvasDrawer.PrepareSimplePen(AColor: TChartColor);
|
||||
begin
|
||||
TADrawUtils.PrepareSimplePen(FCanvas, AColor);
|
||||
|
@ -63,7 +63,7 @@ type
|
||||
procedure SetDepth(AValue: TChartDistance); virtual; abstract;
|
||||
procedure SetTitle(const AValue: String); virtual; abstract;
|
||||
procedure SetZPosition(AValue: TChartDistance); virtual; abstract;
|
||||
procedure UpdateMargins(ACanvas: TCanvas; var AMargins: TRect); virtual;
|
||||
procedure UpdateMargins(ADrawer: IChartDrawer; var AMargins: TRect); virtual;
|
||||
procedure VisitSources(
|
||||
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData); virtual;
|
||||
|
||||
@ -858,7 +858,7 @@ begin
|
||||
Result := FMargins.Data;
|
||||
for i := 0 to SeriesCount - 1 do
|
||||
if Series[i].Active then
|
||||
Series[i].UpdateMargins(ADrawer.Canvas, Result);
|
||||
Series[i].UpdateMargins(ADrawer, Result);
|
||||
end;
|
||||
|
||||
function TChart.GetSeriesCount: Integer;
|
||||
@ -1285,9 +1285,9 @@ begin
|
||||
end;
|
||||
|
||||
procedure TBasicChartSeries.UpdateMargins(
|
||||
ACanvas: TCanvas; var AMargins: TRect);
|
||||
ADrawer: IChartDrawer; var AMargins: TRect);
|
||||
begin
|
||||
Unused(ACanvas, AMargins);
|
||||
Unused(ADrawer, AMargins);
|
||||
end;
|
||||
|
||||
procedure TBasicChartSeries.VisitSources(
|
||||
|
@ -128,7 +128,7 @@ type
|
||||
private
|
||||
function GetDistanceToCenter: Boolean;
|
||||
function LabelAngle: Double; inline;
|
||||
procedure PutLabelFontTo(ACanvas: TCanvas);
|
||||
procedure PutLabelFontTo(ADrawer: IChartDrawer);
|
||||
procedure SetAttachment(AValue: TChartMarkAttachment);
|
||||
procedure SetDistanceToCenter(AValue: Boolean);
|
||||
protected
|
||||
@ -160,14 +160,14 @@ type
|
||||
destructor Destroy; override;
|
||||
|
||||
public
|
||||
procedure Assign(Source: TPersistent); override;
|
||||
function CenterOffset(ACanvas: TCanvas; const AText: String): TSize;
|
||||
procedure Assign(ASource: TPersistent); override;
|
||||
function CenterOffset(ADrawer: IChartDrawer; const AText: String): TSize;
|
||||
procedure DrawLabel(
|
||||
ACanvas: TCanvas; const ADataPoint, ALabelCenter: TPoint;
|
||||
ADrawer: IChartDrawer; const ADataPoint, ALabelCenter: TPoint;
|
||||
const AText: String; var APrevLabelPoly: TPointArray);
|
||||
function GetLabelPolygon(ASize: TPoint): TPointArray;
|
||||
function IsMarkLabelsVisible: Boolean;
|
||||
function MeasureLabel(ACanvas: TCanvas; const AText: String): TSize;
|
||||
function MeasureLabel(ADrawer: IChartDrawer; const AText: String): TSize;
|
||||
procedure SetAdditionalAngle(AAngle: Double);
|
||||
public
|
||||
property DistanceToCenter: Boolean
|
||||
@ -482,10 +482,10 @@ end;
|
||||
|
||||
{ TGenericChartMarks }
|
||||
|
||||
procedure TGenericChartMarks.Assign(Source: TPersistent);
|
||||
procedure TGenericChartMarks.Assign(ASource: TPersistent);
|
||||
begin
|
||||
if Source is Self.ClassType then
|
||||
with TGenericChartMarks(Source) do begin
|
||||
if ASource is Self.ClassType then
|
||||
with TGenericChartMarks(ASource) do begin
|
||||
Self.FClipped := FClipped;
|
||||
Self.FDistance := FDistance;
|
||||
Self.FFormat := FFormat;
|
||||
@ -498,15 +498,15 @@ begin
|
||||
Self.FOverlapPolicy := FOverlapPolicy;
|
||||
Self.FStyle := FStyle;
|
||||
end;
|
||||
inherited Assign(Source);
|
||||
inherited Assign(ASource);
|
||||
end;
|
||||
|
||||
function TGenericChartMarks.CenterOffset(
|
||||
ACanvas: TCanvas; const AText: String): TSize;
|
||||
ADrawer: IChartDrawer; const AText: String): TSize;
|
||||
begin
|
||||
Result := Point(Distance, Distance);
|
||||
if not DistanceToCenter then
|
||||
Result += MeasureLabel(ACanvas, AText) div 2;
|
||||
Result += MeasureLabel(ADrawer, AText) div 2;
|
||||
end;
|
||||
|
||||
constructor TGenericChartMarks.Create(AOwner: TCustomChart);
|
||||
@ -532,16 +532,15 @@ begin
|
||||
end;
|
||||
|
||||
procedure TGenericChartMarks.DrawLabel(
|
||||
ACanvas: TCanvas; const ADataPoint, ALabelCenter: TPoint;
|
||||
ADrawer: IChartDrawer; const ADataPoint, ALabelCenter: TPoint;
|
||||
const AText: String; var APrevLabelPoly: TPointArray);
|
||||
var
|
||||
wasClipping: Boolean = false;
|
||||
labelPoly: TPointArray;
|
||||
ptText: TPoint;
|
||||
i: Integer;
|
||||
begin
|
||||
PutLabelFontTo(ACanvas);
|
||||
ptText := MultiLineTextExtent(ACanvas, AText);
|
||||
PutLabelFontTo(ADrawer);
|
||||
ptText := ADrawer.TextExtent(AText);
|
||||
labelPoly := GetLabelPolygon(ptText);
|
||||
for i := 0 to High(labelPoly) do
|
||||
labelPoly[i] += ALabelCenter;
|
||||
@ -553,23 +552,21 @@ begin
|
||||
exit;
|
||||
APrevLabelPoly := labelPoly;
|
||||
|
||||
if not Clipped and ACanvas.Clipping then begin
|
||||
ACanvas.Clipping := false;
|
||||
wasClipping := true;
|
||||
end;
|
||||
if not Clipped then
|
||||
ADrawer.ClippingStop;
|
||||
|
||||
ACanvas.Pen.Assign(LinkPen);
|
||||
ACanvas.Line(ADataPoint, ALabelCenter);
|
||||
ACanvas.Brush.Assign(LabelBrush);
|
||||
ADrawer.Pen := LinkPen;
|
||||
ADrawer.Line(ADataPoint, ALabelCenter);
|
||||
ADrawer.Brush := LabelBrush;
|
||||
if IsMarginRequired then begin
|
||||
ACanvas.Pen.Assign(Frame);
|
||||
ACanvas.Polygon(labelPoly);
|
||||
ADrawer.Pen := Frame;
|
||||
ADrawer.Polygon(labelPoly);
|
||||
end;
|
||||
|
||||
ptText := RotatePoint(-ptText div 2, LabelAngle) + ALabelCenter;
|
||||
MultiLineTextOut(ACanvas, ptText, AText, taLeftJustify, 0);
|
||||
if wasClipping then
|
||||
ACanvas.Clipping := true;
|
||||
ADrawer.TextOut.Pos(ptText).Text(AText).Done;
|
||||
if not Clipped then
|
||||
ADrawer.ClippingStart;
|
||||
end;
|
||||
|
||||
function TGenericChartMarks.GetDistanceToCenter: Boolean;
|
||||
@ -603,24 +600,22 @@ begin
|
||||
end;
|
||||
|
||||
function TGenericChartMarks.MeasureLabel(
|
||||
ACanvas: TCanvas; const AText: String): TSize;
|
||||
ADrawer: IChartDrawer; const AText: String): TSize;
|
||||
var
|
||||
sz: TPoint;
|
||||
begin
|
||||
PutLabelFontTo(ACanvas);
|
||||
sz := MultiLineTextExtent(ACanvas, AText);
|
||||
PutLabelFontTo(ADrawer);
|
||||
sz := ADrawer.TextExtent(AText);
|
||||
if IsMarginRequired then
|
||||
sz += Point(MARKS_MARGIN_X, MARKS_MARGIN_Y) * 2;
|
||||
Result := MeasureRotatedRect(sz, LabelAngle);
|
||||
end;
|
||||
|
||||
procedure TGenericChartMarks.PutLabelFontTo(ACanvas: TCanvas);
|
||||
procedure TGenericChartMarks.PutLabelFontTo(ADrawer: IChartDrawer);
|
||||
begin
|
||||
with ACanvas.Font do begin
|
||||
Assign(LabelFont);
|
||||
if FAdditionalAngle <> 0 then
|
||||
Orientation := Orientation + RadToOrient(FAdditionalAngle);
|
||||
end;
|
||||
ADrawer.Font := LabelFont;
|
||||
if FAdditionalAngle <> 0 then
|
||||
ADrawer.AddToFontOrientation(RadToOrient(FAdditionalAngle));
|
||||
end;
|
||||
|
||||
procedure TGenericChartMarks.SetAdditionalAngle(AAngle: Double);
|
||||
|
Loading…
Reference in New Issue
Block a user