mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-24 15:40:06 +02:00
TAChart: Extract TATextElements unit
git-svn-id: trunk@38564 -
This commit is contained in:
parent
d682696b86
commit
fa8507e364
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -3059,6 +3059,7 @@ components/tachart/taradialseries.pas svneol=native#text/pascal
|
|||||||
components/tachart/taseries.pas svneol=native#text/plain
|
components/tachart/taseries.pas svneol=native#text/plain
|
||||||
components/tachart/tasources.pas svneol=native#text/pascal
|
components/tachart/tasources.pas svneol=native#text/pascal
|
||||||
components/tachart/tastyles.pas svneol=native#text/pascal
|
components/tachart/tastyles.pas svneol=native#text/pascal
|
||||||
|
components/tachart/tatextelements.pas svneol=native#text/pascal
|
||||||
components/tachart/tatools.pas svneol=native#text/pascal
|
components/tachart/tatools.pas svneol=native#text/pascal
|
||||||
components/tachart/tatransformations.pas svneol=native#text/pascal
|
components/tachart/tatransformations.pas svneol=native#text/pascal
|
||||||
components/tachart/tatypes.pas svneol=native#text/plain
|
components/tachart/tatypes.pas svneol=native#text/plain
|
||||||
|
@ -45,7 +45,7 @@ implementation
|
|||||||
{$R *.lfm}
|
{$R *.lfm}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
TATypes;
|
TATextElements;
|
||||||
|
|
||||||
{ TForm1 }
|
{ TForm1 }
|
||||||
|
|
||||||
|
@ -7,8 +7,7 @@ uses
|
|||||||
cthreads,
|
cthreads,
|
||||||
{$ENDIF}{$ENDIF}
|
{$ENDIF}{$ENDIF}
|
||||||
Interfaces, // this includes the LCL widgetset
|
Interfaces, // this includes the LCL widgetset
|
||||||
Forms, tachartlazaruspkg, Main
|
Forms, tachartlazaruspkg, Main;
|
||||||
{ you can add units after this };
|
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, Graphics,
|
Classes, Graphics,
|
||||||
TAChartUtils, TACustomSource, TADrawUtils, TAIntervalSources, TAStyles,
|
TAChartUtils, TACustomSource, TADrawUtils, TAIntervalSources, TAStyles,
|
||||||
TATypes;
|
TATypes, TATextElements;
|
||||||
|
|
||||||
const
|
const
|
||||||
DEF_TITLE_DISTANCE = 4;
|
DEF_TITLE_DISTANCE = 4;
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
for details about the copyright.
|
for details about the copyright.
|
||||||
"/>
|
"/>
|
||||||
<Version Major="1"/>
|
<Version Major="1"/>
|
||||||
<Files Count="39">
|
<Files Count="40">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="tagraph.pas"/>
|
<Filename Value="tagraph.pas"/>
|
||||||
<HasRegisterProc Value="True"/>
|
<HasRegisterProc Value="True"/>
|
||||||
@ -209,6 +209,10 @@
|
|||||||
<Filename Value="taanimatedsource.pas"/>
|
<Filename Value="taanimatedsource.pas"/>
|
||||||
<UnitName Value="TAAnimatedSource"/>
|
<UnitName Value="TAAnimatedSource"/>
|
||||||
</Item39>
|
</Item39>
|
||||||
|
<Item40>
|
||||||
|
<Filename Value="tatextelements.pas"/>
|
||||||
|
<UnitName Value="TATextElements"/>
|
||||||
|
</Item40>
|
||||||
</Files>
|
</Files>
|
||||||
<LazDoc Paths="$(LazarusDir)\components\tachart\fpdoc"/>
|
<LazDoc Paths="$(LazarusDir)\components\tachart\fpdoc"/>
|
||||||
<Type Value="RunAndDesignTime"/>
|
<Type Value="RunAndDesignTime"/>
|
||||||
|
@ -14,7 +14,7 @@ uses
|
|||||||
TADrawerCanvas, TADrawerSVG, TAIntervalSources, TAChartAxisUtils,
|
TADrawerCanvas, TADrawerSVG, TAIntervalSources, TAChartAxisUtils,
|
||||||
TAChartListbox, TAEnumerators, TADataPointsEditor, TAChartExtentLink,
|
TAChartListbox, TAEnumerators, TADataPointsEditor, TAChartExtentLink,
|
||||||
TAToolEditors, TAMath, TAChartImageList, TADataTools, TAAnimatedSource,
|
TAToolEditors, TAMath, TAChartImageList, TADataTools, TAAnimatedSource,
|
||||||
LazarusPackageIntf;
|
TATextElements, LazarusPackageIntf;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, Graphics, SysUtils,
|
Classes, Graphics, SysUtils,
|
||||||
TAChartAxis, TAChartUtils, TACustomSource, TADrawUtils, TAGraph, TALegend,
|
TAChartAxis, TAChartUtils, TACustomSource, TADrawUtils, TAGraph, TALegend,
|
||||||
TASources, TAStyles, TATypes;
|
TASources, TAStyles, TATextElements, TATypes;
|
||||||
|
|
||||||
const
|
const
|
||||||
DEF_AXIS_INDEX = -1;
|
DEF_AXIS_INDEX = -1;
|
||||||
|
@ -22,7 +22,7 @@ unit TADataTools;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, TAChartUtils, TAGraph, TATools, TATypes;
|
Classes, TAChartUtils, TAGraph, TATools, TATextElements, TATypes;
|
||||||
|
|
||||||
type
|
type
|
||||||
TDataPointDistanceTool = class;
|
TDataPointDistanceTool = class;
|
||||||
|
@ -29,7 +29,8 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Graphics, Classes, Controls, LCLType, SysUtils,
|
Graphics, Classes, Controls, LCLType, SysUtils,
|
||||||
TAChartAxis, TAChartAxisUtils, TAChartUtils, TADrawUtils, TALegend, TATypes;
|
TAChartAxis, TAChartAxisUtils, TAChartUtils, TADrawUtils, TALegend,
|
||||||
|
TATextElements, TATypes;
|
||||||
|
|
||||||
type
|
type
|
||||||
TChart = class;
|
TChart = class;
|
||||||
|
723
components/tachart/tatextelements.pas
Normal file
723
components/tachart/tatextelements.pas
Normal file
@ -0,0 +1,723 @@
|
|||||||
|
{
|
||||||
|
|
||||||
|
*****************************************************************************
|
||||||
|
* *
|
||||||
|
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
||||||
|
* for details about the copyright. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* *
|
||||||
|
*****************************************************************************
|
||||||
|
|
||||||
|
Authors: Alexander Klenin
|
||||||
|
|
||||||
|
}
|
||||||
|
unit TATextElements;
|
||||||
|
|
||||||
|
{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, Graphics, Types,
|
||||||
|
TAChartUtils, TADrawUtils, TATypes;
|
||||||
|
|
||||||
|
const
|
||||||
|
MARKS_MARGIN_X = 4;
|
||||||
|
MARKS_MARGIN_Y = 2;
|
||||||
|
|
||||||
|
type
|
||||||
|
TChartMarksOverlapPolicy = (opIgnore, opHideNeighbour);
|
||||||
|
|
||||||
|
TChartTextElement = class(TChartElement)
|
||||||
|
strict private
|
||||||
|
FClipped: Boolean;
|
||||||
|
FOverlapPolicy: TChartMarksOverlapPolicy;
|
||||||
|
procedure SetAlignment(AValue: TAlignment);
|
||||||
|
procedure SetClipped(AValue: Boolean);
|
||||||
|
procedure SetOverlapPolicy(AValue: TChartMarksOverlapPolicy);
|
||||||
|
strict protected
|
||||||
|
FAlignment: TAlignment;
|
||||||
|
procedure AddMargins(ADrawer: IChartDrawer; var ASize: TPoint);
|
||||||
|
procedure ApplyLabelFont(ADrawer: IChartDrawer); virtual;
|
||||||
|
procedure DrawLink(
|
||||||
|
ADrawer: IChartDrawer; ADataPoint, ALabelCenter: TPoint); virtual;
|
||||||
|
function IsMarginRequired: Boolean;
|
||||||
|
strict protected
|
||||||
|
function GetFrame: TChartPen; virtual; abstract;
|
||||||
|
function GetLabelAngle: Double; virtual;
|
||||||
|
function GetLabelBrush: TBrush; virtual; abstract;
|
||||||
|
function GetLabelFont: TFont; virtual; abstract;
|
||||||
|
function GetLinkPen: TChartPen; virtual;
|
||||||
|
public
|
||||||
|
constructor Create(AOwner: TCustomChart);
|
||||||
|
public
|
||||||
|
procedure Assign(ASource: TPersistent); override;
|
||||||
|
procedure DrawLabel(
|
||||||
|
ADrawer: IChartDrawer; const ADataPoint, ALabelCenter: TPoint;
|
||||||
|
const AText: String; var APrevLabelPoly: TPointArray);
|
||||||
|
function GetLabelPolygon(
|
||||||
|
ADrawer: IChartDrawer; ASize: TPoint): TPointArray; virtual;
|
||||||
|
function MeasureLabel(ADrawer: IChartDrawer; const AText: String): TSize;
|
||||||
|
public
|
||||||
|
// If false, labels may overlap axises and legend.
|
||||||
|
property Clipped: Boolean read FClipped write SetClipped default true;
|
||||||
|
property OverlapPolicy: TChartMarksOverlapPolicy
|
||||||
|
read FOverlapPolicy write SetOverlapPolicy default opIgnore;
|
||||||
|
published
|
||||||
|
property Alignment: TAlignment
|
||||||
|
read FAlignment write SetAlignment;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TChartTitleFramePen = class(TChartPen)
|
||||||
|
published
|
||||||
|
property Visible default false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TChartTitle }
|
||||||
|
|
||||||
|
TChartTitle = class(TChartTextElement)
|
||||||
|
strict private
|
||||||
|
FBrush: TBrush;
|
||||||
|
FFont: TFont;
|
||||||
|
FFrame: TChartTitleFramePen;
|
||||||
|
FMargin: TChartDistance;
|
||||||
|
FText: TStrings;
|
||||||
|
|
||||||
|
procedure SetBrush(AValue: TBrush);
|
||||||
|
procedure SetFont(AValue: TFont);
|
||||||
|
procedure SetFrame(AValue: TChartTitleFramePen);
|
||||||
|
procedure SetMargin(AValue: TChartDistance);
|
||||||
|
procedure SetText(AValue: TStrings);
|
||||||
|
strict protected
|
||||||
|
function GetFrame: TChartPen; override;
|
||||||
|
function GetLabelBrush: TBrush; override;
|
||||||
|
function GetLabelFont: TFont; override;
|
||||||
|
public
|
||||||
|
constructor Create(AOwner: TCustomChart);
|
||||||
|
destructor Destroy; override;
|
||||||
|
public
|
||||||
|
procedure Assign(ASource: TPersistent); override;
|
||||||
|
procedure Draw(
|
||||||
|
ADrawer: IChartDrawer; ADir, ALeft, ARight: Integer; var AY: Integer);
|
||||||
|
published
|
||||||
|
property Alignment default taCenter;
|
||||||
|
property Brush: TBrush read FBrush write SetBrush;
|
||||||
|
property Font: TFont read FFont write SetFont;
|
||||||
|
property Frame: TChartTitleFramePen read FFrame write SetFrame;
|
||||||
|
property Margin: TChartDistance
|
||||||
|
read FMargin write SetMargin default DEF_MARGIN;
|
||||||
|
property Text: TStrings read FText write SetText;
|
||||||
|
property Visible default false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TChartMarkAttachment = (maDefault, maEdge, maCenter);
|
||||||
|
TChartMarkLabelShape = (cmsRectangle, cmsEllipse);
|
||||||
|
|
||||||
|
{ TGenericChartMarks }
|
||||||
|
|
||||||
|
{$IFNDEF fpdoc} // Workaround for issue #18549.
|
||||||
|
generic TGenericChartMarks<_TLabelBrush, _TLinkPen, _TFramePen> =
|
||||||
|
class(TChartTextElement)
|
||||||
|
{$ELSE}
|
||||||
|
TGenericChartMarks = class(TChartTextElement)
|
||||||
|
{$ENDIF}
|
||||||
|
strict private
|
||||||
|
FAdditionalAngle: Double;
|
||||||
|
FArrow: TChartArrow;
|
||||||
|
FAttachment: TChartMarkAttachment;
|
||||||
|
FFrame: _TFramePen;
|
||||||
|
FShape: TChartMarkLabelShape;
|
||||||
|
FYIndex: Integer;
|
||||||
|
function GetDistanceToCenter: Boolean;
|
||||||
|
procedure SetArrow(AValue: TChartArrow);
|
||||||
|
procedure SetAttachment(AValue: TChartMarkAttachment);
|
||||||
|
procedure SetDistance(AValue: TChartDistance);
|
||||||
|
procedure SetDistanceToCenter(AValue: Boolean);
|
||||||
|
procedure SetFormat(AValue: String);
|
||||||
|
procedure SetFrame(AValue: _TFramePen);
|
||||||
|
procedure SetLabelBrush(AValue: _TLabelBrush);
|
||||||
|
procedure SetLabelFont(AValue: TFont);
|
||||||
|
procedure SetLinkPen(AValue: _TLinkPen);
|
||||||
|
procedure SetShape(AValue: TChartMarkLabelShape);
|
||||||
|
procedure SetStyle(AValue: TSeriesMarksStyle);
|
||||||
|
procedure SetYIndex(AValue: Integer);
|
||||||
|
strict protected
|
||||||
|
FDistance: TChartDistance;
|
||||||
|
FFormat: String;
|
||||||
|
FLabelBrush: _TLabelBrush;
|
||||||
|
FLabelFont: TFont;
|
||||||
|
FLinkPen: _TLinkPen;
|
||||||
|
FStyle: TSeriesMarksStyle;
|
||||||
|
strict protected
|
||||||
|
procedure ApplyLabelFont(ADrawer: IChartDrawer); override;
|
||||||
|
procedure DrawLink(
|
||||||
|
ADrawer: IChartDrawer; ADataPoint, ALabelCenter: TPoint); override;
|
||||||
|
function GetFrame: TChartPen; override;
|
||||||
|
function GetLabelAngle: Double; override;
|
||||||
|
function GetLabelBrush: TBrush; override;
|
||||||
|
function GetLabelFont: TFont; override;
|
||||||
|
function GetLinkPen: TChartPen; override;
|
||||||
|
public
|
||||||
|
constructor Create(AOwner: TCustomChart);
|
||||||
|
destructor Destroy; override;
|
||||||
|
public
|
||||||
|
procedure Assign(ASource: TPersistent); override;
|
||||||
|
function CenterOffset(ADrawer: IChartDrawer; const AText: String): TSize;
|
||||||
|
function GetLabelPolygon(
|
||||||
|
ADrawer: IChartDrawer; ASize: TPoint): TPointArray; override;
|
||||||
|
function IsMarkLabelsVisible: Boolean;
|
||||||
|
procedure SetAdditionalAngle(AAngle: Double);
|
||||||
|
public
|
||||||
|
property Arrow: TChartArrow read FArrow write SetArrow;
|
||||||
|
property DistanceToCenter: Boolean
|
||||||
|
read GetDistanceToCenter write SetDistanceToCenter
|
||||||
|
stored false default false;
|
||||||
|
property Format: String read FFormat write SetFormat;
|
||||||
|
property Frame: _TFramePen read FFrame write SetFrame;
|
||||||
|
property LabelBrush: _TLabelBrush read FLabelBrush write SetLabelBrush;
|
||||||
|
property LinkPen: _TLinkPen read FLinkPen write SetLinkPen;
|
||||||
|
property Style: TSeriesMarksStyle read FStyle write SetStyle;
|
||||||
|
property YIndex: Integer read FYIndex write SetYIndex default 0;
|
||||||
|
published
|
||||||
|
property Alignment default taLeftJustify;
|
||||||
|
property Attachment: TChartMarkAttachment
|
||||||
|
read FAttachment write SetAttachment default maDefault;
|
||||||
|
// Distance between labelled object and label.
|
||||||
|
property Clipped;
|
||||||
|
property Distance: TChartDistance read FDistance write SetDistance;
|
||||||
|
property LabelFont: TFont read FLabelFont write SetLabelFont;
|
||||||
|
property Shape: TChartMarkLabelShape
|
||||||
|
read FShape write SetShape default cmsRectangle;
|
||||||
|
property Visible default true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TChartLinkPen = class(TChartPen)
|
||||||
|
published
|
||||||
|
property Color default clWhite;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TChartLabelBrush = class(TBrush)
|
||||||
|
published
|
||||||
|
property Color default clYellow;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$IFNDEF fpdoc} // Workaround for issue #18549.
|
||||||
|
TCustomChartMarks =
|
||||||
|
specialize TGenericChartMarks<TChartLabelBrush, TChartLinkPen, TChartPen>;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
{ TChartMarks }
|
||||||
|
|
||||||
|
TChartMarks = class(TCustomChartMarks)
|
||||||
|
public
|
||||||
|
procedure Assign(Source: TPersistent); override;
|
||||||
|
constructor Create(AOwner: TCustomChart);
|
||||||
|
published
|
||||||
|
property Arrow;
|
||||||
|
property Distance default DEF_MARKS_DISTANCE;
|
||||||
|
property Format;
|
||||||
|
property Frame;
|
||||||
|
property LabelBrush;
|
||||||
|
property LinkPen;
|
||||||
|
property OverlapPolicy;
|
||||||
|
property Style default smsNone;
|
||||||
|
property YIndex;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
GraphMath, Math, SysUtils,
|
||||||
|
TACustomSource, TAGeometry;
|
||||||
|
|
||||||
|
{ TChartTextElement }
|
||||||
|
|
||||||
|
procedure TChartTextElement.AddMargins(
|
||||||
|
ADrawer: IChartDrawer; var ASize: TPoint);
|
||||||
|
begin
|
||||||
|
if not IsMarginRequired then exit;
|
||||||
|
with ADrawer do
|
||||||
|
ASize += Point(Scale(MARKS_MARGIN_X), Scale(MARKS_MARGIN_Y)) * 2;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTextElement.ApplyLabelFont(ADrawer: IChartDrawer);
|
||||||
|
begin
|
||||||
|
ADrawer.Font := GetLabelFont;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTextElement.Assign(ASource: TPersistent);
|
||||||
|
begin
|
||||||
|
if ASource is TChartTextElement then
|
||||||
|
with TChartTextElement(ASource) do begin
|
||||||
|
Self.FAlignment := Alignment;
|
||||||
|
Self.FClipped := FClipped;
|
||||||
|
Self.FOverlapPolicy := FOverlapPolicy;
|
||||||
|
end;
|
||||||
|
inherited Assign(ASource);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TChartTextElement.Create(AOwner: TCustomChart);
|
||||||
|
begin
|
||||||
|
inherited Create(AOwner);
|
||||||
|
FClipped := true;
|
||||||
|
FOverlapPolicy := opIgnore;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTextElement.DrawLabel(
|
||||||
|
ADrawer: IChartDrawer; const ADataPoint, ALabelCenter: TPoint;
|
||||||
|
const AText: String; var APrevLabelPoly: TPointArray);
|
||||||
|
var
|
||||||
|
labelPoly: TPointArray;
|
||||||
|
ptText: TPoint;
|
||||||
|
i, w: Integer;
|
||||||
|
begin
|
||||||
|
ApplyLabelFont(ADrawer);
|
||||||
|
ptText := ADrawer.TextExtent(AText);
|
||||||
|
w := ptText.X;
|
||||||
|
labelPoly := GetLabelPolygon(ADrawer, ptText);
|
||||||
|
for i := 0 to High(labelPoly) do
|
||||||
|
labelPoly[i] += ALabelCenter;
|
||||||
|
|
||||||
|
if
|
||||||
|
(OverlapPolicy = opHideNeighbour) and
|
||||||
|
IsPolygonIntersectsPolygon(APrevLabelPoly, labelPoly)
|
||||||
|
then
|
||||||
|
exit;
|
||||||
|
APrevLabelPoly := labelPoly;
|
||||||
|
|
||||||
|
if not Clipped then
|
||||||
|
ADrawer.ClippingStop;
|
||||||
|
|
||||||
|
DrawLink(ADrawer, ADataPoint, ALabelCenter);
|
||||||
|
ADrawer.Brush := GetLabelBrush;
|
||||||
|
if IsMarginRequired then begin
|
||||||
|
if GetFrame.Visible then
|
||||||
|
ADrawer.Pen := GetFrame
|
||||||
|
else
|
||||||
|
ADrawer.SetPenParams(psClear, clTAColor);
|
||||||
|
ADrawer.Polygon(labelPoly, 0, Length(labelPoly));
|
||||||
|
end;
|
||||||
|
|
||||||
|
ptText := RotatePoint(-ptText div 2, GetLabelAngle) + ALabelCenter;
|
||||||
|
ADrawer.TextOut.Pos(ptText).Alignment(Alignment).Width(w).Text(AText).Done;
|
||||||
|
if not Clipped then
|
||||||
|
ADrawer.ClippingStart;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTextElement.DrawLink(
|
||||||
|
ADrawer: IChartDrawer; ADataPoint, ALabelCenter: TPoint);
|
||||||
|
var
|
||||||
|
p: TChartPen;
|
||||||
|
begin
|
||||||
|
if ADataPoint = ALabelCenter then exit;
|
||||||
|
p := GetLinkPen;
|
||||||
|
if p.Visible then begin
|
||||||
|
ADrawer.Pen := p;
|
||||||
|
ADrawer.Line(ADataPoint, ALabelCenter);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTextElement.GetLabelAngle: Double;
|
||||||
|
begin
|
||||||
|
// Negate to take into account top-down Y axis.
|
||||||
|
Result := -OrientToRad(GetLabelFont.Orientation);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTextElement.GetLabelPolygon(
|
||||||
|
ADrawer: IChartDrawer; ASize: TPoint): TPointArray;
|
||||||
|
begin
|
||||||
|
AddMargins(ADrawer, ASize);
|
||||||
|
Result := RotateRect(ASize, GetLabelAngle);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTextElement.GetLinkPen: TChartPen;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTextElement.IsMarginRequired: Boolean;
|
||||||
|
begin
|
||||||
|
with GetFrame do
|
||||||
|
Result := (GetLabelBrush.Style <> bsClear) or (Style <> psClear) and Visible;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTextElement.MeasureLabel(
|
||||||
|
ADrawer: IChartDrawer; const AText: String): TSize;
|
||||||
|
var
|
||||||
|
sz: TPoint;
|
||||||
|
begin
|
||||||
|
ApplyLabelFont(ADrawer);
|
||||||
|
sz := ADrawer.TextExtent(AText);
|
||||||
|
AddMargins(ADrawer, sz);
|
||||||
|
Result := MeasureRotatedRect(sz, GetLabelAngle);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTextElement.SetAlignment(AValue: TAlignment);
|
||||||
|
begin
|
||||||
|
if FAlignment = AValue then exit;
|
||||||
|
FAlignment := AValue;
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTextElement.SetClipped(AValue: Boolean);
|
||||||
|
begin
|
||||||
|
if FClipped = AValue then exit;
|
||||||
|
FClipped := AValue;
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTextElement.SetOverlapPolicy(AValue: TChartMarksOverlapPolicy);
|
||||||
|
begin
|
||||||
|
if FOverlapPolicy = AValue then exit;
|
||||||
|
FOverlapPolicy := AValue;
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TChartTitle }
|
||||||
|
|
||||||
|
procedure TChartTitle.Assign(ASource: TPersistent);
|
||||||
|
begin
|
||||||
|
if ASource is TChartTitle then
|
||||||
|
with TChartTitle(ASource) do begin
|
||||||
|
Self.FBrush.Assign(Brush);
|
||||||
|
Self.FFont.Assign(Font);
|
||||||
|
Self.FFrame.Assign(Frame);
|
||||||
|
Self.FText.Assign(Text);
|
||||||
|
end;
|
||||||
|
|
||||||
|
inherited Assign(ASource);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TChartTitle.Create(AOwner: TCustomChart);
|
||||||
|
begin
|
||||||
|
inherited Create(AOwner);
|
||||||
|
|
||||||
|
FAlignment := taCenter;
|
||||||
|
InitHelper(FBrush, TBrush);
|
||||||
|
FBrush.Color := FOwner.Color;
|
||||||
|
InitHelper(FFont, TFont);
|
||||||
|
FFont.Color := clBlue;
|
||||||
|
InitHelper(FFrame, TChartTitleFramePen);
|
||||||
|
FMargin := DEF_MARGIN;
|
||||||
|
FText := TStringList.Create;
|
||||||
|
TStringList(FText).OnChange := @StyleChanged;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TChartTitle.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FBrush);
|
||||||
|
FreeAndNil(FFont);
|
||||||
|
FreeAndNil(FFrame);
|
||||||
|
FreeAndNil(FText);
|
||||||
|
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTitle.Draw(
|
||||||
|
ADrawer: IChartDrawer; ADir, ALeft, ARight: Integer; var AY: Integer);
|
||||||
|
var
|
||||||
|
p, ptSize: TPoint;
|
||||||
|
dummy: TPointArray = nil;
|
||||||
|
begin
|
||||||
|
if not Visible or (Text.Count = 0) then exit;
|
||||||
|
ptSize := MeasureLabel(ADrawer, Text.Text);
|
||||||
|
case Alignment of
|
||||||
|
taLeftJustify: p.X := ALeft + ptSize.X div 2;
|
||||||
|
taRightJustify: p.X := ARight - ptSize.X div 2;
|
||||||
|
taCenter: p.X := (ALeft + ARight) div 2;
|
||||||
|
end;
|
||||||
|
p.Y := AY + ADir * ptSize.Y div 2;
|
||||||
|
DrawLabel(ADrawer, p, p, Text.Text, dummy);
|
||||||
|
AY += ADir * (ptSize.Y + Margin);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTitle.GetFrame: TChartPen;
|
||||||
|
begin
|
||||||
|
Result := Frame;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTitle.GetLabelBrush: TBrush;
|
||||||
|
begin
|
||||||
|
Result := Brush;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartTitle.GetLabelFont: TFont;
|
||||||
|
begin
|
||||||
|
Result := Font;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTitle.SetBrush(AValue: TBrush);
|
||||||
|
begin
|
||||||
|
FBrush.Assign(AValue);
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTitle.SetFont(AValue: TFont);
|
||||||
|
begin
|
||||||
|
FFont.Assign(AValue);
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTitle.SetFrame(AValue: TChartTitleFramePen);
|
||||||
|
begin
|
||||||
|
FFrame.Assign(AValue);
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTitle.SetMargin(AValue: TChartDistance);
|
||||||
|
begin
|
||||||
|
if FMargin = AValue then exit;
|
||||||
|
FMargin := AValue;
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChartTitle.SetText(AValue: TStrings);
|
||||||
|
begin
|
||||||
|
FText.Assign(AValue);
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TGenericChartMarks }
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.ApplyLabelFont(ADrawer: IChartDrawer);
|
||||||
|
begin
|
||||||
|
inherited ApplyLabelFont(ADrawer);
|
||||||
|
if FAdditionalAngle <> 0 then
|
||||||
|
ADrawer.AddToFontOrientation(RadToOrient(FAdditionalAngle));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.Assign(ASource: TPersistent);
|
||||||
|
begin
|
||||||
|
if ASource is Self.ClassType then
|
||||||
|
with TGenericChartMarks(ASource) do begin
|
||||||
|
Self.FDistance := FDistance;
|
||||||
|
Self.FFormat := FFormat;
|
||||||
|
Self.FFrame.Assign(FFrame);
|
||||||
|
// FPC miscompiles virtual calls to generic type arguments,
|
||||||
|
// so as a workaround these assignments are moved to the specializations.
|
||||||
|
// Self.FLabelBrush.Assign(FLabelBrush);
|
||||||
|
// Self.FLabelFont.Assign(FLabelFont);
|
||||||
|
// Self.FLinkPen.Assign(FLinkPen);
|
||||||
|
Self.FStyle := FStyle;
|
||||||
|
end;
|
||||||
|
inherited Assign(ASource);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericChartMarks.CenterOffset(
|
||||||
|
ADrawer: IChartDrawer; const AText: String): TSize;
|
||||||
|
var
|
||||||
|
d: Integer;
|
||||||
|
begin
|
||||||
|
d := ADrawer.Scale(Distance);
|
||||||
|
Result := Size(d, d);
|
||||||
|
if not DistanceToCenter then
|
||||||
|
Result += MeasureLabel(ADrawer, AText) div 2;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TGenericChartMarks.Create(AOwner: TCustomChart);
|
||||||
|
begin
|
||||||
|
inherited Create(AOwner);
|
||||||
|
FArrow := TChartArrow.Create(AOwner);
|
||||||
|
InitHelper(FFrame, _TFramePen);
|
||||||
|
InitHelper(FLabelBrush, _TLabelBrush);
|
||||||
|
InitHelper(FLabelFont, TFont);
|
||||||
|
InitHelper(FLinkPen, _TLinkPen);
|
||||||
|
FStyle := smsNone;
|
||||||
|
FVisible := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TGenericChartMarks.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FArrow);
|
||||||
|
FreeAndNil(FFrame);
|
||||||
|
FreeAndNil(FLabelBrush);
|
||||||
|
FreeAndNil(FLabelFont);
|
||||||
|
FreeAndNil(FLinkPen);
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.DrawLink(
|
||||||
|
ADrawer: IChartDrawer; ADataPoint, ALabelCenter: TPoint);
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
with (ADataPoint - ALabelCenter) do
|
||||||
|
Arrow.Draw(ADrawer, ADataPoint, ArcTan2(Y, X), GetLinkPen);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericChartMarks.GetDistanceToCenter: Boolean;
|
||||||
|
begin
|
||||||
|
Result := Attachment = maCenter;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericChartMarks.GetFrame: TChartPen;
|
||||||
|
begin
|
||||||
|
Result := Frame;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericChartMarks.GetLabelAngle: Double;
|
||||||
|
begin
|
||||||
|
Result := inherited GetLabelAngle - FAdditionalAngle;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericChartMarks.GetLabelBrush: TBrush;
|
||||||
|
begin
|
||||||
|
Result := LabelBrush;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericChartMarks.GetLabelFont: TFont;
|
||||||
|
begin
|
||||||
|
Result := LabelFont;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericChartMarks.GetLabelPolygon(ADrawer: IChartDrawer;
|
||||||
|
ASize: TPoint): TPointArray;
|
||||||
|
var
|
||||||
|
e: TEllipse;
|
||||||
|
a: Double;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
AddMargins(ADrawer, ASize);
|
||||||
|
case Shape of
|
||||||
|
cmsRectangle: Result := RotateRect(ASize, GetLabelAngle);
|
||||||
|
cmsEllipse: begin
|
||||||
|
e.InitRadius(ASize.X / 2, ASize.Y / 2);
|
||||||
|
Result := e.TesselateRadialPie(0, 2 * Pi, 3);
|
||||||
|
SetLength(Result, Length(Result) - 1);
|
||||||
|
a := GetLabelAngle;
|
||||||
|
for i := 0 to High(Result) do
|
||||||
|
Result[i] := RotatePoint(Result[i], a);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericChartMarks.GetLinkPen: TChartPen;
|
||||||
|
begin
|
||||||
|
Result := LinkPen;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericChartMarks.IsMarkLabelsVisible: Boolean;
|
||||||
|
begin
|
||||||
|
Result := Visible and (Style <> smsNone) and (Format <> '');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetAdditionalAngle(AAngle: Double);
|
||||||
|
begin
|
||||||
|
FAdditionalAngle := AAngle;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetArrow(AValue: TChartArrow);
|
||||||
|
begin
|
||||||
|
if FArrow = AValue then exit;
|
||||||
|
FArrow.Assign(AValue);
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetAttachment(AValue: TChartMarkAttachment);
|
||||||
|
begin
|
||||||
|
if FAttachment = AValue then exit;
|
||||||
|
FAttachment := AValue;
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetDistance(AValue: TChartDistance);
|
||||||
|
begin
|
||||||
|
if FDistance = AValue then exit;
|
||||||
|
FDistance := AValue;
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetDistanceToCenter(AValue: Boolean);
|
||||||
|
begin
|
||||||
|
if AValue then
|
||||||
|
Attachment := maCenter
|
||||||
|
else
|
||||||
|
Attachment := maDefault;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetFormat(AValue: String);
|
||||||
|
begin
|
||||||
|
if FFormat = AValue then exit;
|
||||||
|
TCustomChartSource.CheckFormat(AValue);
|
||||||
|
FFormat := AValue;
|
||||||
|
FStyle := High(FStyle);
|
||||||
|
while (FStyle > smsCustom) and (SERIES_MARK_FORMATS[FStyle] <> AValue) do
|
||||||
|
Dec(FStyle);
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetFrame(AValue: _TFramePen);
|
||||||
|
begin
|
||||||
|
if FFrame = AValue then exit;
|
||||||
|
FFrame.Assign(AValue);
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetLabelBrush(AValue: _TLabelBrush);
|
||||||
|
begin
|
||||||
|
if FLabelBrush = AValue then exit;
|
||||||
|
FLabelBrush.Assign(AValue);
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetLabelFont(AValue: TFont);
|
||||||
|
begin
|
||||||
|
if FLabelFont = AValue then exit;
|
||||||
|
FLabelFont.Assign(AValue);
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetLinkPen(AValue: _TLinkPen);
|
||||||
|
begin
|
||||||
|
if FLinkPen = AValue then exit;
|
||||||
|
FLinkPen.Assign(AValue);
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetShape(AValue: TChartMarkLabelShape);
|
||||||
|
begin
|
||||||
|
if FShape = AValue then exit;
|
||||||
|
FShape := AValue;
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetStyle(AValue: TSeriesMarksStyle);
|
||||||
|
begin
|
||||||
|
if FStyle = AValue then exit;
|
||||||
|
FStyle := AValue;
|
||||||
|
if FStyle <> smsCustom then
|
||||||
|
FFormat := SERIES_MARK_FORMATS[FStyle];
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericChartMarks.SetYIndex(AValue: Integer);
|
||||||
|
begin
|
||||||
|
if FYIndex = AValue then exit;
|
||||||
|
FYIndex := AValue;
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TChartMarks }
|
||||||
|
|
||||||
|
procedure TChartMarks.Assign(Source: TPersistent);
|
||||||
|
begin
|
||||||
|
if Source is TChartMarks then
|
||||||
|
with TChartMarks(Source) do begin
|
||||||
|
Self.FLabelBrush.Assign(FLabelBrush);
|
||||||
|
Self.FLabelFont.Assign(FLabelFont);
|
||||||
|
Self.FLinkPen.Assign(FLinkPen);
|
||||||
|
end;
|
||||||
|
inherited Assign(Source);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TChartMarks.Create(AOwner: TCustomChart);
|
||||||
|
begin
|
||||||
|
inherited Create(AOwner);
|
||||||
|
FDistance := DEF_MARKS_DISTANCE;
|
||||||
|
FLabelBrush.Color := clYellow;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -23,17 +23,15 @@ Authors: Luнs Rodrigues, Philippe Martinole, Alexander Klenin
|
|||||||
}
|
}
|
||||||
unit TATypes;
|
unit TATypes;
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$H+}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Math, Graphics, Controls, FPCanvas, Types, GraphMath,
|
Classes, Graphics, Controls, FPCanvas,
|
||||||
TACustomSource, TAChartUtils, TADrawUtils, TAGeometry;
|
TAChartUtils, TADrawUtils;
|
||||||
|
|
||||||
const
|
const
|
||||||
MARKS_MARGIN_X = 4;
|
|
||||||
MARKS_MARGIN_Y = 2;
|
|
||||||
DEF_MARGIN = 4;
|
DEF_MARGIN = 4;
|
||||||
DEF_MARKS_DISTANCE = 20;
|
DEF_MARKS_DISTANCE = 20;
|
||||||
DEF_POINTER_SIZE = 4;
|
DEF_POINTER_SIZE = 4;
|
||||||
@ -85,206 +83,6 @@ type
|
|||||||
property Visible: Boolean read FVisible write SetVisible;
|
property Visible: Boolean read FVisible write SetVisible;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TChartMarksOverlapPolicy = (opIgnore, opHideNeighbour);
|
|
||||||
|
|
||||||
TChartTextElement = class(TChartElement)
|
|
||||||
strict private
|
|
||||||
FClipped: Boolean;
|
|
||||||
FOverlapPolicy: TChartMarksOverlapPolicy;
|
|
||||||
procedure SetAlignment(AValue: TAlignment);
|
|
||||||
procedure SetClipped(AValue: Boolean);
|
|
||||||
procedure SetOverlapPolicy(AValue: TChartMarksOverlapPolicy);
|
|
||||||
strict protected
|
|
||||||
FAlignment: TAlignment;
|
|
||||||
procedure AddMargins(ADrawer: IChartDrawer; var ASize: TPoint);
|
|
||||||
procedure ApplyLabelFont(ADrawer: IChartDrawer); virtual;
|
|
||||||
procedure DrawLink(
|
|
||||||
ADrawer: IChartDrawer; ADataPoint, ALabelCenter: TPoint); virtual;
|
|
||||||
function IsMarginRequired: Boolean;
|
|
||||||
strict protected
|
|
||||||
function GetFrame: TChartPen; virtual; abstract;
|
|
||||||
function GetLabelAngle: Double; virtual;
|
|
||||||
function GetLabelBrush: TBrush; virtual; abstract;
|
|
||||||
function GetLabelFont: TFont; virtual; abstract;
|
|
||||||
function GetLinkPen: TChartPen; virtual;
|
|
||||||
public
|
|
||||||
constructor Create(AOwner: TCustomChart);
|
|
||||||
public
|
|
||||||
procedure Assign(ASource: TPersistent); override;
|
|
||||||
procedure DrawLabel(
|
|
||||||
ADrawer: IChartDrawer; const ADataPoint, ALabelCenter: TPoint;
|
|
||||||
const AText: String; var APrevLabelPoly: TPointArray);
|
|
||||||
function GetLabelPolygon(
|
|
||||||
ADrawer: IChartDrawer; ASize: TPoint): TPointArray; virtual;
|
|
||||||
function MeasureLabel(ADrawer: IChartDrawer; const AText: String): TSize;
|
|
||||||
public
|
|
||||||
// If false, labels may overlap axises and legend.
|
|
||||||
property Clipped: Boolean read FClipped write SetClipped default true;
|
|
||||||
property OverlapPolicy: TChartMarksOverlapPolicy
|
|
||||||
read FOverlapPolicy write SetOverlapPolicy default opIgnore;
|
|
||||||
published
|
|
||||||
property Alignment: TAlignment
|
|
||||||
read FAlignment write SetAlignment;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TChartTitleFramePen = class(TChartPen)
|
|
||||||
published
|
|
||||||
property Visible default false;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TChartTitle }
|
|
||||||
|
|
||||||
TChartTitle = class(TChartTextElement)
|
|
||||||
strict private
|
|
||||||
FBrush: TBrush;
|
|
||||||
FFont: TFont;
|
|
||||||
FFrame: TChartTitleFramePen;
|
|
||||||
FMargin: TChartDistance;
|
|
||||||
FText: TStrings;
|
|
||||||
|
|
||||||
procedure SetBrush(AValue: TBrush);
|
|
||||||
procedure SetFont(AValue: TFont);
|
|
||||||
procedure SetFrame(AValue: TChartTitleFramePen);
|
|
||||||
procedure SetMargin(AValue: TChartDistance);
|
|
||||||
procedure SetText(AValue: TStrings);
|
|
||||||
strict protected
|
|
||||||
function GetFrame: TChartPen; override;
|
|
||||||
function GetLabelBrush: TBrush; override;
|
|
||||||
function GetLabelFont: TFont; override;
|
|
||||||
public
|
|
||||||
constructor Create(AOwner: TCustomChart);
|
|
||||||
destructor Destroy; override;
|
|
||||||
public
|
|
||||||
procedure Assign(ASource: TPersistent); override;
|
|
||||||
procedure Draw(
|
|
||||||
ADrawer: IChartDrawer; ADir, ALeft, ARight: Integer; var AY: Integer);
|
|
||||||
published
|
|
||||||
property Alignment default taCenter;
|
|
||||||
property Brush: TBrush read FBrush write SetBrush;
|
|
||||||
property Font: TFont read FFont write SetFont;
|
|
||||||
property Frame: TChartTitleFramePen read FFrame write SetFrame;
|
|
||||||
property Margin: TChartDistance
|
|
||||||
read FMargin write SetMargin default DEF_MARGIN;
|
|
||||||
property Text: TStrings read FText write SetText;
|
|
||||||
property Visible default false;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TChartArrow = class;
|
|
||||||
|
|
||||||
TChartMarkAttachment = (maDefault, maEdge, maCenter);
|
|
||||||
TChartMarkLabelShape = (cmsRectangle, cmsEllipse);
|
|
||||||
|
|
||||||
{ TGenericChartMarks }
|
|
||||||
|
|
||||||
{$IFNDEF fpdoc} // Workaround for issue #18549.
|
|
||||||
generic TGenericChartMarks<_TLabelBrush, _TLinkPen, _TFramePen> =
|
|
||||||
class(TChartTextElement)
|
|
||||||
{$ELSE}
|
|
||||||
TGenericChartMarks = class(TChartTextElement)
|
|
||||||
{$ENDIF}
|
|
||||||
strict private
|
|
||||||
FAdditionalAngle: Double;
|
|
||||||
FArrow: TChartArrow;
|
|
||||||
FAttachment: TChartMarkAttachment;
|
|
||||||
FFrame: _TFramePen;
|
|
||||||
FShape: TChartMarkLabelShape;
|
|
||||||
FYIndex: Integer;
|
|
||||||
function GetDistanceToCenter: Boolean;
|
|
||||||
procedure SetArrow(AValue: TChartArrow);
|
|
||||||
procedure SetAttachment(AValue: TChartMarkAttachment);
|
|
||||||
procedure SetDistance(AValue: TChartDistance);
|
|
||||||
procedure SetDistanceToCenter(AValue: Boolean);
|
|
||||||
procedure SetFormat(AValue: String);
|
|
||||||
procedure SetFrame(AValue: _TFramePen);
|
|
||||||
procedure SetLabelBrush(AValue: _TLabelBrush);
|
|
||||||
procedure SetLabelFont(AValue: TFont);
|
|
||||||
procedure SetLinkPen(AValue: _TLinkPen);
|
|
||||||
procedure SetShape(AValue: TChartMarkLabelShape);
|
|
||||||
procedure SetStyle(AValue: TSeriesMarksStyle);
|
|
||||||
procedure SetYIndex(AValue: Integer);
|
|
||||||
strict protected
|
|
||||||
FDistance: TChartDistance;
|
|
||||||
FFormat: String;
|
|
||||||
FLabelBrush: _TLabelBrush;
|
|
||||||
FLabelFont: TFont;
|
|
||||||
FLinkPen: _TLinkPen;
|
|
||||||
FStyle: TSeriesMarksStyle;
|
|
||||||
strict protected
|
|
||||||
procedure ApplyLabelFont(ADrawer: IChartDrawer); override;
|
|
||||||
procedure DrawLink(
|
|
||||||
ADrawer: IChartDrawer; ADataPoint, ALabelCenter: TPoint); override;
|
|
||||||
function GetFrame: TChartPen; override;
|
|
||||||
function GetLabelAngle: Double; override;
|
|
||||||
function GetLabelBrush: TBrush; override;
|
|
||||||
function GetLabelFont: TFont; override;
|
|
||||||
function GetLinkPen: TChartPen; override;
|
|
||||||
public
|
|
||||||
constructor Create(AOwner: TCustomChart);
|
|
||||||
destructor Destroy; override;
|
|
||||||
public
|
|
||||||
procedure Assign(ASource: TPersistent); override;
|
|
||||||
function CenterOffset(ADrawer: IChartDrawer; const AText: String): TSize;
|
|
||||||
function GetLabelPolygon(
|
|
||||||
ADrawer: IChartDrawer; ASize: TPoint): TPointArray; override;
|
|
||||||
function IsMarkLabelsVisible: Boolean;
|
|
||||||
procedure SetAdditionalAngle(AAngle: Double);
|
|
||||||
public
|
|
||||||
property Arrow: TChartArrow read FArrow write SetArrow;
|
|
||||||
property DistanceToCenter: Boolean
|
|
||||||
read GetDistanceToCenter write SetDistanceToCenter
|
|
||||||
stored false default false;
|
|
||||||
property Format: String read FFormat write SetFormat;
|
|
||||||
property Frame: _TFramePen read FFrame write SetFrame;
|
|
||||||
property LabelBrush: _TLabelBrush read FLabelBrush write SetLabelBrush;
|
|
||||||
property LinkPen: _TLinkPen read FLinkPen write SetLinkPen;
|
|
||||||
property Style: TSeriesMarksStyle read FStyle write SetStyle;
|
|
||||||
property YIndex: Integer read FYIndex write SetYIndex default 0;
|
|
||||||
published
|
|
||||||
property Alignment default taLeftJustify;
|
|
||||||
property Attachment: TChartMarkAttachment
|
|
||||||
read FAttachment write SetAttachment default maDefault;
|
|
||||||
// Distance between labelled object and label.
|
|
||||||
property Clipped;
|
|
||||||
property Distance: TChartDistance read FDistance write SetDistance;
|
|
||||||
property LabelFont: TFont read FLabelFont write SetLabelFont;
|
|
||||||
property Shape: TChartMarkLabelShape
|
|
||||||
read FShape write SetShape default cmsRectangle;
|
|
||||||
property Visible default true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TChartLinkPen = class(TChartPen)
|
|
||||||
published
|
|
||||||
property Color default clWhite;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TChartLabelBrush = class(TBrush)
|
|
||||||
published
|
|
||||||
property Color default clYellow;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{$IFNDEF fpdoc} // Workaround for issue #18549.
|
|
||||||
TCustomChartMarks =
|
|
||||||
specialize TGenericChartMarks<TChartLabelBrush, TChartLinkPen, TChartPen>;
|
|
||||||
{$ENDIF}
|
|
||||||
|
|
||||||
{ TChartMarks }
|
|
||||||
|
|
||||||
TChartMarks = class(TCustomChartMarks)
|
|
||||||
public
|
|
||||||
procedure Assign(Source: TPersistent); override;
|
|
||||||
constructor Create(AOwner: TCustomChart);
|
|
||||||
published
|
|
||||||
property Arrow;
|
|
||||||
property Distance default DEF_MARKS_DISTANCE;
|
|
||||||
property Format;
|
|
||||||
property Frame;
|
|
||||||
property LabelBrush;
|
|
||||||
property LinkPen;
|
|
||||||
property OverlapPolicy;
|
|
||||||
property Style default smsNone;
|
|
||||||
property YIndex;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TSeriesPointerStyle = (
|
TSeriesPointerStyle = (
|
||||||
psNone, psRectangle, psCircle, psCross, psDiagCross, psStar,
|
psNone, psRectangle, psCircle, psCross, psDiagCross, psStar,
|
||||||
psLowBracket, psHighBracket, psLeftBracket, psRightBracket, psDiamond,
|
psLowBracket, psHighBracket, psLeftBracket, psRightBracket, psDiamond,
|
||||||
@ -426,6 +224,10 @@ type
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
Math, SysUtils,
|
||||||
|
TAGeometry;
|
||||||
|
|
||||||
{ TChartPen }
|
{ TChartPen }
|
||||||
|
|
||||||
procedure TChartPen.Assign(ASource: TPersistent);
|
procedure TChartPen.Assign(ASource: TPersistent);
|
||||||
@ -493,492 +295,6 @@ begin
|
|||||||
FOwner.StyleChanged(Sender);
|
FOwner.StyleChanged(Sender);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TChartTextElement }
|
|
||||||
|
|
||||||
procedure TChartTextElement.AddMargins(
|
|
||||||
ADrawer: IChartDrawer; var ASize: TPoint);
|
|
||||||
begin
|
|
||||||
if not IsMarginRequired then exit;
|
|
||||||
with ADrawer do
|
|
||||||
ASize += Point(Scale(MARKS_MARGIN_X), Scale(MARKS_MARGIN_Y)) * 2;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTextElement.ApplyLabelFont(ADrawer: IChartDrawer);
|
|
||||||
begin
|
|
||||||
ADrawer.Font := GetLabelFont;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTextElement.Assign(ASource: TPersistent);
|
|
||||||
begin
|
|
||||||
if ASource is TChartTextElement then
|
|
||||||
with TChartTextElement(ASource) do begin
|
|
||||||
Self.FAlignment := Alignment;
|
|
||||||
Self.FClipped := FClipped;
|
|
||||||
Self.FOverlapPolicy := FOverlapPolicy;
|
|
||||||
end;
|
|
||||||
inherited Assign(ASource);
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TChartTextElement.Create(AOwner: TCustomChart);
|
|
||||||
begin
|
|
||||||
inherited Create(AOwner);
|
|
||||||
FClipped := true;
|
|
||||||
FOverlapPolicy := opIgnore;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTextElement.DrawLabel(
|
|
||||||
ADrawer: IChartDrawer; const ADataPoint, ALabelCenter: TPoint;
|
|
||||||
const AText: String; var APrevLabelPoly: TPointArray);
|
|
||||||
var
|
|
||||||
labelPoly: TPointArray;
|
|
||||||
ptText: TPoint;
|
|
||||||
i, w: Integer;
|
|
||||||
begin
|
|
||||||
ApplyLabelFont(ADrawer);
|
|
||||||
ptText := ADrawer.TextExtent(AText);
|
|
||||||
w := ptText.X;
|
|
||||||
labelPoly := GetLabelPolygon(ADrawer, ptText);
|
|
||||||
for i := 0 to High(labelPoly) do
|
|
||||||
labelPoly[i] += ALabelCenter;
|
|
||||||
|
|
||||||
if
|
|
||||||
(OverlapPolicy = opHideNeighbour) and
|
|
||||||
IsPolygonIntersectsPolygon(APrevLabelPoly, labelPoly)
|
|
||||||
then
|
|
||||||
exit;
|
|
||||||
APrevLabelPoly := labelPoly;
|
|
||||||
|
|
||||||
if not Clipped then
|
|
||||||
ADrawer.ClippingStop;
|
|
||||||
|
|
||||||
DrawLink(ADrawer, ADataPoint, ALabelCenter);
|
|
||||||
ADrawer.Brush := GetLabelBrush;
|
|
||||||
if IsMarginRequired then begin
|
|
||||||
if GetFrame.Visible then
|
|
||||||
ADrawer.Pen := GetFrame
|
|
||||||
else
|
|
||||||
ADrawer.SetPenParams(psClear, clTAColor);
|
|
||||||
ADrawer.Polygon(labelPoly, 0, Length(labelPoly));
|
|
||||||
end;
|
|
||||||
|
|
||||||
ptText := RotatePoint(-ptText div 2, GetLabelAngle) + ALabelCenter;
|
|
||||||
ADrawer.TextOut.Pos(ptText).Alignment(Alignment).Width(w).Text(AText).Done;
|
|
||||||
if not Clipped then
|
|
||||||
ADrawer.ClippingStart;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTextElement.DrawLink(
|
|
||||||
ADrawer: IChartDrawer; ADataPoint, ALabelCenter: TPoint);
|
|
||||||
var
|
|
||||||
p: TChartPen;
|
|
||||||
begin
|
|
||||||
if ADataPoint = ALabelCenter then exit;
|
|
||||||
p := GetLinkPen;
|
|
||||||
if p.Visible then begin
|
|
||||||
ADrawer.Pen := p;
|
|
||||||
ADrawer.Line(ADataPoint, ALabelCenter);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TChartTextElement.GetLabelAngle: Double;
|
|
||||||
begin
|
|
||||||
// Negate to take into account top-down Y axis.
|
|
||||||
Result := -OrientToRad(GetLabelFont.Orientation);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TChartTextElement.GetLabelPolygon(
|
|
||||||
ADrawer: IChartDrawer; ASize: TPoint): TPointArray;
|
|
||||||
begin
|
|
||||||
AddMargins(ADrawer, ASize);
|
|
||||||
Result := RotateRect(ASize, GetLabelAngle);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TChartTextElement.GetLinkPen: TChartPen;
|
|
||||||
begin
|
|
||||||
Result := nil;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TChartTextElement.IsMarginRequired: Boolean;
|
|
||||||
begin
|
|
||||||
with GetFrame do
|
|
||||||
Result := (GetLabelBrush.Style <> bsClear) or (Style <> psClear) and Visible;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TChartTextElement.MeasureLabel(
|
|
||||||
ADrawer: IChartDrawer; const AText: String): TSize;
|
|
||||||
var
|
|
||||||
sz: TPoint;
|
|
||||||
begin
|
|
||||||
ApplyLabelFont(ADrawer);
|
|
||||||
sz := ADrawer.TextExtent(AText);
|
|
||||||
AddMargins(ADrawer, sz);
|
|
||||||
Result := MeasureRotatedRect(sz, GetLabelAngle);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTextElement.SetAlignment(AValue: TAlignment);
|
|
||||||
begin
|
|
||||||
if FAlignment = AValue then exit;
|
|
||||||
FAlignment := AValue;
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTextElement.SetClipped(AValue: Boolean);
|
|
||||||
begin
|
|
||||||
if FClipped = AValue then exit;
|
|
||||||
FClipped := AValue;
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTextElement.SetOverlapPolicy(AValue: TChartMarksOverlapPolicy);
|
|
||||||
begin
|
|
||||||
if FOverlapPolicy = AValue then exit;
|
|
||||||
FOverlapPolicy := AValue;
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TChartTitle }
|
|
||||||
|
|
||||||
procedure TChartTitle.Assign(ASource: TPersistent);
|
|
||||||
begin
|
|
||||||
if ASource is TChartTitle then
|
|
||||||
with TChartTitle(ASource) do begin
|
|
||||||
Self.FBrush.Assign(Brush);
|
|
||||||
Self.FFont.Assign(Font);
|
|
||||||
Self.FFrame.Assign(Frame);
|
|
||||||
Self.FText.Assign(Text);
|
|
||||||
end;
|
|
||||||
|
|
||||||
inherited Assign(ASource);
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TChartTitle.Create(AOwner: TCustomChart);
|
|
||||||
begin
|
|
||||||
inherited Create(AOwner);
|
|
||||||
|
|
||||||
FAlignment := taCenter;
|
|
||||||
InitHelper(FBrush, TBrush);
|
|
||||||
FBrush.Color := FOwner.Color;
|
|
||||||
InitHelper(FFont, TFont);
|
|
||||||
FFont.Color := clBlue;
|
|
||||||
InitHelper(FFrame, TChartTitleFramePen);
|
|
||||||
FMargin := DEF_MARGIN;
|
|
||||||
FText := TStringList.Create;
|
|
||||||
TStringList(FText).OnChange := @StyleChanged;
|
|
||||||
end;
|
|
||||||
|
|
||||||
destructor TChartTitle.Destroy;
|
|
||||||
begin
|
|
||||||
FreeAndNil(FBrush);
|
|
||||||
FreeAndNil(FFont);
|
|
||||||
FreeAndNil(FFrame);
|
|
||||||
FreeAndNil(FText);
|
|
||||||
|
|
||||||
inherited;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTitle.Draw(
|
|
||||||
ADrawer: IChartDrawer; ADir, ALeft, ARight: Integer; var AY: Integer);
|
|
||||||
var
|
|
||||||
p, ptSize: TPoint;
|
|
||||||
dummy: TPointArray = nil;
|
|
||||||
begin
|
|
||||||
if not Visible or (Text.Count = 0) then exit;
|
|
||||||
ptSize := MeasureLabel(ADrawer, Text.Text);
|
|
||||||
case Alignment of
|
|
||||||
taLeftJustify: p.X := ALeft + ptSize.X div 2;
|
|
||||||
taRightJustify: p.X := ARight - ptSize.X div 2;
|
|
||||||
taCenter: p.X := (ALeft + ARight) div 2;
|
|
||||||
end;
|
|
||||||
p.Y := AY + ADir * ptSize.Y div 2;
|
|
||||||
DrawLabel(ADrawer, p, p, Text.Text, dummy);
|
|
||||||
AY += ADir * (ptSize.Y + Margin);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TChartTitle.GetFrame: TChartPen;
|
|
||||||
begin
|
|
||||||
Result := Frame;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TChartTitle.GetLabelBrush: TBrush;
|
|
||||||
begin
|
|
||||||
Result := Brush;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TChartTitle.GetLabelFont: TFont;
|
|
||||||
begin
|
|
||||||
Result := Font;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTitle.SetBrush(AValue: TBrush);
|
|
||||||
begin
|
|
||||||
FBrush.Assign(AValue);
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTitle.SetFont(AValue: TFont);
|
|
||||||
begin
|
|
||||||
FFont.Assign(AValue);
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTitle.SetFrame(AValue: TChartTitleFramePen);
|
|
||||||
begin
|
|
||||||
FFrame.Assign(AValue);
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTitle.SetMargin(AValue: TChartDistance);
|
|
||||||
begin
|
|
||||||
if FMargin = AValue then exit;
|
|
||||||
FMargin := AValue;
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TChartTitle.SetText(AValue: TStrings);
|
|
||||||
begin
|
|
||||||
FText.Assign(AValue);
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TGenericChartMarks }
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.ApplyLabelFont(ADrawer: IChartDrawer);
|
|
||||||
begin
|
|
||||||
inherited ApplyLabelFont(ADrawer);
|
|
||||||
if FAdditionalAngle <> 0 then
|
|
||||||
ADrawer.AddToFontOrientation(RadToOrient(FAdditionalAngle));
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.Assign(ASource: TPersistent);
|
|
||||||
begin
|
|
||||||
if ASource is Self.ClassType then
|
|
||||||
with TGenericChartMarks(ASource) do begin
|
|
||||||
Self.FDistance := FDistance;
|
|
||||||
Self.FFormat := FFormat;
|
|
||||||
Self.FFrame.Assign(FFrame);
|
|
||||||
// FPC miscompiles virtual calls to generic type arguments,
|
|
||||||
// so as a workaround these assignments are moved to the specializations.
|
|
||||||
// Self.FLabelBrush.Assign(FLabelBrush);
|
|
||||||
// Self.FLabelFont.Assign(FLabelFont);
|
|
||||||
// Self.FLinkPen.Assign(FLinkPen);
|
|
||||||
Self.FStyle := FStyle;
|
|
||||||
end;
|
|
||||||
inherited Assign(ASource);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGenericChartMarks.CenterOffset(
|
|
||||||
ADrawer: IChartDrawer; const AText: String): TSize;
|
|
||||||
var
|
|
||||||
d: Integer;
|
|
||||||
begin
|
|
||||||
d := ADrawer.Scale(Distance);
|
|
||||||
Result := Size(d, d);
|
|
||||||
if not DistanceToCenter then
|
|
||||||
Result += MeasureLabel(ADrawer, AText) div 2;
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TGenericChartMarks.Create(AOwner: TCustomChart);
|
|
||||||
begin
|
|
||||||
inherited Create(AOwner);
|
|
||||||
FArrow := TChartArrow.Create(AOwner);
|
|
||||||
InitHelper(FFrame, _TFramePen);
|
|
||||||
InitHelper(FLabelBrush, _TLabelBrush);
|
|
||||||
InitHelper(FLabelFont, TFont);
|
|
||||||
InitHelper(FLinkPen, _TLinkPen);
|
|
||||||
FStyle := smsNone;
|
|
||||||
FVisible := true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
destructor TGenericChartMarks.Destroy;
|
|
||||||
begin
|
|
||||||
FreeAndNil(FArrow);
|
|
||||||
FreeAndNil(FFrame);
|
|
||||||
FreeAndNil(FLabelBrush);
|
|
||||||
FreeAndNil(FLabelFont);
|
|
||||||
FreeAndNil(FLinkPen);
|
|
||||||
inherited;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.DrawLink(
|
|
||||||
ADrawer: IChartDrawer; ADataPoint, ALabelCenter: TPoint);
|
|
||||||
begin
|
|
||||||
inherited;
|
|
||||||
with (ADataPoint - ALabelCenter) do
|
|
||||||
Arrow.Draw(ADrawer, ADataPoint, ArcTan2(Y, X), GetLinkPen);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGenericChartMarks.GetDistanceToCenter: Boolean;
|
|
||||||
begin
|
|
||||||
Result := Attachment = maCenter;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGenericChartMarks.GetFrame: TChartPen;
|
|
||||||
begin
|
|
||||||
Result := Frame;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGenericChartMarks.GetLabelAngle: Double;
|
|
||||||
begin
|
|
||||||
Result := inherited GetLabelAngle - FAdditionalAngle;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGenericChartMarks.GetLabelBrush: TBrush;
|
|
||||||
begin
|
|
||||||
Result := LabelBrush;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGenericChartMarks.GetLabelFont: TFont;
|
|
||||||
begin
|
|
||||||
Result := LabelFont;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGenericChartMarks.GetLabelPolygon(ADrawer: IChartDrawer;
|
|
||||||
ASize: TPoint): TPointArray;
|
|
||||||
var
|
|
||||||
e: TEllipse;
|
|
||||||
a: Double;
|
|
||||||
i: Integer;
|
|
||||||
begin
|
|
||||||
AddMargins(ADrawer, ASize);
|
|
||||||
case Shape of
|
|
||||||
cmsRectangle: Result := RotateRect(ASize, GetLabelAngle);
|
|
||||||
cmsEllipse: begin
|
|
||||||
e.InitRadius(ASize.X / 2, ASize.Y / 2);
|
|
||||||
Result := e.TesselateRadialPie(0, 2 * Pi, 3);
|
|
||||||
SetLength(Result, Length(Result) - 1);
|
|
||||||
a := GetLabelAngle;
|
|
||||||
for i := 0 to High(Result) do
|
|
||||||
Result[i] := RotatePoint(Result[i], a);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGenericChartMarks.GetLinkPen: TChartPen;
|
|
||||||
begin
|
|
||||||
Result := LinkPen;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGenericChartMarks.IsMarkLabelsVisible: Boolean;
|
|
||||||
begin
|
|
||||||
Result := Visible and (Style <> smsNone) and (Format <> '');
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetAdditionalAngle(AAngle: Double);
|
|
||||||
begin
|
|
||||||
FAdditionalAngle := AAngle;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetArrow(AValue: TChartArrow);
|
|
||||||
begin
|
|
||||||
if FArrow = AValue then exit;
|
|
||||||
FArrow.Assign(AValue);
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetAttachment(AValue: TChartMarkAttachment);
|
|
||||||
begin
|
|
||||||
if FAttachment = AValue then exit;
|
|
||||||
FAttachment := AValue;
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetDistance(AValue: TChartDistance);
|
|
||||||
begin
|
|
||||||
if FDistance = AValue then exit;
|
|
||||||
FDistance := AValue;
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetDistanceToCenter(AValue: Boolean);
|
|
||||||
begin
|
|
||||||
if AValue then
|
|
||||||
Attachment := maCenter
|
|
||||||
else
|
|
||||||
Attachment := maDefault;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetFormat(AValue: String);
|
|
||||||
begin
|
|
||||||
if FFormat = AValue then exit;
|
|
||||||
TCustomChartSource.CheckFormat(AValue);
|
|
||||||
FFormat := AValue;
|
|
||||||
FStyle := High(FStyle);
|
|
||||||
while (FStyle > smsCustom) and (SERIES_MARK_FORMATS[FStyle] <> AValue) do
|
|
||||||
Dec(FStyle);
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetFrame(AValue: _TFramePen);
|
|
||||||
begin
|
|
||||||
if FFrame = AValue then exit;
|
|
||||||
FFrame.Assign(AValue);
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetLabelBrush(AValue: _TLabelBrush);
|
|
||||||
begin
|
|
||||||
if FLabelBrush = AValue then exit;
|
|
||||||
FLabelBrush.Assign(AValue);
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetLabelFont(AValue: TFont);
|
|
||||||
begin
|
|
||||||
if FLabelFont = AValue then exit;
|
|
||||||
FLabelFont.Assign(AValue);
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetLinkPen(AValue: _TLinkPen);
|
|
||||||
begin
|
|
||||||
if FLinkPen = AValue then exit;
|
|
||||||
FLinkPen.Assign(AValue);
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetShape(AValue: TChartMarkLabelShape);
|
|
||||||
begin
|
|
||||||
if FShape = AValue then exit;
|
|
||||||
FShape := AValue;
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetStyle(AValue: TSeriesMarksStyle);
|
|
||||||
begin
|
|
||||||
if FStyle = AValue then exit;
|
|
||||||
FStyle := AValue;
|
|
||||||
if FStyle <> smsCustom then
|
|
||||||
FFormat := SERIES_MARK_FORMATS[FStyle];
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGenericChartMarks.SetYIndex(AValue: Integer);
|
|
||||||
begin
|
|
||||||
if FYIndex = AValue then exit;
|
|
||||||
FYIndex := AValue;
|
|
||||||
StyleChanged(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TChartMarks }
|
|
||||||
|
|
||||||
procedure TChartMarks.Assign(Source: TPersistent);
|
|
||||||
begin
|
|
||||||
if Source is TChartMarks then
|
|
||||||
with TChartMarks(Source) do begin
|
|
||||||
Self.FLabelBrush.Assign(FLabelBrush);
|
|
||||||
Self.FLabelFont.Assign(FLabelFont);
|
|
||||||
Self.FLinkPen.Assign(FLinkPen);
|
|
||||||
end;
|
|
||||||
inherited Assign(Source);
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TChartMarks.Create(AOwner: TCustomChart);
|
|
||||||
begin
|
|
||||||
inherited Create(AOwner);
|
|
||||||
FDistance := DEF_MARKS_DISTANCE;
|
|
||||||
FLabelBrush.Color := clYellow;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TSeriesPointer }
|
{ TSeriesPointer }
|
||||||
|
|
||||||
procedure TSeriesPointer.Assign(Source: TPersistent);
|
procedure TSeriesPointer.Assign(Source: TPersistent);
|
||||||
|
Loading…
Reference in New Issue
Block a user