mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-21 20:48:17 +02:00
TAChart: Start implementation of IChartDrawer interface
git-svn-id: trunk@29519 -
This commit is contained in:
parent
09d05b6a3c
commit
2acf57df8d
@ -21,7 +21,10 @@ unit TADrawUtils;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, Graphics, SysUtils, Types;
|
||||
Classes, Graphics, FPCanvas, SysUtils, Types;
|
||||
|
||||
type
|
||||
TChartColor = -$7FFFFFFF-1..$7FFFFFFF;
|
||||
|
||||
const
|
||||
Colors: array [1..15] of TColor = (
|
||||
@ -29,6 +32,8 @@ const
|
||||
clTeal, clNavy, clMaroon, clLime, clOlive, clPurple, clSilver, clAqua);
|
||||
|
||||
type
|
||||
//TCanvas = TFPCustomCanvas;
|
||||
|
||||
TPenBrushFont = set of (pbfPen, pbfBrush, pbfFont);
|
||||
|
||||
{ TPenBrushFontRecall }
|
||||
@ -45,6 +50,35 @@ type
|
||||
procedure Recall;
|
||||
end;
|
||||
|
||||
IChartDrawer = interface
|
||||
function GetCanvas: TCanvas;
|
||||
procedure PrepareSimplePen(AColor: TChartColor);
|
||||
procedure Rectangle(const ARect: TRect);
|
||||
procedure SetBrush(APen: TFPCustomBrush);
|
||||
procedure SetBrushParams(AStyle: TBrushStyle; AColor: TChartColor);
|
||||
procedure SetPen(APen: TFPCustomPen);
|
||||
|
||||
property Brush: TFPCustomBrush write SetBrush;
|
||||
property Canvas: TCanvas read GetCanvas;
|
||||
property Pen: TFPCustomPen write SetPen;
|
||||
end;
|
||||
|
||||
{ TCanvasDrawer }
|
||||
|
||||
TCanvasDrawer = class(TInterfacedObject, IChartDrawer)
|
||||
private
|
||||
FCanvas: TCanvas;
|
||||
procedure SetBrush(ABrush: TFPCustomBrush);
|
||||
procedure SetPen(APen: TFPCustomPen);
|
||||
public
|
||||
constructor Create(ACanvas: TCanvas);
|
||||
function GetCanvas: TCanvas;
|
||||
|
||||
procedure PrepareSimplePen(AColor: TChartColor);
|
||||
procedure Rectangle(const ARect: TRect);
|
||||
procedure SetBrushParams(AStyle: TBrushStyle; AColor: TChartColor);
|
||||
end;
|
||||
|
||||
procedure DrawLineDepth(ACanvas: TCanvas; AX1, AY1, AX2, AY2, ADepth: Integer);
|
||||
procedure DrawLineDepth(ACanvas: TCanvas; const AP1, AP2: TPoint; ADepth: Integer);
|
||||
|
||||
@ -175,6 +209,45 @@ begin
|
||||
Result := ACanvas.TextHeight(TYPICAL_TEXT);
|
||||
end;
|
||||
|
||||
{ TCanvasDrawer }
|
||||
|
||||
constructor TCanvasDrawer.Create(ACanvas: TCanvas);
|
||||
begin
|
||||
FCanvas := ACanvas;
|
||||
end;
|
||||
|
||||
function TCanvasDrawer.GetCanvas: TCanvas;
|
||||
begin
|
||||
Result := FCanvas;
|
||||
end;
|
||||
|
||||
procedure TCanvasDrawer.PrepareSimplePen(AColor: TChartColor);
|
||||
begin
|
||||
TADrawUtils.PrepareSimplePen(FCanvas, AColor);
|
||||
end;
|
||||
|
||||
procedure TCanvasDrawer.Rectangle(const ARect: TRect);
|
||||
begin
|
||||
FCanvas.Rectangle(ARect);
|
||||
end;
|
||||
|
||||
procedure TCanvasDrawer.SetBrush(ABrush: TFPCustomBrush);
|
||||
begin
|
||||
FCanvas.Brush.Assign(ABrush);
|
||||
end;
|
||||
|
||||
procedure TCanvasDrawer.SetBrushParams(
|
||||
AStyle: TBrushStyle; AColor: TChartColor);
|
||||
begin
|
||||
FCanvas.Brush.Style := AStyle;
|
||||
FCanvas.Brush.Color := AColor;
|
||||
end;
|
||||
|
||||
procedure TCanvasDrawer.SetPen(APen: TFPCustomPen);
|
||||
begin
|
||||
FCanvas.Pen.Assign(APen);
|
||||
end;
|
||||
|
||||
{ TPenBrushFontRecall }
|
||||
|
||||
constructor TPenBrushFontRecall.Create(ACanvas: TCanvas; AParams: TPenBrushFont);
|
||||
|
@ -29,7 +29,7 @@ interface
|
||||
|
||||
uses
|
||||
Graphics, Classes, Controls, LCLType, SysUtils,
|
||||
TAChartAxis, TAChartUtils, TALegend, TATypes;
|
||||
TAChartAxis, TAChartUtils, TADrawUtils, TALegend, TATypes;
|
||||
|
||||
type
|
||||
TChart = class;
|
||||
@ -78,7 +78,8 @@ type
|
||||
destructor Destroy; override;
|
||||
|
||||
public
|
||||
procedure Draw(ACanvas: TCanvas); virtual; abstract;
|
||||
procedure Draw(ADrawer: IChartDrawer); virtual;
|
||||
procedure Draw(ACanvas: TCanvas); virtual;
|
||||
function IsEmpty: Boolean; virtual; abstract;
|
||||
procedure MovePoint(var AIndex: Integer; const ANewPos: TPoint); virtual;
|
||||
|
||||
@ -214,8 +215,8 @@ type
|
||||
procedure VisitSources(
|
||||
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData);
|
||||
protected
|
||||
procedure Clear(ACanvas: TCanvas; const ARect: TRect);
|
||||
procedure DisplaySeries(ACanvas: TCanvas);
|
||||
procedure Clear(ADrawer: IChartDrawer; const ARect: TRect);
|
||||
procedure DisplaySeries(ADrawer: IChartDrawer);
|
||||
procedure DrawBackWall(ACanvas: TCanvas);
|
||||
procedure DrawTitleFoot(ACanvas: TCanvas);
|
||||
procedure MouseDown(
|
||||
@ -251,6 +252,7 @@ type
|
||||
function Clone: TChart;
|
||||
procedure CopyToClipboardBitmap;
|
||||
procedure DeleteSeries(ASeries: TBasicChartSeries);
|
||||
procedure Draw(ADrawer: IChartDrawer; const ARect: TRect);
|
||||
procedure DrawLegendOn(ACanvas: TCanvas; var ARect: TRect);
|
||||
function GetFullExtent: TDoubleRect;
|
||||
procedure PaintOnCanvas(ACanvas: TCanvas; ARect: TRect);
|
||||
@ -354,7 +356,7 @@ var
|
||||
implementation
|
||||
|
||||
uses
|
||||
Clipbrd, Dialogs, GraphMath, LCLProc, LResources, Math, TADrawUtils, Types;
|
||||
Clipbrd, Dialogs, GraphMath, LCLProc, LResources, Math, Types;
|
||||
|
||||
function CompareZPosition(AItem1, AItem2: Pointer): Integer;
|
||||
begin
|
||||
@ -539,41 +541,10 @@ end;
|
||||
|
||||
procedure TChart.PaintOnCanvas(ACanvas: TCanvas; ARect: TRect);
|
||||
var
|
||||
i: Integer;
|
||||
legendItems: TChartLegendItems = nil;
|
||||
legendRect: TRect;
|
||||
drawer: IChartDrawer;
|
||||
begin
|
||||
Clear(ACanvas, ARect);
|
||||
|
||||
FClipRect := ARect;
|
||||
InflateRect(FClipRect, -2, -2);
|
||||
|
||||
for i := 0 to AxisList.Count - 1 do
|
||||
with AxisList[i] do
|
||||
if Transformations <> nil then
|
||||
Transformations.SetChart(Self);
|
||||
for i := 0 to SeriesCount - 1 do
|
||||
Series[i].BeforeDraw;
|
||||
|
||||
if not FIsZoomed then
|
||||
FLogicalExtent := GetFullExtent;
|
||||
FCurrentExtent := FLogicalExtent;
|
||||
DrawTitleFoot(ACanvas);
|
||||
if Legend.Visible then
|
||||
PrepareLegend(ACanvas, legendItems, FClipRect, legendRect);
|
||||
try
|
||||
PrepareAxis(ACanvas);
|
||||
DrawBackWall(ACanvas);
|
||||
DisplaySeries(ACanvas);
|
||||
if Legend.Visible then
|
||||
Legend.Draw(ACanvas, legendItems, legendRect);
|
||||
finally
|
||||
legendItems.Free;
|
||||
end;
|
||||
DrawReticule(ACanvas);
|
||||
|
||||
for i := 0 to SeriesCount - 1 do
|
||||
Series[i].AfterDraw;
|
||||
drawer := TCanvasDrawer.Create(ACanvas);
|
||||
Draw(drawer, ARect);
|
||||
end;
|
||||
|
||||
procedure TChart.PrepareLegend(
|
||||
@ -652,19 +623,18 @@ begin
|
||||
rY.UpdateMinMax(@YImageToGraph);
|
||||
end;
|
||||
|
||||
procedure TChart.Clear(ACanvas: TCanvas; const ARect: TRect);
|
||||
procedure TChart.Clear(ADrawer: IChartDrawer; const ARect: TRect);
|
||||
var
|
||||
defaultDrawing: Boolean = true;
|
||||
begin
|
||||
PrepareSimplePen(ACanvas, Color);
|
||||
ACanvas.Brush.Color := Color;
|
||||
ACanvas.Brush.Style := bsSolid;
|
||||
if Assigned(OnBeforeDrawBackground) then
|
||||
OnBeforeDrawBackground(Self, ACanvas, ARect, defaultDrawing);
|
||||
ADrawer.PrepareSimplePen(Color);
|
||||
ADrawer.SetBrushParams(bsSolid, Color);
|
||||
if (ADrawer.Canvas <> nil) and Assigned(OnBeforeDrawBackground) then
|
||||
OnBeforeDrawBackground(Self, ADrawer.Canvas, ARect, defaultDrawing);
|
||||
if defaultDrawing then
|
||||
ACanvas.Rectangle(ARect);
|
||||
if Assigned(OnAfterDrawBackground) then
|
||||
OnAfterDrawBackground(Self, ACanvas, ARect);
|
||||
ADrawer.Rectangle(ARect);
|
||||
if (ADrawer.Canvas <> nil) and Assigned(OnAfterDrawBackground) then
|
||||
OnAfterDrawBackground(Self, ADrawer.Canvas, ARect);
|
||||
end;
|
||||
|
||||
procedure TChart.ClearSeries;
|
||||
@ -901,7 +871,7 @@ begin
|
||||
PaintOnCanvas(ACanvas, Rect);
|
||||
end;
|
||||
|
||||
procedure TChart.DisplaySeries(ACanvas: TCanvas);
|
||||
procedure TChart.DisplaySeries(ADrawer: IChartDrawer);
|
||||
|
||||
procedure OffsetDrawArea(AZPos, ADepth: Integer);
|
||||
begin
|
||||
@ -928,27 +898,66 @@ begin
|
||||
with TBasicChartSeries(seriesInZOrder[i]) do begin
|
||||
if not Active then continue;
|
||||
// Interleave axises with series according to ZPosition.
|
||||
AxisList.Draw(ACanvas, FClipRect, Self, ZPosition, d, axisIndex);
|
||||
AxisList.Draw(ADrawer.Canvas, FClipRect, Self, ZPosition, d, axisIndex);
|
||||
OffsetDrawArea(Min(ZPosition, d), Min(Depth, d));
|
||||
ACanvas.ClipRect := FClipRect;
|
||||
ACanvas.Clipping := true;
|
||||
ADrawer.Canvas.ClipRect := FClipRect;
|
||||
ADrawer.Canvas.Clipping := true;
|
||||
try
|
||||
try
|
||||
Draw(ACanvas);
|
||||
Draw(ADrawer);
|
||||
except
|
||||
Active := false;
|
||||
raise;
|
||||
end;
|
||||
finally
|
||||
OffsetDrawArea(-Min(ZPosition, d), -Min(Depth, d));
|
||||
ACanvas.Clipping := false;
|
||||
ADrawer.Canvas.Clipping := false;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
seriesInZOrder.Free;
|
||||
end;
|
||||
end;
|
||||
AxisList.Draw(ACanvas, FClipRect, Self, MaxInt, d, axisIndex);
|
||||
AxisList.Draw(ADrawer.Canvas, FClipRect, Self, MaxInt, d, axisIndex);
|
||||
end;
|
||||
|
||||
procedure TChart.Draw(ADrawer: IChartDrawer; const ARect: TRect);
|
||||
var
|
||||
i: Integer;
|
||||
legendItems: TChartLegendItems = nil;
|
||||
legendRect: TRect;
|
||||
begin
|
||||
Clear(ADrawer, ARect);
|
||||
|
||||
FClipRect := ARect;
|
||||
InflateRect(FClipRect, -2, -2);
|
||||
|
||||
for i := 0 to AxisList.Count - 1 do
|
||||
with AxisList[i] do
|
||||
if Transformations <> nil then
|
||||
Transformations.SetChart(Self);
|
||||
for i := 0 to SeriesCount - 1 do
|
||||
Series[i].BeforeDraw;
|
||||
|
||||
if not FIsZoomed then
|
||||
FLogicalExtent := GetFullExtent;
|
||||
FCurrentExtent := FLogicalExtent;
|
||||
DrawTitleFoot(ADrawer.Canvas);
|
||||
if Legend.Visible then
|
||||
PrepareLegend(ADrawer.Canvas, legendItems, FClipRect, legendRect);
|
||||
try
|
||||
PrepareAxis(ADrawer.Canvas);
|
||||
DrawBackWall(ADrawer.Canvas);
|
||||
DisplaySeries(ADrawer);
|
||||
if Legend.Visible then
|
||||
Legend.Draw(ADrawer.Canvas, legendItems, legendRect);
|
||||
finally
|
||||
legendItems.Free;
|
||||
end;
|
||||
DrawReticule(ADrawer.Canvas);
|
||||
|
||||
for i := 0 to SeriesCount - 1 do
|
||||
Series[i].AfterDraw;
|
||||
end;
|
||||
|
||||
procedure TChart.DrawReticule(ACanvas: TCanvas);
|
||||
@ -1260,6 +1269,17 @@ begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TBasicChartSeries.Draw(ADrawer: IChartDrawer);
|
||||
begin
|
||||
Draw(ADrawer.Canvas);
|
||||
end;
|
||||
|
||||
procedure TBasicChartSeries.Draw(ACanvas: TCanvas);
|
||||
begin
|
||||
Unused(ACanvas);
|
||||
raise EChartError(ClassName + '.Draw not implemented');
|
||||
end;
|
||||
|
||||
function TBasicChartSeries.GraphToAxisX(AX: Double): Double;
|
||||
begin
|
||||
Result := AX;
|
||||
|
Loading…
Reference in New Issue
Block a user