mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-07 14:39:34 +01:00
TAChart: Use IChartDrawer to draw chart title and footer
git-svn-id: trunk@29528 -
This commit is contained in:
parent
29469237ae
commit
a4fb8cc245
@ -50,6 +50,8 @@ type
|
|||||||
procedure Recall;
|
procedure Recall;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TChartTextOut = class;
|
||||||
|
|
||||||
{ IChartDrawer }
|
{ IChartDrawer }
|
||||||
|
|
||||||
IChartDrawer = interface
|
IChartDrawer = interface
|
||||||
@ -66,7 +68,8 @@ type
|
|||||||
procedure SetFont(AValue: TFPCustomFont);
|
procedure SetFont(AValue: TFPCustomFont);
|
||||||
procedure SetPen(APen: TFPCustomPen);
|
procedure SetPen(APen: TFPCustomPen);
|
||||||
function TextExtent(const AText: String): TPoint;
|
function TextExtent(const AText: String): TPoint;
|
||||||
procedure TextOut(AX, AY: Integer; const AText: String);
|
function TextExtent(AText: TStrings): TPoint;
|
||||||
|
function TextOut: TChartTextOut;
|
||||||
|
|
||||||
property Brush: TFPCustomBrush write SetBrush;
|
property Brush: TFPCustomBrush write SetBrush;
|
||||||
property Canvas: TCanvas read GetCanvas;
|
property Canvas: TCanvas read GetCanvas;
|
||||||
@ -74,6 +77,27 @@ type
|
|||||||
property Pen: TFPCustomPen write SetPen;
|
property Pen: TFPCustomPen write SetPen;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TChartTextOut }
|
||||||
|
|
||||||
|
TChartTextOut = class
|
||||||
|
FAlignment: TAlignment;
|
||||||
|
FDrawer: IChartDrawer;
|
||||||
|
FPos: TPoint;
|
||||||
|
FText1: String;
|
||||||
|
FText2: TStrings;
|
||||||
|
FWidth: Integer;
|
||||||
|
public
|
||||||
|
constructor Create(ADrawer: IChartDrawer);
|
||||||
|
public
|
||||||
|
function Alignment(AAlignment: TAlignment): TChartTextOut;
|
||||||
|
procedure Done;
|
||||||
|
function Pos(AX, AY: Integer): TChartTextOut;
|
||||||
|
function Pos(const APos: TPoint): TChartTextOut;
|
||||||
|
function Text(const AText: String): TChartTextOut;
|
||||||
|
function Text(const AText: TStrings): TChartTextOut;
|
||||||
|
function Width(AWidth: Integer): TChartTextOut;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TCanvasDrawer }
|
{ TCanvasDrawer }
|
||||||
|
|
||||||
TCanvasDrawer = class(TInterfacedObject, IChartDrawer)
|
TCanvasDrawer = class(TInterfacedObject, IChartDrawer)
|
||||||
@ -95,7 +119,8 @@ type
|
|||||||
procedure Rectangle(const ARect: TRect);
|
procedure Rectangle(const ARect: TRect);
|
||||||
procedure SetBrushParams(AStyle: TBrushStyle; AColor: TChartColor);
|
procedure SetBrushParams(AStyle: TBrushStyle; AColor: TChartColor);
|
||||||
function TextExtent(const AText: String): TPoint;
|
function TextExtent(const AText: String): TPoint;
|
||||||
procedure TextOut(AX, AY: Integer; const AText: String);
|
function TextExtent(AText: TStrings): TPoint;
|
||||||
|
function TextOut: TChartTextOut;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure DrawLineDepth(ACanvas: TCanvas; AX1, AY1, AX2, AY2, ADepth: Integer);
|
procedure DrawLineDepth(ACanvas: TCanvas; AX1, AY1, AX2, AY2, ADepth: Integer);
|
||||||
@ -103,10 +128,12 @@ procedure DrawLineDepth(ACanvas: TCanvas; const AP1, AP2: TPoint; ADepth: Intege
|
|||||||
|
|
||||||
function MultiLineTextExtent(ACanvas: TCanvas; const AText: String): TPoint;
|
function MultiLineTextExtent(ACanvas: TCanvas; const AText: String): TPoint;
|
||||||
function MultiLineTextExtent(ACanvas: TCanvas; AText: TStrings): TPoint;
|
function MultiLineTextExtent(ACanvas: TCanvas; AText: TStrings): TPoint;
|
||||||
procedure MultiLineTextOut(ACanvas: TCanvas; APos: TPoint; const AText: String);
|
|
||||||
procedure MultiLineTextOut(
|
procedure MultiLineTextOut(
|
||||||
ACanvas: TCanvas; APos: TPoint; AText: TStrings; AAlignment: TAlignment;
|
ACanvas: TCanvas; APos: TPoint; const AText: String;
|
||||||
AWidth: Integer);
|
AAlignment: TAlignment; AWidth: Integer);
|
||||||
|
procedure MultiLineTextOut(
|
||||||
|
ACanvas: TCanvas; APos: TPoint; AText: TStrings;
|
||||||
|
AAlignment: TAlignment; AWidth: Integer);
|
||||||
|
|
||||||
procedure PrepareSimplePen(ACanvas: TCanvas; AColor: TColor);
|
procedure PrepareSimplePen(ACanvas: TCanvas; AColor: TColor);
|
||||||
procedure PrepareXorPen(ACanvas: TCanvas);
|
procedure PrepareXorPen(ACanvas: TCanvas);
|
||||||
@ -162,7 +189,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure MultiLineTextOut(ACanvas: TCanvas; APos: TPoint; const AText: String);
|
procedure MultiLineTextOut(
|
||||||
|
ACanvas: TCanvas; APos: TPoint; const AText: String; AAlignment: TAlignment;
|
||||||
|
AWidth: Integer);
|
||||||
var
|
var
|
||||||
sl: TStrings;
|
sl: TStrings;
|
||||||
begin
|
begin
|
||||||
@ -173,7 +202,7 @@ begin
|
|||||||
sl := TStringList.Create;
|
sl := TStringList.Create;
|
||||||
try
|
try
|
||||||
sl.Text := AText;
|
sl.Text := AText;
|
||||||
MultiLineTextOut(ACanvas, APos, sl, taLeftJustify, 0);
|
MultiLineTextOut(ACanvas, APos, sl, AAlignment, AWidth);
|
||||||
finally
|
finally
|
||||||
sl.Free;
|
sl.Free;
|
||||||
end;
|
end;
|
||||||
@ -228,6 +257,59 @@ begin
|
|||||||
Result := ACanvas.TextHeight(TYPICAL_TEXT);
|
Result := ACanvas.TextHeight(TYPICAL_TEXT);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TChartTextOut }
|
||||||
|
|
||||||
|
function TChartTextOut.Alignment(AAlignment: TAlignment): TChartTextOut;
|
||||||
|
begin
|
||||||
|
FAlignment := AAlignment;
|
||||||
|
Result := Self;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TChartTextOut.Create(ADrawer: IChartDrawer);
|
||||||
|
begin
|
||||||
|
FDrawer := ADrawer;
|
||||||
|
FAlignment := taLeftJustify;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTextOut.Done;
|
||||||
|
begin
|
||||||
|
if FText2 = nil then
|
||||||
|
MultiLineTextOut(FDrawer.Canvas, FPos, FText1, FAlignment, FWidth)
|
||||||
|
else
|
||||||
|
MultiLineTextOut(FDrawer.Canvas, FPos, FText2, FAlignment, FWidth);
|
||||||
|
Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTextOut.Pos(AX, AY: Integer): TChartTextOut;
|
||||||
|
begin
|
||||||
|
FPos := Point(AX, AY);
|
||||||
|
Result := Self;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTextOut.Pos(const APos: TPoint): TChartTextOut;
|
||||||
|
begin
|
||||||
|
FPos := APos;
|
||||||
|
Result := Self;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTextOut.Text(const AText: String): TChartTextOut;
|
||||||
|
begin
|
||||||
|
FText1 := AText;
|
||||||
|
Result := Self;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTextOut.Text(const AText: TStrings): TChartTextOut;
|
||||||
|
begin
|
||||||
|
FText2 := AText;
|
||||||
|
Result := Self;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTextOut.Width(AWidth: Integer): TChartTextOut;
|
||||||
|
begin
|
||||||
|
FWidth := AWidth;
|
||||||
|
Result := Self;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TCanvasDrawer }
|
{ TCanvasDrawer }
|
||||||
|
|
||||||
constructor TCanvasDrawer.Create(ACanvas: TCanvas);
|
constructor TCanvasDrawer.Create(ACanvas: TCanvas);
|
||||||
@ -292,12 +374,17 @@ end;
|
|||||||
|
|
||||||
function TCanvasDrawer.TextExtent(const AText: String): TPoint;
|
function TCanvasDrawer.TextExtent(const AText: String): TPoint;
|
||||||
begin
|
begin
|
||||||
Result := FCanvas.TextExtent(AText);
|
Result := MultiLineTextExtent(FCanvas, AText);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCanvasDrawer.TextOut(AX, AY: Integer; const AText: String);
|
function TCanvasDrawer.TextExtent(AText: TStrings): TPoint;
|
||||||
begin
|
begin
|
||||||
FCanvas.TextOut(AX, AY, AText);
|
Result := MultiLineTextExtent(FCanvas, AText);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCanvasDrawer.TextOut: TChartTextOut;
|
||||||
|
begin
|
||||||
|
Result := TChartTextOut.Create(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TPenBrushFontRecall }
|
{ TPenBrushFontRecall }
|
||||||
|
|||||||
@ -218,7 +218,6 @@ type
|
|||||||
procedure Clear(ADrawer: IChartDrawer; const ARect: TRect);
|
procedure Clear(ADrawer: IChartDrawer; const ARect: TRect);
|
||||||
procedure DisplaySeries(ADrawer: IChartDrawer);
|
procedure DisplaySeries(ADrawer: IChartDrawer);
|
||||||
procedure DrawBackWall(ACanvas: TCanvas);
|
procedure DrawBackWall(ACanvas: TCanvas);
|
||||||
procedure DrawTitleFoot(ACanvas: TCanvas);
|
|
||||||
procedure MouseDown(
|
procedure MouseDown(
|
||||||
Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
||||||
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
||||||
@ -629,7 +628,7 @@ end;
|
|||||||
|
|
||||||
procedure TChart.Draw(ADrawer: IChartDrawer; const ARect: TRect);
|
procedure TChart.Draw(ADrawer: IChartDrawer; const ARect: TRect);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i, c: Integer;
|
||||||
legendItems: TChartLegendItems = nil;
|
legendItems: TChartLegendItems = nil;
|
||||||
legendRect: TRect;
|
legendRect: TRect;
|
||||||
begin
|
begin
|
||||||
@ -648,7 +647,11 @@ begin
|
|||||||
if not FIsZoomed then
|
if not FIsZoomed then
|
||||||
FLogicalExtent := GetFullExtent;
|
FLogicalExtent := GetFullExtent;
|
||||||
FCurrentExtent := FLogicalExtent;
|
FCurrentExtent := FLogicalExtent;
|
||||||
DrawTitleFoot(ADrawer.Canvas);
|
|
||||||
|
c := (FClipRect.Left + FClipRect.Right) div 2;
|
||||||
|
FTitle.Draw(ADrawer, 1, c, FClipRect.Top);
|
||||||
|
FFoot.Draw(ADrawer, -1, c, FClipRect.Bottom);
|
||||||
|
|
||||||
if Legend.Visible then
|
if Legend.Visible then
|
||||||
PrepareLegend(ADrawer, legendItems, FClipRect, legendRect);
|
PrepareLegend(ADrawer, legendItems, FClipRect, legendRect);
|
||||||
try
|
try
|
||||||
@ -734,21 +737,6 @@ begin
|
|||||||
DrawLineHoriz(ACanvas, FReticulePos.Y);
|
DrawLineHoriz(ACanvas, FReticulePos.Y);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TChart.DrawTitleFoot(ACanvas: TCanvas);
|
|
||||||
var
|
|
||||||
c: Integer;
|
|
||||||
pbf: TPenBrushFontRecall;
|
|
||||||
begin
|
|
||||||
pbf := TPenBrushFontRecall.Create(ACanvas, [pbfBrush, pbfFont]);
|
|
||||||
try
|
|
||||||
c := (FClipRect.Left + FClipRect.Right) div 2;
|
|
||||||
FTitle.Draw(ACanvas, 1, c, FClipRect.Top);
|
|
||||||
FFoot.Draw(ACanvas, -1, c, FClipRect.Bottom);
|
|
||||||
finally
|
|
||||||
pbf.Free;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChart.EraseBackground(DC: HDC);
|
procedure TChart.EraseBackground(DC: HDC);
|
||||||
begin
|
begin
|
||||||
// do not erase, since we will paint over it anyway
|
// do not erase, since we will paint over it anyway
|
||||||
|
|||||||
@ -204,7 +204,8 @@ end;
|
|||||||
|
|
||||||
procedure TLegendItem.Draw(ADrawer: IChartDrawer; const ARect: TRect);
|
procedure TLegendItem.Draw(ADrawer: IChartDrawer; const ARect: TRect);
|
||||||
begin
|
begin
|
||||||
ADrawer.TextOut(ARect.Right + SYMBOL_TEXT_SPACING, ARect.Top, FText);
|
ADrawer.TextOut.
|
||||||
|
Pos(ARect.Right + SYMBOL_TEXT_SPACING, ARect.Top).Text(FText).Done;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TLegendItemUserDrawn }
|
{ TLegendItemUserDrawn }
|
||||||
|
|||||||
@ -29,7 +29,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Graphics, Controls, FPCanvas, Types,
|
Classes, SysUtils, Graphics, Controls, FPCanvas, Types,
|
||||||
TAChartUtils;
|
TAChartUtils, TADrawUtils;
|
||||||
|
|
||||||
const
|
const
|
||||||
MARKS_MARGIN_X = 4;
|
MARKS_MARGIN_X = 4;
|
||||||
@ -103,8 +103,8 @@ type
|
|||||||
constructor Create(AOwner: TCustomChart);
|
constructor Create(AOwner: TCustomChart);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
public
|
public
|
||||||
procedure Assign(Source: TPersistent); override;
|
procedure Assign(ASource: TPersistent); override;
|
||||||
procedure Draw(ACanvas: TCanvas; ADir, AX: Integer; var AY: Integer);
|
procedure Draw(ADrawer: IChartDrawer; ADir, AX: Integer; var AY: Integer);
|
||||||
published
|
published
|
||||||
property Alignment: TAlignment
|
property Alignment: TAlignment
|
||||||
read FAlignment write SetAlignment default taCenter;
|
read FAlignment write SetAlignment default taCenter;
|
||||||
@ -311,7 +311,7 @@ type
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
TACustomSource, TADrawUtils;
|
TACustomSource;
|
||||||
|
|
||||||
{ TChartPen }
|
{ TChartPen }
|
||||||
|
|
||||||
@ -383,10 +383,10 @@ end;
|
|||||||
|
|
||||||
{ TChartTitle }
|
{ TChartTitle }
|
||||||
|
|
||||||
procedure TChartTitle.Assign(Source: TPersistent);
|
procedure TChartTitle.Assign(ASource: TPersistent);
|
||||||
begin
|
begin
|
||||||
if Source is TChartTitle then
|
if ASource is TChartTitle then
|
||||||
with TChartTitle(Source) do begin
|
with TChartTitle(ASource) do begin
|
||||||
Self.FAlignment := Alignment;
|
Self.FAlignment := Alignment;
|
||||||
Self.FBrush.Assign(Brush);
|
Self.FBrush.Assign(Brush);
|
||||||
Self.FFont.Assign(Font);
|
Self.FFont.Assign(Font);
|
||||||
@ -394,7 +394,7 @@ begin
|
|||||||
Self.FText.Assign(Text);
|
Self.FText.Assign(Text);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
inherited Assign(Source);
|
inherited Assign(ASource);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TChartTitle.Create(AOwner: TCustomChart);
|
constructor TChartTitle.Create(AOwner: TCustomChart);
|
||||||
@ -423,22 +423,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TChartTitle.Draw(
|
procedure TChartTitle.Draw(
|
||||||
ACanvas: TCanvas; ADir, AX: Integer; var AY: Integer);
|
ADrawer: IChartDrawer; ADir, AX: Integer; var AY: Integer);
|
||||||
var
|
var
|
||||||
ptSize, textOrigin: TPoint;
|
ptSize, textOrigin: TPoint;
|
||||||
a: Double;
|
a: Double;
|
||||||
w: Integer;
|
w: Integer;
|
||||||
begin
|
begin
|
||||||
if not Visible or (Text.Count = 0) then exit;
|
if not Visible or (Text.Count = 0) then exit;
|
||||||
ACanvas.Brush.Assign(Brush);
|
ADrawer.Brush := Brush;
|
||||||
ACanvas.Font.Assign(Font);
|
ADrawer.Font := Font;
|
||||||
a := -OrientToRad(Font.Orientation);
|
a := -OrientToRad(Font.Orientation);
|
||||||
ptSize := MultiLineTextExtent(ACanvas, Text);
|
ptSize := ADrawer.TextExtent(Text);
|
||||||
textOrigin := RotatePoint(-ptSize div 2, a);
|
textOrigin := RotatePoint(-ptSize div 2, a);
|
||||||
w := ptSize.X;
|
w := ptSize.X;
|
||||||
ptSize := MeasureRotatedRect(ptSize, a);
|
ptSize := MeasureRotatedRect(ptSize, a);
|
||||||
textOrigin += Point(AX, AY + ptSize.Y div 2 * ADir);
|
textOrigin += Point(AX, AY + ptSize.Y div 2 * ADir);
|
||||||
MultiLineTextOut(ACanvas, textOrigin, Text, Alignment, w);
|
ADrawer.TextOut.Pos(textOrigin).Text(Text).Alignment(Alignment).Width(w).Done;
|
||||||
AY += ADir * (ptSize.Y + Margin);
|
AY += ADir * (ptSize.Y + Margin);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -567,7 +567,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
ptText := RotatePoint(-ptText div 2, LabelAngle) + ALabelCenter;
|
ptText := RotatePoint(-ptText div 2, LabelAngle) + ALabelCenter;
|
||||||
MultiLineTextOut(ACanvas, ptText, AText);
|
MultiLineTextOut(ACanvas, ptText, AText, taLeftJustify, 0);
|
||||||
if wasClipping then
|
if wasClipping then
|
||||||
ACanvas.Clipping := true;
|
ACanvas.Clipping := true;
|
||||||
end;
|
end;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user