2023-10-23 22:18:31 +00:00
|
|
|
unit fpsChart;
|
2023-10-22 08:33:55 +00:00
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
2023-10-23 00:03:45 +00:00
|
|
|
{$modeswitch advancedrecords}
|
2023-10-22 08:33:55 +00:00
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
Classes, SysUtils, Contnrs, fpsTypes, fpsUtils;
|
|
|
|
|
|
|
|
const
|
|
|
|
clsNoLine = -2;
|
|
|
|
clsSolid = -1;
|
|
|
|
|
|
|
|
{@@ Pre-defined chart line styles given as indexes into the chart's LineStyles
|
|
|
|
list. Get their value in the constructor of TsChart. Default here to -1
|
2023-10-23 00:03:45 +00:00
|
|
|
which is the code for a solid line, just in case that something goes wrong }
|
2023-10-22 08:33:55 +00:00
|
|
|
var
|
|
|
|
clsFineDot: Integer = -1;
|
|
|
|
clsDot: Integer = -1;
|
|
|
|
clsDash: Integer = -1;
|
|
|
|
clsDashDot: Integer = -1;
|
|
|
|
clsLongDash: Integer = -1;
|
|
|
|
clsLongDashDot: Integer = -1;
|
|
|
|
clsLongDashDotDot: Integer = -1;
|
|
|
|
|
2023-10-23 22:18:31 +00:00
|
|
|
const
|
|
|
|
DEFAULT_CHART_LINEWIDTH = 0.75; // pts
|
|
|
|
DEFAULT_CHART_FONT = 'Arial';
|
|
|
|
|
2023-10-25 17:15:57 +00:00
|
|
|
DEFAULT_SERIES_COLORS: array[0..7] of TsColor = (
|
|
|
|
scRed, scBlue, scGreen, scMagenta, scPurple, scTeal, scBlack, scGray
|
|
|
|
);
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
type
|
|
|
|
TsChart = class;
|
|
|
|
|
2023-10-23 09:28:05 +00:00
|
|
|
TsChartLine = class
|
|
|
|
Style: Integer; // index into chart's LineStyle list or predefined clsSolid/clsNoLine
|
|
|
|
Width: Double; // mm
|
|
|
|
Color: TsColor; // in hex: $00bbggrr, r=red, g=green, b=blue
|
|
|
|
Transparency: Double; // in percent
|
|
|
|
end;
|
|
|
|
|
2023-11-05 00:26:04 +00:00
|
|
|
TsChartGradientStyle = (cgsLinear, cgsAxial, cgsRadial, cgsElliptic, cgsSquare, cgsRectangular);
|
|
|
|
|
|
|
|
TsChartGradient = class
|
|
|
|
Name: String;
|
|
|
|
Style: TsChartGradientStyle;
|
|
|
|
StartColor: TsColor;
|
|
|
|
EndColor: TsColor;
|
|
|
|
StartIntensity: Double; // 0.0 ... 1.0
|
|
|
|
EndIntensity: Double; // 0.0 ... 1.0
|
|
|
|
Border: Double; // 0.0 ... 1.0
|
|
|
|
CenterX, CenterY: Double; // 0.0 ... 1.0
|
|
|
|
Angle: Integer; // degrees
|
|
|
|
constructor Create;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartGradientList = class(TFPObjectList)
|
|
|
|
private
|
|
|
|
function GetItem(AIndex: Integer): TsChartGradient;
|
|
|
|
procedure SetItem(AIndex: Integer; AValue: TsChartGradient);
|
|
|
|
function AddGradient(AName: String; AStyle: TsChartGradientStyle;
|
|
|
|
AStartColor, AEndColor: TsColor; AStartIntensity, AEndIntensity: Double;
|
|
|
|
ABorder, ACenterX, ACenterY: Double; AAngle: Integer): Integer;
|
|
|
|
public
|
|
|
|
function AddAxialGradient(AName: String; AStartColor, AEndColor: TsColor;
|
|
|
|
AStartIntensity, AEndIntensity, ABorder: Double; AAngle: Integer): Integer;
|
|
|
|
function AddEllipticGradient(AName: String; AStartColor, AEndColor: TsColor;
|
|
|
|
AStartIntensity, AEndIntensity, ABorder, ACenterX, ACenterY: Double;
|
|
|
|
AAngle: Integer): Integer;
|
|
|
|
function AddLinearGradient(AName: String; AStartColor, AEndColor: TsColor;
|
|
|
|
AStartIntensity, AEndIntensity, ABorder: Double; AAngle: Integer): Integer;
|
|
|
|
function AddRadialGradient(AName: String;
|
|
|
|
AStartColor, AEndColor: TsColor; AStartIntensity, AEndIntensity, ABorder: Double;
|
|
|
|
ACenterX, ACenterY: Double): Integer;
|
|
|
|
function AddRectangularGradient(AName: String; AStartColor, AEndColor: TsColor;
|
|
|
|
AStartIntensity, AEndIntensity: Double; ABorder, ACenterX, ACenterY: Double;
|
|
|
|
AAngle: Integer): Integer;
|
|
|
|
function AddSquareGradient(AName: String; AStartColor, AEndColor: TsColor;
|
|
|
|
AStartIntensity, AEndIntensity: Double; ABorder, ACenterX, ACenterY: Double;
|
|
|
|
AAngle: Integer): Integer;
|
|
|
|
function IndexOfName(AName: String): Integer;
|
|
|
|
function FindByName(AName: String): TsChartGradient;
|
|
|
|
property Items[AIndex: Integer]: TsChartGradient read GetItem write SetItem; default;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartFillStyle = (cfsNoFill, cfsSolid, cfsGradient);
|
|
|
|
|
2023-10-23 09:28:05 +00:00
|
|
|
TsChartFill = class
|
2023-11-05 00:26:04 +00:00
|
|
|
Style: TsChartFillStyle;
|
2023-10-23 09:28:05 +00:00
|
|
|
FgColor: TsColor;
|
|
|
|
BgColor: TsColor;
|
2023-11-05 00:26:04 +00:00
|
|
|
Gradient: Integer;
|
2023-10-30 22:37:44 +00:00
|
|
|
Transparency: Double; // 0.0 ... 1.0
|
2023-10-22 08:33:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartLineSegment = record
|
|
|
|
Length: Double; // mm or % of linewidth
|
|
|
|
Count: Integer;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartLineStyle = class
|
|
|
|
Name: String;
|
|
|
|
Segment1: TsChartLineSegment;
|
|
|
|
Segment2: TsChartLineSegment;
|
|
|
|
Distance: Double; // mm or % of linewidth
|
|
|
|
RelativeToLineWidth: Boolean;
|
|
|
|
function GetID: String;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartLineStyleList = class(TFPObjectList)
|
|
|
|
private
|
|
|
|
function GetItem(AIndex: Integer): TsChartLineStyle;
|
|
|
|
procedure SetItem(AIndex: Integer; AValue: TsChartLineStyle);
|
|
|
|
public
|
|
|
|
function Add(AName: String;
|
|
|
|
ASeg1Length: Double; ASeg1Count: Integer;
|
|
|
|
ASeg2Length: Double; ASeg2Count: Integer;
|
|
|
|
ADistance: Double; ARelativeToLineWidth: Boolean): Integer;
|
|
|
|
property Items[AIndex: Integer]: TsChartLineStyle read GetItem write SetItem; default;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartElement = class
|
|
|
|
private
|
|
|
|
FChart: TsChart;
|
|
|
|
FVisible: Boolean;
|
|
|
|
public
|
|
|
|
constructor Create(AChart: TsChart);
|
|
|
|
property Chart: TsChart read FChart;
|
|
|
|
property Visible: Boolean read FVisible write FVisible;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartFillElement = class(TsChartElement)
|
|
|
|
private
|
|
|
|
FBackground: TsChartFill;
|
|
|
|
FBorder: TsChartLine;
|
|
|
|
public
|
|
|
|
constructor Create(AChart: TsChart);
|
2023-10-23 09:28:05 +00:00
|
|
|
destructor Destroy; override;
|
2023-10-22 08:33:55 +00:00
|
|
|
property Background: TsChartFill read FBackground write FBackground;
|
|
|
|
property Border: TsChartLine read FBorder write FBorder;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartText = class(TsChartFillElement)
|
|
|
|
private
|
|
|
|
FCaption: String;
|
2023-10-27 17:45:33 +00:00
|
|
|
FRotationAngle: Integer;
|
2023-10-22 08:33:55 +00:00
|
|
|
FShowCaption: Boolean;
|
|
|
|
FFont: TsFont;
|
|
|
|
public
|
|
|
|
constructor Create(AChart: TsChart);
|
|
|
|
destructor Destroy; override;
|
|
|
|
property Caption: String read FCaption write FCaption;
|
|
|
|
property Font: TsFont read FFont write FFont;
|
|
|
|
property ShowCaption: Boolean read FShowCaption write FShowCaption;
|
2023-10-27 17:45:33 +00:00
|
|
|
property RotationAngle: Integer read FRotationAngle write FRotationAngle;
|
2023-10-22 08:33:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartAxisPosition = (capStart, capEnd, capValue);
|
2023-10-29 21:33:39 +00:00
|
|
|
TsChartAxisTick = (catInside, catOutside);
|
|
|
|
TsChartAxisTicks = set of TsChartAxisTick;
|
2023-10-30 22:37:44 +00:00
|
|
|
TsChartType = (ctEmpty, ctBar, ctLine, ctArea, ctBarLine, ctScatter, ctBubble,
|
|
|
|
ctRadar, ctFilledRadar, ctPie, ctRing);
|
2023-10-22 08:33:55 +00:00
|
|
|
|
2023-10-23 18:21:54 +00:00
|
|
|
TsChartAxis = class(TsChartFillElement)
|
2023-10-22 08:33:55 +00:00
|
|
|
private
|
|
|
|
FAutomaticMax: Boolean;
|
|
|
|
FAutomaticMin: Boolean;
|
|
|
|
FAutomaticMajorInterval: Boolean;
|
|
|
|
FAutomaticMinorSteps: Boolean;
|
|
|
|
FAxisLine: TsChartLine;
|
|
|
|
FMajorGridLines: TsChartLine;
|
|
|
|
FMinorGridLines: TsChartline;
|
|
|
|
FInverted: Boolean;
|
2023-10-23 18:21:54 +00:00
|
|
|
FCaption: String;
|
|
|
|
FCaptionFont: TsFont;
|
|
|
|
FCaptionRotation: Integer;
|
2023-10-22 08:33:55 +00:00
|
|
|
FLabelFont: TsFont;
|
|
|
|
FLabelFormat: String;
|
2023-11-03 22:36:00 +00:00
|
|
|
FLabelFormatPercent: String;
|
2023-10-23 18:21:54 +00:00
|
|
|
FLabelRotation: Integer;
|
2023-10-22 08:33:55 +00:00
|
|
|
FLogarithmic: Boolean;
|
|
|
|
FMajorInterval: Double;
|
2023-10-29 21:33:39 +00:00
|
|
|
FMajorTicks: TsChartAxisTicks;
|
2023-10-22 08:33:55 +00:00
|
|
|
FMax: Double;
|
|
|
|
FMin: Double;
|
|
|
|
FMinorSteps: Double;
|
2023-10-29 21:33:39 +00:00
|
|
|
FMinorTicks: TsChartAxisTicks;
|
2023-10-22 08:33:55 +00:00
|
|
|
FPosition: TsChartAxisPosition;
|
|
|
|
FPositionValue: Double;
|
2023-10-23 18:21:54 +00:00
|
|
|
FShowCaption: Boolean;
|
2023-10-22 08:33:55 +00:00
|
|
|
FShowLabels: Boolean;
|
|
|
|
public
|
|
|
|
constructor Create(AChart: TsChart);
|
|
|
|
destructor Destroy; override;
|
|
|
|
property AutomaticMax: Boolean read FAutomaticMax write FAutomaticMax;
|
|
|
|
property AutomaticMin: Boolean read FAutomaticMin write FAutomaticMin;
|
|
|
|
property AutomaticMajorInterval: Boolean read FAutomaticMajorInterval write FAutomaticMajorInterval;
|
|
|
|
property AutomaticMinorSteps: Boolean read FAutomaticMinorSteps write FAutomaticMinorSteps;
|
|
|
|
property AxisLine: TsChartLine read FAxisLine write FAxisLine;
|
2023-10-23 18:21:54 +00:00
|
|
|
property Caption: String read FCaption write FCaption;
|
|
|
|
property CaptionFont: TsFont read FCaptionFont write FCaptionFont;
|
|
|
|
property CaptionRotation: Integer read FCaptionRotation write FCaptionRotation;
|
2023-10-22 08:33:55 +00:00
|
|
|
property Inverted: Boolean read FInverted write FInverted;
|
|
|
|
property LabelFont: TsFont read FLabelFont write FLabelFont;
|
|
|
|
property LabelFormat: String read FLabelFormat write FLabelFormat;
|
2023-11-03 22:36:00 +00:00
|
|
|
property LabelFormatPercent: String read FLabelFormatPercent write FLabelFormatPercent;
|
2023-10-23 18:21:54 +00:00
|
|
|
property LabelRotation: Integer read FLabelRotation write FLabelRotation;
|
2023-10-22 08:33:55 +00:00
|
|
|
property Logarithmic: Boolean read FLogarithmic write FLogarithmic;
|
|
|
|
property MajorGridLines: TsChartLine read FMajorGridLines write FMajorGridLines;
|
|
|
|
property MajorInterval: Double read FMajorInterval write FMajorInterval;
|
2023-10-29 21:33:39 +00:00
|
|
|
property MajorTicks: TsChartAxisTicks read FMajorTicks write FMajorTicks;
|
2023-10-22 08:33:55 +00:00
|
|
|
property Max: Double read FMax write FMax;
|
|
|
|
property Min: Double read FMin write FMin;
|
2023-10-23 18:21:54 +00:00
|
|
|
property MinorGridLines: TsChartLine read FMinorGridLines write FMinorGridLines;
|
2023-10-22 08:33:55 +00:00
|
|
|
property MinorSteps: Double read FMinorSteps write FMinorSteps;
|
2023-10-29 21:33:39 +00:00
|
|
|
property MinorTicks: TsChartAxisTicks read FMinorTicks write FMinorTicks;
|
2023-10-22 08:33:55 +00:00
|
|
|
property Position: TsChartAxisPosition read FPosition write FPosition;
|
|
|
|
property PositionValue: Double read FPositionValue write FPositionValue;
|
2023-10-23 18:21:54 +00:00
|
|
|
property ShowCaption: Boolean read FShowCaption write FShowCaption;
|
2023-10-22 08:33:55 +00:00
|
|
|
property ShowLabels: Boolean read FShowLabels write FShowLabels;
|
|
|
|
end;
|
|
|
|
|
2023-10-26 21:21:51 +00:00
|
|
|
TsChartLegendPosition = (lpRight, lpTop, lpBottom, lpLeft);
|
|
|
|
|
2023-10-23 22:18:31 +00:00
|
|
|
TsChartLegend = class(TsChartFillElement)
|
|
|
|
private
|
|
|
|
FFont: TsFont;
|
2023-10-26 11:30:36 +00:00
|
|
|
FCanOverlapPlotArea: Boolean;
|
2023-10-26 21:21:51 +00:00
|
|
|
FPosition: TsChartLegendPosition;
|
2023-10-23 22:18:31 +00:00
|
|
|
public
|
|
|
|
constructor Create(AChart: TsChart);
|
|
|
|
destructor Destroy; override;
|
2023-10-26 11:30:36 +00:00
|
|
|
property CanOverlapPlotArea: Boolean read FCanOverlapPlotArea write FCanOverlapPlotArea;
|
2023-10-23 22:18:31 +00:00
|
|
|
property Font: TsFont read FFont write FFont;
|
2023-10-26 21:21:51 +00:00
|
|
|
property Position: TsChartLegendPosition read FPosition write FPosition;
|
2023-10-30 14:37:53 +00:00
|
|
|
// There is also a "legend-expansion" but this does not seem to have a visual effect in Calc.
|
2023-10-22 08:33:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartAxisLink = (alPrimary, alSecondary);
|
2023-10-30 14:37:53 +00:00
|
|
|
TsChartDataLabel = (cdlValue, cdlPercentage, cdlValueAndPercentage, cdlCategory, cdlSeriesName, cdlSymbol);
|
|
|
|
TsChartDataLabels = set of TsChartDataLabel;
|
2023-10-30 17:41:53 +00:00
|
|
|
TsChartLabelPosition = (lpDefault, lpOutside, lpInside, lpCenter);
|
2023-10-22 08:33:55 +00:00
|
|
|
|
|
|
|
TsChartSeries = class(TsChartElement)
|
|
|
|
private
|
|
|
|
FChartType: TsChartType;
|
|
|
|
FXRange: TsCellRange; // cell range containing the x data
|
|
|
|
FYRange: TsCellRange;
|
|
|
|
FLabelRange: TsCellRange;
|
2023-10-30 14:37:53 +00:00
|
|
|
FLabelFont: TsFont;
|
2023-10-30 17:41:53 +00:00
|
|
|
FLabelPosition: TsChartLabelPosition;
|
|
|
|
FLabelSeparator: string;
|
2023-10-29 15:52:46 +00:00
|
|
|
FFillColorRange: TsCellRange;
|
2023-10-22 08:33:55 +00:00
|
|
|
FYAxis: TsChartAxisLink;
|
|
|
|
FTitleAddr: TsCellCoord;
|
|
|
|
FLabelFormat: String;
|
2023-10-25 17:15:57 +00:00
|
|
|
FLine: TsChartLine;
|
|
|
|
FFill: TsChartFill;
|
2023-10-30 14:37:53 +00:00
|
|
|
FDataLabels: TsChartDataLabels;
|
2023-10-30 22:37:44 +00:00
|
|
|
protected
|
|
|
|
function GetChartType: TsChartType; virtual;
|
2023-10-22 08:33:55 +00:00
|
|
|
public
|
2023-10-27 17:45:33 +00:00
|
|
|
constructor Create(AChart: TsChart); virtual;
|
2023-10-25 17:15:57 +00:00
|
|
|
destructor Destroy; override;
|
2023-10-22 08:33:55 +00:00
|
|
|
function GetCount: Integer;
|
|
|
|
function GetXCount: Integer;
|
|
|
|
function GetYCount: Integer;
|
|
|
|
function HasLabels: Boolean;
|
|
|
|
function HasXValues: Boolean;
|
|
|
|
function HasYValues: Boolean;
|
|
|
|
procedure SetTitleAddr(ARow, ACol: Cardinal);
|
|
|
|
procedure SetLabelRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
|
|
|
procedure SetXRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
|
|
|
procedure SetYRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
2023-10-29 15:52:46 +00:00
|
|
|
procedure SetFillColorRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
2023-10-22 08:33:55 +00:00
|
|
|
function LabelsInCol: Boolean;
|
|
|
|
function XValuesInCol: Boolean;
|
|
|
|
function YValuesInCol: Boolean;
|
2023-10-27 22:28:13 +00:00
|
|
|
|
2023-10-30 22:37:44 +00:00
|
|
|
property ChartType: TsChartType read GetChartType;
|
2023-10-22 08:33:55 +00:00
|
|
|
property Count: Integer read GetCount;
|
2023-10-30 14:37:53 +00:00
|
|
|
property DataLabels: TsChartDataLabels read FDataLabels write FDataLabels;
|
2023-10-29 15:52:46 +00:00
|
|
|
property FillColorRange: TsCellRange read FFillColorRange;
|
2023-10-30 14:37:53 +00:00
|
|
|
property LabelFont: TsFont read FLabelFont write FLabelFont;
|
2023-10-22 08:33:55 +00:00
|
|
|
property LabelFormat: String read FLabelFormat write FLabelFormat; // Number format in Excel notation, e.g. '0.00'
|
2023-10-30 17:41:53 +00:00
|
|
|
property LabelPosition: TsChartLabelPosition read FLabelPosition write FLabelPosition;
|
2023-10-22 08:33:55 +00:00
|
|
|
property LabelRange: TsCellRange read FLabelRange;
|
2023-10-30 17:41:53 +00:00
|
|
|
property LabelSeparator: string read FLabelSeparator write FLabelSeparator;
|
|
|
|
property TitleAddr: TsCellCoord read FTitleAddr write FTitleAddr; // use '\n' for line-break
|
2023-10-22 08:33:55 +00:00
|
|
|
property XRange: TsCellRange read FXRange;
|
|
|
|
property YRange: TsCellRange read FYRange;
|
|
|
|
property YAxis: TsChartAxisLink read FYAxis write FYAxis;
|
2023-10-25 17:15:57 +00:00
|
|
|
|
|
|
|
property Fill: TsChartFill read FFill write FFill;
|
|
|
|
property Line: TsChartLine read FLine write FLine;
|
2023-10-22 08:33:55 +00:00
|
|
|
end;
|
2023-10-27 17:45:33 +00:00
|
|
|
TsChartSeriesClass = class of TsChartSeries;
|
2023-10-22 08:33:55 +00:00
|
|
|
|
2023-10-27 20:44:33 +00:00
|
|
|
TsAreaSeries = class(TsChartSeries)
|
|
|
|
public
|
|
|
|
constructor Create(AChart: TsChart); override;
|
|
|
|
end;
|
|
|
|
|
2023-10-26 22:00:07 +00:00
|
|
|
TsBarSeries = class(TsChartSeries)
|
|
|
|
public
|
2023-10-27 17:45:33 +00:00
|
|
|
constructor Create(AChart: TsChart); override;
|
2023-10-26 22:00:07 +00:00
|
|
|
end;
|
|
|
|
|
2023-10-28 12:07:10 +00:00
|
|
|
TsBubbleSeries = class(TsChartSeries)
|
|
|
|
private
|
|
|
|
FBubbleRange: TsCellRange;
|
|
|
|
public
|
|
|
|
constructor Create(AChart: TsChart); override;
|
|
|
|
procedure SetBubbleRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
|
|
|
property BubbleRange: TsCellRange read FBubbleRange;
|
|
|
|
end;
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
TsChartSeriesSymbol = (
|
2023-10-23 00:03:45 +00:00
|
|
|
cssRect, cssDiamond, cssTriangle, cssTriangleDown, cssTriangleLeft,
|
|
|
|
cssTriangleRight, cssCircle, cssStar, cssX, cssPlus, cssAsterisk
|
2023-10-22 08:33:55 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
TsLineSeries = class(TsChartSeries)
|
|
|
|
private
|
|
|
|
FSymbol: TsChartSeriesSymbol;
|
|
|
|
FSymbolHeight: Double; // in mm
|
|
|
|
FSymbolWidth: Double; // in mm
|
2023-10-27 22:28:13 +00:00
|
|
|
FShowLines: Boolean;
|
2023-10-25 17:15:57 +00:00
|
|
|
FShowSymbols: Boolean;
|
2023-10-27 22:28:13 +00:00
|
|
|
FBorder: TsChartLine;
|
2023-10-25 17:15:57 +00:00
|
|
|
function GetSymbolFill: TsChartFill;
|
|
|
|
procedure SetSymbolFill(Value: TsChartFill);
|
2023-10-22 08:33:55 +00:00
|
|
|
public
|
2023-10-27 17:45:33 +00:00
|
|
|
constructor Create(AChart: TsChart); override;
|
2023-10-27 22:28:13 +00:00
|
|
|
destructor Destroy; override;
|
2023-10-22 08:33:55 +00:00
|
|
|
property Symbol: TsChartSeriesSymbol read FSymbol write FSymbol;
|
2023-10-27 22:28:13 +00:00
|
|
|
property SymbolBorder: TsChartLine read FBorder write FBorder;
|
2023-10-25 17:15:57 +00:00
|
|
|
property SymbolFill: TsChartFill read GetSymbolFill write SetSymbolFill;
|
2023-10-22 08:33:55 +00:00
|
|
|
property SymbolHeight: double read FSymbolHeight write FSymbolHeight;
|
|
|
|
property SymbolWidth: double read FSymbolWidth write FSymbolWidth;
|
2023-10-27 22:28:13 +00:00
|
|
|
property ShowLines: Boolean read FShowLines write FShowLines;
|
2023-10-25 17:15:57 +00:00
|
|
|
property ShowSymbols: Boolean read FShowSymbols write FShowSymbols;
|
2023-10-22 08:33:55 +00:00
|
|
|
end;
|
|
|
|
|
2023-10-30 17:41:53 +00:00
|
|
|
TsPieSeries = class(TsChartSeries)
|
|
|
|
public
|
|
|
|
constructor Create(AChart: TsChart); override;
|
|
|
|
end;
|
|
|
|
|
2023-10-30 14:56:16 +00:00
|
|
|
TsRadarSeries = class(TsLineSeries)
|
2023-10-30 22:37:44 +00:00
|
|
|
protected
|
|
|
|
function GetChartType: TsChartType; override;
|
2023-10-30 14:56:16 +00:00
|
|
|
end;
|
|
|
|
|
2023-10-30 17:41:53 +00:00
|
|
|
TsRingSeries = class(TsChartSeries)
|
|
|
|
public
|
|
|
|
constructor Create(AChart: TsChart); override;
|
|
|
|
end;
|
|
|
|
|
2023-11-03 18:56:15 +00:00
|
|
|
TsRegressionType = (rtNone, rtLinear, rtLogarithmic, rtExponential, rtPower, rtPolynomial);
|
|
|
|
|
|
|
|
TsRegressionEquation = class
|
|
|
|
Fill: TsChartFill;
|
|
|
|
Font: TsFont;
|
|
|
|
Border: TsChartLine;
|
|
|
|
NumberFormat: String;
|
|
|
|
Left, Top: Double; // mm, relative to outer chart boundaries!
|
|
|
|
XName: String;
|
|
|
|
YName: String;
|
|
|
|
constructor Create;
|
|
|
|
destructor Destroy; override;
|
|
|
|
function DefaultBorder: Boolean;
|
|
|
|
function DefaultFill: Boolean;
|
|
|
|
function DefaultFont: Boolean;
|
|
|
|
function DefaultNumberFormat: Boolean;
|
|
|
|
function DefaultPosition: Boolean;
|
|
|
|
function DefaultXName: Boolean;
|
|
|
|
function DefaultYName: Boolean;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartRegression = class
|
|
|
|
Title: String;
|
|
|
|
RegressionType: TsRegressionType;
|
|
|
|
ExtrapolateForwardBy: Double;
|
|
|
|
ExtrapolateBackwardBy: Double;
|
|
|
|
ForceYIntercept: Boolean;
|
|
|
|
YInterceptValue: Double;
|
|
|
|
PolynomialDegree: Integer;
|
|
|
|
DisplayEquation: Boolean;
|
|
|
|
DisplayRSquare: Boolean;
|
|
|
|
Equation: TsRegressionEquation;
|
|
|
|
Line: TsChartLine;
|
|
|
|
constructor Create;
|
|
|
|
destructor Destroy; override;
|
|
|
|
end;
|
|
|
|
|
2023-10-27 21:24:32 +00:00
|
|
|
TsScatterSeries = class(TsLineSeries)
|
2023-11-03 18:56:15 +00:00
|
|
|
private
|
|
|
|
FRegression: TsChartRegression;
|
2023-10-27 21:24:32 +00:00
|
|
|
public
|
|
|
|
constructor Create(AChart: TsChart); override;
|
2023-11-03 18:56:15 +00:00
|
|
|
destructor Destroy; override;
|
|
|
|
property Regression: TsChartRegression read FRegression write FRegression;
|
2023-10-27 21:24:32 +00:00
|
|
|
end;
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
TsChartSeriesList = class(TFPList)
|
|
|
|
private
|
|
|
|
function GetItem(AIndex: Integer): TsChartSeries;
|
|
|
|
procedure SetItem(AIndex: Integer; AValue: TsChartSeries);
|
|
|
|
public
|
|
|
|
property Items[AIndex: Integer]: TsChartSeries read GetItem write SetItem; default;
|
|
|
|
end;
|
|
|
|
|
2023-10-27 22:28:13 +00:00
|
|
|
TsChartStackMode = (csmSideBySide, csmStacked, csmStackedPercentage);
|
|
|
|
TsChartInterpolation = (
|
|
|
|
ciLinear,
|
|
|
|
ciCubicSpline, ciBSpline,
|
|
|
|
ciStepStart, ciStepEnd, ciStepCenterX, ciStepCenterY
|
|
|
|
);
|
2023-10-27 20:44:33 +00:00
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
TsChart = class(TsChartFillElement)
|
|
|
|
private
|
|
|
|
FIndex: Integer; // Index in workbook's chart list
|
|
|
|
FSheetIndex: Integer;
|
|
|
|
FRow, FCol: Cardinal;
|
|
|
|
FOffsetX, FOffsetY: Double;
|
|
|
|
FWidth, FHeight: Double; // Width, Height of the chart, in mm.
|
|
|
|
|
|
|
|
FPlotArea: TsChartFillElement;
|
|
|
|
FFloor: TsChartFillElement;
|
|
|
|
FXAxis: TsChartAxis;
|
|
|
|
FX2Axis: TsChartAxis;
|
|
|
|
FYAxis: TsChartAxis;
|
|
|
|
FY2Axis: TsChartAxis;
|
|
|
|
|
2023-10-27 22:28:13 +00:00
|
|
|
FRotatedAxes: Boolean; // For bar series: vertical columns <--> horizontal bars
|
|
|
|
FStackMode: TsChartStackMode; // For bar and area series
|
|
|
|
FInterpolation: TsChartInterpolation; // For line/scatter series: data connection lines
|
2023-10-27 20:09:03 +00:00
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
FTitle: TsChartText;
|
|
|
|
FSubTitle: TsChartText;
|
|
|
|
FLegend: TsChartLegend;
|
|
|
|
FSeriesList: TsChartSeriesList;
|
|
|
|
|
|
|
|
FLineStyles: TsChartLineStyleList;
|
2023-11-05 00:26:04 +00:00
|
|
|
FGradients: TsChartGradientList;
|
2023-10-22 08:33:55 +00:00
|
|
|
function GetCategoryLabelRange: TsCellRange;
|
|
|
|
|
|
|
|
public
|
|
|
|
constructor Create;
|
|
|
|
destructor Destroy; override;
|
|
|
|
function AddSeries(ASeries: TsChartSeries): Integer;
|
|
|
|
procedure DeleteSeries(AIndex: Integer);
|
|
|
|
|
|
|
|
function GetChartType: TsChartType;
|
|
|
|
function GetLineStyle(AIndex: Integer): TsChartLineStyle;
|
|
|
|
function IsScatterChart: Boolean;
|
|
|
|
function NumLineStyles: Integer;
|
2023-10-27 22:28:13 +00:00
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
{ Index of chart in workbook's chart list. }
|
|
|
|
property Index: Integer read FIndex write FIndex;
|
|
|
|
{ Index of worksheet sheet which contains the chart. }
|
|
|
|
property SheetIndex: Integer read FSheetIndex write FSheetIndex;
|
|
|
|
{ Row index of the cell in which the chart has its top/left corner (anchor) }
|
|
|
|
property Row: Cardinal read FRow write FRow;
|
|
|
|
{ Column index of the cell in which the chart has its top/left corner (anchor) }
|
|
|
|
property Col: Cardinal read FCol write FCol;
|
|
|
|
{ Offset of the left chart edge relative to the anchor cell, in mm }
|
|
|
|
property OffsetX: double read FOffsetX write FOffsetX;
|
|
|
|
{ Offset of the top chart edge relative to the anchor cell, in mm }
|
|
|
|
property OffsetY: double read FOffsetY write FOffsetY;
|
|
|
|
{ Width of the chart, in mm }
|
|
|
|
property Width: double read FWidth write FWidth;
|
|
|
|
{ Height of the chart, in mm }
|
|
|
|
property Height: double read FHeight write FHeight;
|
|
|
|
|
2023-10-23 00:03:45 +00:00
|
|
|
{ Attributes of the entire chart background }
|
|
|
|
property Background: TsChartFill read FBackground write FBackground;
|
|
|
|
property Border: TsChartLine read FBorder write FBorder;
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
{ Attributes of the plot area (rectangle enclosed by axes) }
|
|
|
|
property PlotArea: TsChartFillElement read FPlotArea write FPlotArea;
|
|
|
|
{ Attributes of the floor of a 3D chart }
|
|
|
|
property Floor: TsChartFillElement read FFloor write FFloor;
|
|
|
|
|
|
|
|
{ Attributes of the chart's title }
|
|
|
|
property Title: TsChartText read FTitle write FTitle;
|
|
|
|
{ Attributes of the chart's subtitle }
|
|
|
|
property Subtitle: TsChartText read FSubtitle write FSubTitle;
|
|
|
|
{ Attributs of the chart's legend }
|
|
|
|
property Legend: TsChartLegend read FLegend write FLegend;
|
|
|
|
|
|
|
|
{ Attributes of the plot's primary x axis (bottom) }
|
|
|
|
property XAxis: TsChartAxis read FXAxis write FXAxis;
|
|
|
|
{ Attributes of the plot's secondary x axis (top) }
|
|
|
|
property X2Axis: TsChartAxis read FX2Axis write FX2Axis;
|
|
|
|
{ Attributes of the plot's primary y axis (left) }
|
|
|
|
property YAxis: TsChartAxis read FYAxis write FYAxis;
|
|
|
|
{ Attributes of the plot's secondary y axis (right) }
|
|
|
|
property Y2Axis: TsChartAxis read FY2Axis write FY2Axis;
|
2023-10-27 20:44:33 +00:00
|
|
|
|
2023-10-27 22:28:13 +00:00
|
|
|
{ Connecting line between data points (for line and scatter series) }
|
|
|
|
property Interpolation: TsChartInterpolation read FInterpolation write FInterpolation;
|
2023-10-28 12:07:10 +00:00
|
|
|
{ x and y axes exchanged (mainly for bar series, but works also for scatter and bubble series) }
|
2023-10-27 20:09:03 +00:00
|
|
|
property RotatedAxes: Boolean read FRotatedAxes write FRotatedAxes;
|
2023-10-27 22:28:13 +00:00
|
|
|
{ Stacking of series (for bar and area series ) }
|
2023-10-27 20:44:33 +00:00
|
|
|
property StackMode: TsChartStackMode read FStackMode write FStackMode;
|
2023-10-22 08:33:55 +00:00
|
|
|
|
|
|
|
property CategoryLabelRange: TsCellRange read GetCategoryLabelRange;
|
|
|
|
|
|
|
|
{ Attributes of the series }
|
|
|
|
property Series: TsChartSeriesList read FSeriesList write FSeriesList;
|
2023-11-05 00:26:04 +00:00
|
|
|
|
|
|
|
{ Style lists }
|
|
|
|
property LineStyles: TsChartLineStyleList read FLineStyles;
|
|
|
|
property Gradients: TsChartGradientList read FGradients;
|
2023-10-22 08:33:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
TsChartList = class(TObjectList)
|
|
|
|
private
|
|
|
|
function GetItem(AIndex: Integer): TsChart;
|
|
|
|
procedure SetItem(AIndex: Integer; AValue: TsChart);
|
|
|
|
public
|
|
|
|
property Items[AIndex: Integer]: TsChart read GetItem write SetItem; default;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
2023-11-05 00:26:04 +00:00
|
|
|
{ TsChartGradient }
|
|
|
|
|
|
|
|
constructor TsChartGradient.Create;
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
StartIntensity := 1.0;
|
|
|
|
EndIntensity := 1.0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{ TsChartGradientList }
|
|
|
|
|
|
|
|
function TsChartGradientList.AddAxialGradient(AName: String;
|
|
|
|
AStartColor, AEndColor: TsColor; AStartIntensity, AEndIntensity, ABorder: Double;
|
|
|
|
AAngle: Integer): Integer;
|
|
|
|
begin
|
|
|
|
Result := AddGradient(AName, cgsAxial, AStartColor, AEndColor,
|
|
|
|
AStartIntensity, AEndIntensity, ABorder, 0.0, 0.0, AAngle);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartGradientList.AddEllipticGradient(AName: String;
|
|
|
|
AStartColor, AEndColor: TsColor; AStartIntensity, AEndIntensity: Double;
|
|
|
|
ABorder, ACenterX, ACenterY: Double; AAngle: Integer): Integer;
|
|
|
|
begin
|
|
|
|
Result := AddGradient(AName, cgsElliptic, AStartColor, AEndColor,
|
|
|
|
AStartIntensity, AEndIntensity, ABorder, ACenterX, ACenterY, AAngle);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartGradientList.AddGradient(AName: String; AStyle: TsChartGradientStyle;
|
|
|
|
AStartColor, AEndColor: TsColor; AStartIntensity, AEndIntensity: Double;
|
|
|
|
ABorder, ACenterX, ACenterY: Double; AAngle: Integer): Integer;
|
|
|
|
var
|
|
|
|
item: TsChartGradient;
|
|
|
|
begin
|
|
|
|
if AName = '' then
|
|
|
|
AName := 'G' + IntToStr(Count+1);
|
|
|
|
Result := IndexOfName(AName);
|
|
|
|
if Result = -1 then
|
|
|
|
begin
|
|
|
|
item := TsChartGradient.Create;
|
|
|
|
Result := inherited Add(item);
|
|
|
|
end else
|
|
|
|
item := Items[Result];
|
|
|
|
item.Name := AName;
|
|
|
|
item.Style := AStyle;
|
|
|
|
item.StartColor := AStartColor;
|
|
|
|
item.EndColor := AEndColor;
|
|
|
|
item.StartIntensity := AStartIntensity;
|
|
|
|
item.EndIntensity := AEndIntensity;
|
|
|
|
item.Border := ABorder;
|
|
|
|
item.Angle := AAngle;
|
|
|
|
item.CenterX := ACenterX;
|
|
|
|
item.CenterY := ACenterY;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartGradientList.AddLinearGradient(AName: String;
|
|
|
|
AStartColor, AEndColor: TsColor; AStartIntensity, AEndIntensity, ABorder: Double;
|
|
|
|
AAngle: Integer): Integer;
|
|
|
|
begin
|
|
|
|
Result := AddGradient(AName, cgsLinear, AStartColor, AEndColor,
|
|
|
|
AStartIntensity, AEndIntensity, ABorder, 0.0, 0.0, AAngle);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartGradientList.AddRadialGradient(AName: String;
|
|
|
|
AStartColor, AEndColor: TsColor; AStartIntensity, AEndIntensity, ABorder: Double;
|
|
|
|
ACenterX, ACenterY: Double): Integer;
|
|
|
|
begin
|
|
|
|
Result := AddGradient(AName, cgsRadial, AStartColor, AEndColor,
|
|
|
|
AStartIntensity, AEndIntensity, ABorder, ACenterX, ACenterY, 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartGradientList.AddRectangularGradient(AName: String;
|
|
|
|
AStartColor, AEndColor: TsColor; AStartIntensity, AEndIntensity: Double;
|
|
|
|
ABorder, ACenterX, ACenterY: Double; AAngle: Integer): Integer;
|
|
|
|
begin
|
|
|
|
Result := AddGradient(AName, cgsRectangular, AStartColor, AEndColor,
|
|
|
|
AStartIntensity, AEndIntensity, ABorder, ACenterX, ACenterY, AAngle);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartGradientList.AddSquareGradient(AName: String;
|
|
|
|
AStartColor, AEndColor: TsColor; AStartIntensity, AEndIntensity: Double;
|
|
|
|
ABorder, ACenterX, ACenterY: Double; AAngle: Integer): Integer;
|
|
|
|
begin
|
|
|
|
Result := AddGradient(AName, cgsSquare, AStartColor, AEndColor,
|
|
|
|
AStartIntensity, AEndIntensity, ABorder, ACenterX, ACenterY, AAngle);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartGradientList.FindByName(AName: String): TsChartGradient;
|
|
|
|
var
|
|
|
|
idx: Integer;
|
|
|
|
begin
|
|
|
|
idx := IndexOfName(AName);
|
|
|
|
if idx > -1 then
|
|
|
|
Result := Items[idx]
|
|
|
|
else
|
|
|
|
Result := nil;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartGradientList.GetItem(AIndex: Integer): TsChartGradient;
|
|
|
|
begin
|
|
|
|
Result := TsChartGradient(inherited Items[AIndex]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartGradientList.IndexOfName(AName: String): Integer;
|
|
|
|
begin
|
|
|
|
for Result := 0 to Count-1 do
|
|
|
|
if SameText(Items[Result].Name, AName) then
|
|
|
|
exit;
|
|
|
|
Result := -1;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsChartGradientList.SetItem(AIndex: Integer; AValue: TsChartGradient);
|
|
|
|
begin
|
|
|
|
inherited Items[AIndex] := AValue;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
{ TsChartLineStyle }
|
|
|
|
|
|
|
|
function TsChartLineStyle.GetID: String;
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
begin
|
|
|
|
Result := Name;
|
|
|
|
for i:=1 to Length(Result) do
|
|
|
|
if Result[i] in [' ', '-'] then Result[i] := '_';
|
|
|
|
Result := 'FPS' + Result;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{ TsChartLineStyleList }
|
|
|
|
|
|
|
|
function TsChartLineStyleList.Add(AName: String;
|
|
|
|
ASeg1Length: Double; ASeg1Count: Integer;
|
|
|
|
ASeg2Length: Double; ASeg2Count: Integer;
|
|
|
|
ADistance: Double; ARelativeToLineWidth: Boolean): Integer;
|
|
|
|
var
|
|
|
|
ls: TsChartLineStyle;
|
|
|
|
begin
|
|
|
|
ls := TsChartLineStyle.Create;
|
|
|
|
ls.Name := AName;
|
|
|
|
ls.Segment1.Count := ASeg1Count;
|
|
|
|
ls.Segment1.Length := ASeg1Length;
|
|
|
|
ls.Segment2.Count := ASeg2Count;
|
|
|
|
ls.Segment2.Length := ASeg2Length;
|
|
|
|
ls.Distance := ADistance;
|
|
|
|
ls.RelativeToLineWidth := ARelativeToLineWidth;
|
|
|
|
result := inherited Add(ls);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartLineStyleList.GetItem(AIndex: Integer): TsChartLineStyle;
|
|
|
|
begin
|
|
|
|
Result := TsChartLineStyle(inherited);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsChartLineStyleList.SetItem(AIndex: Integer; AValue: TsChartLineStyle);
|
|
|
|
begin
|
|
|
|
inherited Items[AIndex] := AValue;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{ TsChartElement }
|
|
|
|
|
|
|
|
constructor TsChartElement.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
FChart := AChart;
|
|
|
|
FVisible := true;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{ TsChartFillElement }
|
|
|
|
|
|
|
|
constructor TsChartFillElement.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Create(AChart);
|
2023-10-23 09:28:05 +00:00
|
|
|
FBackground := TsChartFill.Create;
|
2023-11-05 00:26:04 +00:00
|
|
|
FBackground.Style := cfsSolid;
|
2023-10-22 08:33:55 +00:00
|
|
|
FBackground.BgColor := scWhite;
|
|
|
|
FBackground.FgColor := scWhite;
|
2023-11-05 00:26:04 +00:00
|
|
|
FBackground.Gradient := -1;
|
2023-10-23 09:28:05 +00:00
|
|
|
FBorder := TsChartLine.Create;
|
2023-10-22 08:33:55 +00:00
|
|
|
FBorder.Style := clsSolid;
|
2023-10-23 22:18:31 +00:00
|
|
|
FBorder.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
2023-10-22 08:33:55 +00:00
|
|
|
FBorder.Color := scBlack;
|
|
|
|
end;
|
|
|
|
|
2023-10-23 09:28:05 +00:00
|
|
|
destructor TsChartFillElement.Destroy;
|
|
|
|
begin
|
|
|
|
FBorder.Free;
|
|
|
|
FBackground.Free;
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
|
|
|
|
{ TsChartText }
|
|
|
|
|
|
|
|
constructor TsChartText.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Create(AChart);
|
|
|
|
FShowCaption := true;
|
|
|
|
FFont := TsFont.Create;
|
2023-10-23 18:21:54 +00:00
|
|
|
FFont.Size := 10;
|
2023-10-22 08:33:55 +00:00
|
|
|
FFont.Style := [];
|
|
|
|
FFont.Color := scBlack;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TsChartText.Destroy;
|
|
|
|
begin
|
|
|
|
FFont.Free;
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{ TsChartAxis }
|
|
|
|
|
|
|
|
constructor TsChartAxis.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Create(AChart);
|
|
|
|
|
2023-10-29 18:36:13 +00:00
|
|
|
FAutomaticMin := true;
|
|
|
|
FAutomaticMax := true;
|
2023-10-22 08:33:55 +00:00
|
|
|
FAutomaticMajorInterval := true;
|
|
|
|
FAutomaticMinorSteps := true;
|
|
|
|
|
2023-10-23 18:21:54 +00:00
|
|
|
FCaptionFont := TsFont.Create;
|
|
|
|
FCaptionFont.Size := 10;
|
|
|
|
FCaptionFont.Style := [];
|
|
|
|
FCaptionFont.Color := scBlack;
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
FLabelFont := TsFont.Create;
|
2023-10-23 18:21:54 +00:00
|
|
|
FLabelFont.Size := 9;
|
2023-10-22 08:33:55 +00:00
|
|
|
FLabelFont.Style := [];
|
|
|
|
FLabelFont.Color := scBlack;
|
|
|
|
|
2023-11-03 22:36:00 +00:00
|
|
|
FLabelFormatPercent := '0%';
|
|
|
|
|
2023-10-23 18:21:54 +00:00
|
|
|
FCaptionRotation := 0;
|
|
|
|
FLabelRotation := 0;
|
|
|
|
|
|
|
|
FShowCaption := true;
|
2023-10-22 08:33:55 +00:00
|
|
|
FShowLabels := true;
|
|
|
|
|
2023-10-23 09:28:05 +00:00
|
|
|
FAxisLine := TsChartLine.Create;
|
2023-10-22 08:33:55 +00:00
|
|
|
FAxisLine.Color := scBlack;
|
|
|
|
FAxisLine.Style := clsSolid;
|
2023-10-23 22:18:31 +00:00
|
|
|
FAxisLine.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
2023-10-22 08:33:55 +00:00
|
|
|
|
2023-10-29 21:33:39 +00:00
|
|
|
FMajorTicks := [catOutside];
|
|
|
|
FMinorTicks := [];
|
2023-10-22 08:33:55 +00:00
|
|
|
|
2023-10-23 09:28:05 +00:00
|
|
|
FMajorGridLines := TsChartLine.Create;
|
2023-10-22 08:33:55 +00:00
|
|
|
FMajorGridLines.Color := scSilver;
|
|
|
|
FMajorGridLines.Style := clsSolid;
|
2023-10-23 22:18:31 +00:00
|
|
|
FMajorGridLines.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
2023-10-22 08:33:55 +00:00
|
|
|
|
2023-10-23 09:28:05 +00:00
|
|
|
FMinorGridLines := TsChartLine.Create;
|
2023-10-22 08:33:55 +00:00
|
|
|
FMinorGridLines.Color := scSilver;
|
2023-10-25 17:15:57 +00:00
|
|
|
FMinorGridLines.Style := clsDash;
|
2023-10-23 22:18:31 +00:00
|
|
|
FMinorGridLines.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
2023-10-22 08:33:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TsChartAxis.Destroy;
|
|
|
|
begin
|
2023-10-23 09:28:05 +00:00
|
|
|
FMinorGridLines.Free;
|
|
|
|
FMajorGridLines.Free;
|
|
|
|
FAxisLine.Free;
|
2023-10-22 08:33:55 +00:00
|
|
|
FLabelFont.Free;
|
2023-10-23 18:21:54 +00:00
|
|
|
FCaptionFont.Free;
|
2023-10-22 08:33:55 +00:00
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2023-10-23 22:18:31 +00:00
|
|
|
{ TsChartLegend }
|
|
|
|
|
|
|
|
constructor TsChartLegend.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Create(AChart);
|
|
|
|
FFont := TsFont.Create;
|
|
|
|
FFont.Size := 9;
|
|
|
|
FVisible := true;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TsChartLegend.Destroy;
|
|
|
|
begin
|
|
|
|
FFont.Free;
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
{ TsChartSeries }
|
|
|
|
|
|
|
|
constructor TsChartSeries.Create(AChart: TsChart);
|
2023-10-25 17:15:57 +00:00
|
|
|
var
|
|
|
|
idx: Integer;
|
2023-10-22 08:33:55 +00:00
|
|
|
begin
|
|
|
|
inherited Create(AChart);
|
2023-10-25 17:15:57 +00:00
|
|
|
|
|
|
|
idx := AChart.AddSeries(self);
|
|
|
|
|
|
|
|
FFill := TsChartFill.Create;
|
2023-11-05 00:26:04 +00:00
|
|
|
FFill.Style := cfsSolid;
|
2023-10-25 17:15:57 +00:00
|
|
|
FFill.FgColor := DEFAULT_SERIES_COLORS[idx mod Length(DEFAULT_SERIES_COLORS)];
|
|
|
|
FFill.BgColor := DEFAULT_SERIES_COLORS[idx mod Length(DEFAULT_SERIES_COLORS)];
|
2023-11-05 00:26:04 +00:00
|
|
|
FFill.Gradient := -1;
|
2023-10-25 17:15:57 +00:00
|
|
|
|
|
|
|
FLine := TsChartLine.Create;
|
|
|
|
FLine.Style := clsSolid;
|
|
|
|
FLine.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
|
|
|
FLine.Color := DEFAULT_SERIES_COLORS[idx mod Length(DEFAULT_SERIES_COLORS)];
|
2023-10-30 14:37:53 +00:00
|
|
|
|
|
|
|
FLabelFont := TsFont.Create;
|
|
|
|
FLabelFont := TsFont.Create;
|
|
|
|
FLabelFont.Size := 9;
|
2023-10-25 17:15:57 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TsChartSeries.Destroy;
|
|
|
|
begin
|
2023-10-30 14:37:53 +00:00
|
|
|
FLabelFont.Free;
|
2023-10-25 17:15:57 +00:00
|
|
|
FLine.Free;
|
|
|
|
FFill.Free;
|
|
|
|
inherited;
|
2023-10-22 08:33:55 +00:00
|
|
|
end;
|
|
|
|
|
2023-10-30 22:37:44 +00:00
|
|
|
function TsChartSeries.GetChartType: TsChartType;
|
|
|
|
begin
|
|
|
|
Result := FChartType;
|
|
|
|
end;
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
function TsChartSeries.GetCount: Integer;
|
|
|
|
begin
|
|
|
|
Result := GetYCount;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartSeries.GetXCount: Integer;
|
|
|
|
begin
|
|
|
|
if (FXRange.Row1 = FXRange.Row2) and (FXRange.Col1 = FXRange.Col2) then
|
|
|
|
Result := 0
|
|
|
|
else
|
|
|
|
if (FXRange.Row1 = FXRange.Row2) then
|
|
|
|
Result := FXRange.Col2 - FXRange.Col1 + 1
|
|
|
|
else
|
|
|
|
Result := FXRange.Row2 - FXRange.Row1 + 1;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartSeries.GetYCount: Integer;
|
|
|
|
begin
|
|
|
|
if YValuesInCol then
|
|
|
|
Result := FYRange.Row2 - FYRange.Row1 + 1
|
|
|
|
else
|
|
|
|
Result := FYRange.Col2 - FYRange.Col1 + 1;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartSeries.HasLabels: Boolean;
|
|
|
|
begin
|
|
|
|
Result := not ((FLabelRange.Row1 = FLabelRange.Row2) and (FLabelRange.Col1 = FLabelRange.Col2));
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartSeries.HasXValues: Boolean;
|
|
|
|
begin
|
|
|
|
Result := not ((FXRange.Row1 = FXRange.Row2) and (FXRange.Col1 = FXRange.Col2));
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartSeries.HasYValues: Boolean;
|
|
|
|
begin
|
|
|
|
Result := not ((FYRange.Row1 = FYRange.Row2) and (FYRange.Col1 = FYRange.Col2));
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartSeries.LabelsInCol: Boolean;
|
|
|
|
begin
|
|
|
|
Result := (FLabelRange.Col1 = FLabelRange.Col2) and (FLabelRange.Row1 <> FLabelRange.Row2);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsChartSeries.SetTitleAddr(ARow, ACol: Cardinal);
|
|
|
|
begin
|
|
|
|
FTitleAddr.Row := ARow;
|
|
|
|
FTitleAddr.Col := ACol;
|
|
|
|
end;
|
|
|
|
|
2023-10-29 15:52:46 +00:00
|
|
|
procedure TsChartSeries.SetFillColorRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
|
|
|
begin
|
|
|
|
if (ARow1 <> ARow2) and (ACol1 <> ACol2) then
|
|
|
|
raise Exception.Create('Series fill color values can only be located in a single column or row.');
|
|
|
|
FFillColorRange.Row1 := ARow1;
|
|
|
|
FFillColorRange.Col1 := ACol1;
|
|
|
|
FFillColorRange.Row2 := ARow2;
|
|
|
|
FFillColorRange.Col2 := ACol2;
|
|
|
|
end;
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
procedure TsChartSeries.SetLabelRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
|
|
|
begin
|
|
|
|
if (ARow1 <> ARow2) and (ACol1 <> ACol2) then
|
|
|
|
raise Exception.Create('Series labels can only be located in a single column or row.');
|
|
|
|
FLabelRange.Row1 := ARow1;
|
|
|
|
FLabelRange.Col1 := ACol1;
|
|
|
|
FLabelRange.Row2 := ARow2;
|
|
|
|
FLabelRange.Col2 := ACol2;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsChartSeries.SetXRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
|
|
|
begin
|
|
|
|
if (ARow1 <> ARow2) and (ACol1 <> ACol2) then
|
|
|
|
raise Exception.Create('Series x values can only be located in a single column or row.');
|
|
|
|
FXRange.Row1 := ARow1;
|
|
|
|
FXRange.Col1 := ACol1;
|
|
|
|
FXRange.Row2 := ARow2;
|
|
|
|
FXRange.Col2 := ACol2;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsChartSeries.SetYRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
|
|
|
begin
|
|
|
|
if (ARow1 <> ARow2) and (ACol1 <> ACol2) then
|
|
|
|
raise Exception.Create('Series y values can only be located in a single column or row.');
|
|
|
|
FYRange.Row1 := ARow1;
|
|
|
|
FYRange.Col1 := ACol1;
|
|
|
|
FYRange.Row2 := ARow2;
|
|
|
|
FYRange.Col2 := ACol2;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartSeries.XValuesInCol: Boolean;
|
|
|
|
begin
|
|
|
|
Result := (FXRange.Col1 = FXRange.Col2) and (FXRange.Row1 <> FXRange.Row2);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChartSeries.YValuesInCol: Boolean;
|
|
|
|
begin
|
|
|
|
Result := (FYRange.Col1 = FYRange.Col2) and (FYRange.Row1 <> FYRange.Row2);
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{ TsChartSeriesList }
|
|
|
|
|
|
|
|
function TsChartSeriesList.GetItem(AIndex: Integer): TsChartSeries;
|
|
|
|
begin
|
|
|
|
Result := TsChartSeries(inherited Items[AIndex]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsChartSeriesList.SetItem(AIndex: Integer; AValue: TsChartSeries);
|
|
|
|
begin
|
|
|
|
inherited Items[AIndex] := AValue;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2023-10-27 20:44:33 +00:00
|
|
|
{ TsAreaSeries }
|
|
|
|
|
|
|
|
constructor TsAreaSeries.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Create(AChart);
|
|
|
|
FChartType := ctArea;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2023-10-26 22:00:07 +00:00
|
|
|
{ TsBarSeries }
|
|
|
|
|
|
|
|
constructor TsBarSeries.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Create(AChart);
|
|
|
|
FChartType := ctBar;
|
|
|
|
end;
|
|
|
|
|
2023-10-29 15:52:46 +00:00
|
|
|
|
2023-10-28 12:07:10 +00:00
|
|
|
{ TsBubbleSeries }
|
|
|
|
|
|
|
|
constructor TsBubbleSeries.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited;
|
|
|
|
FChartType := ctBubble;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsBubbleSeries.SetBubbleRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
|
|
|
begin
|
|
|
|
if (ARow1 <> ARow2) and (ACol1 <> ACol2) then
|
2023-10-29 15:52:46 +00:00
|
|
|
raise Exception.Create('Bubble series values can only be located in a single column or row.');
|
2023-10-28 12:07:10 +00:00
|
|
|
FBubbleRange.Row1 := ARow1;
|
|
|
|
FBubbleRange.Col1 := ACol1;
|
|
|
|
FBubbleRange.Row2 := ARow2;
|
|
|
|
FBubbleRange.Col2 := ACol2;
|
|
|
|
end;
|
2023-10-26 22:00:07 +00:00
|
|
|
|
2023-10-29 15:52:46 +00:00
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
{ TsLineSeries }
|
|
|
|
|
|
|
|
constructor TsLineSeries.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Create(AChart);
|
|
|
|
FChartType := ctLine;
|
2023-10-25 17:15:57 +00:00
|
|
|
FSymbolWidth := 2.5;
|
|
|
|
FSymbolHeight := 2.5;
|
2023-10-27 22:28:13 +00:00
|
|
|
FShowSymbols := false;
|
|
|
|
FShowLines := true;
|
|
|
|
|
|
|
|
FBorder := TsChartLine.Create;
|
|
|
|
FBorder.Style := clsSolid;
|
|
|
|
FBorder.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
|
|
|
FBorder.Color := scBlack;
|
2023-10-25 17:15:57 +00:00
|
|
|
end;
|
2023-10-22 08:33:55 +00:00
|
|
|
|
2023-10-27 22:28:13 +00:00
|
|
|
destructor TsLineSeries.Destroy;
|
2023-10-25 17:15:57 +00:00
|
|
|
begin
|
2023-10-27 22:28:13 +00:00
|
|
|
FBorder.Free;
|
|
|
|
inherited;
|
2023-10-25 17:15:57 +00:00
|
|
|
end;
|
2023-10-22 08:33:55 +00:00
|
|
|
|
2023-10-25 17:15:57 +00:00
|
|
|
function TsLineSeries.GetSymbolFill: TsChartFill;
|
|
|
|
begin
|
|
|
|
Result := FFill;
|
|
|
|
end;
|
2023-10-22 08:33:55 +00:00
|
|
|
|
2023-10-25 17:15:57 +00:00
|
|
|
procedure TsLineSeries.SetSymbolFill(Value: TsChartFill);
|
2023-10-23 09:28:05 +00:00
|
|
|
begin
|
2023-10-25 17:15:57 +00:00
|
|
|
FFill := Value;
|
2023-10-23 09:28:05 +00:00
|
|
|
end;
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
|
2023-10-30 17:41:53 +00:00
|
|
|
{ TsPieSeries }
|
|
|
|
constructor TsPieSeries.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Create(AChart);
|
|
|
|
FChartType := ctPie;
|
|
|
|
FLine.Color := scBlack;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2023-10-30 14:56:16 +00:00
|
|
|
{ TsRadarSeries }
|
2023-10-30 22:37:44 +00:00
|
|
|
function TsRadarSeries.GetChartType: TsChartType;
|
2023-10-30 14:56:16 +00:00
|
|
|
begin
|
2023-11-05 00:26:04 +00:00
|
|
|
if Fill.Style <> cfsNoFill then
|
2023-10-30 22:37:44 +00:00
|
|
|
Result := ctFilledRadar
|
|
|
|
else
|
|
|
|
Result := ctRadar;
|
2023-10-30 14:56:16 +00:00
|
|
|
end;
|
|
|
|
|
2023-11-03 18:56:15 +00:00
|
|
|
|
2023-10-30 17:41:53 +00:00
|
|
|
{ TsRingSeries }
|
|
|
|
constructor TsRingSeries.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Create(AChart);
|
|
|
|
FChartType := ctRing;
|
|
|
|
FLine.Color := scBlack;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2023-11-03 18:56:15 +00:00
|
|
|
{ TsRegressionEquation }
|
|
|
|
constructor TsRegressionEquation.Create;
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
Font := TsFont.Create;
|
|
|
|
Font.Size := 9;
|
|
|
|
Border := TsChartLine.Create;
|
|
|
|
Border.Style := clsNoLine;
|
|
|
|
Border.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
|
|
|
Border.Color := scBlack;
|
|
|
|
Fill := TsChartFill.Create;
|
|
|
|
Fill.FgColor := scWhite;
|
|
|
|
XName := 'x';
|
|
|
|
YName := 'f(x)';
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TsRegressionEquation.Destroy;
|
|
|
|
begin
|
|
|
|
Fill.Free;
|
|
|
|
Border.Free;
|
|
|
|
Font.Free;
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsRegressionEquation.DefaultBorder: Boolean;
|
|
|
|
begin
|
|
|
|
Result := Border.Style = clsNoLine;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsRegressionEquation.DefaultFill: Boolean;
|
|
|
|
begin
|
2023-11-05 00:26:04 +00:00
|
|
|
Result := Fill.Style = cfsNoFill;
|
2023-11-03 18:56:15 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
function TsRegressionEquation.DefaultFont: Boolean;
|
|
|
|
begin
|
|
|
|
Result := (Font.FontName = '') and (Font.Size = 9) and (Font.Style = []) and
|
|
|
|
(Font.Color = scBlack);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsRegressionEquation.DefaultNumberFormat: Boolean;
|
|
|
|
begin
|
|
|
|
Result := NumberFormat = '';
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsRegressionEquation.DefaultPosition: Boolean;
|
|
|
|
begin
|
|
|
|
Result := (Left = 0) and (Top = 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsRegressionEquation.DefaultXName: Boolean;
|
|
|
|
begin
|
|
|
|
Result := XName = 'x';
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsRegressionEquation.DefaultYName: Boolean;
|
|
|
|
begin
|
|
|
|
Result := YName = 'f(x)';
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{ TsChartRegression }
|
|
|
|
constructor TsChartRegression.Create;
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
Line := TsChartLine.Create;
|
|
|
|
Line.Style := clsSolid;
|
|
|
|
Line.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
|
|
|
Line.Color := scBlack;
|
|
|
|
|
|
|
|
Equation := TsRegressionEquation.Create;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TsChartRegression.Destroy;
|
|
|
|
begin
|
|
|
|
Line.Free;
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2023-10-27 21:24:32 +00:00
|
|
|
{ TsScatterSeries }
|
|
|
|
|
|
|
|
constructor TsScatterSeries.Create(AChart: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Create(AChart);
|
|
|
|
FChartType := ctScatter;
|
2023-11-03 18:56:15 +00:00
|
|
|
FRegression := TsChartRegression.Create;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TsScatterSeries.Destroy;
|
|
|
|
begin
|
|
|
|
FRegression.Free;
|
|
|
|
inherited;
|
2023-10-27 21:24:32 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
{ TsChart }
|
|
|
|
|
|
|
|
constructor TsChart.Create;
|
|
|
|
begin
|
|
|
|
inherited Create(nil);
|
|
|
|
|
|
|
|
FLineStyles := TsChartLineStyleList.Create;
|
|
|
|
clsFineDot := FLineStyles.Add('fine-dot', 100, 1, 0, 0, 100, false);
|
|
|
|
clsDot := FLineStyles.Add('dot', 150, 1, 0, 0, 150, true);
|
|
|
|
clsDash := FLineStyles.Add('dash', 300, 1, 0, 0, 150, true);
|
|
|
|
clsDashDot := FLineStyles.Add('dash-dot', 300, 1, 100, 1, 150, true);
|
|
|
|
clsLongDash := FLineStyles.Add('long dash', 400, 1, 0, 0, 200, true);
|
|
|
|
clsLongDashDot := FLineStyles.Add('long dash-dot', 500, 1, 100, 1, 200, true);
|
|
|
|
clsLongDashDotDot := FLineStyles.Add('long dash-dot-dot', 500, 1, 100, 2, 200, true);
|
|
|
|
|
2023-11-05 00:26:04 +00:00
|
|
|
FGradients := TsChartGradientList.Create;
|
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
FSheetIndex := 0;
|
|
|
|
FRow := 0;
|
|
|
|
FCol := 0;
|
|
|
|
FOffsetX := 0.0;
|
|
|
|
FOffsetY := 0.0;
|
|
|
|
FWidth := 12;
|
|
|
|
FHeight := 9;
|
|
|
|
|
2023-10-23 10:58:15 +00:00
|
|
|
// FBackground and FBorder already created by ancestor.
|
2023-10-23 00:03:45 +00:00
|
|
|
|
2023-10-22 08:33:55 +00:00
|
|
|
FPlotArea := TsChartFillElement.Create(self);
|
|
|
|
FFloor := TsChartFillElement.Create(self);
|
2023-11-05 00:26:04 +00:00
|
|
|
FFloor.Background.Style := cfsNoFill;
|
2023-10-22 08:33:55 +00:00
|
|
|
|
|
|
|
FTitle := TsChartText.Create(self);
|
|
|
|
FTitle.Font.Size := 14;
|
|
|
|
|
|
|
|
FSubTitle := TsChartText.Create(self);
|
|
|
|
FSubTitle.Font.Size := 12;
|
|
|
|
|
|
|
|
FLegend := TsChartLegend.Create(self);
|
|
|
|
|
|
|
|
FXAxis := TsChartAxis.Create(self);
|
|
|
|
FXAxis.Caption := 'x axis';
|
2023-10-23 18:21:54 +00:00
|
|
|
FXAxis.CaptionFont.Style := [fssBold];
|
2023-10-22 08:33:55 +00:00
|
|
|
FXAxis.LabelFont.Size := 9;
|
|
|
|
FXAxis.Position := capStart;
|
|
|
|
|
|
|
|
FX2Axis := TsChartAxis.Create(self);
|
|
|
|
FX2Axis.Caption := 'Secondary x axis';
|
2023-10-23 18:21:54 +00:00
|
|
|
FX2Axis.CaptionFont.Style := [fssBold];
|
2023-10-22 08:33:55 +00:00
|
|
|
FX2Axis.LabelFont.Size := 9;
|
|
|
|
FX2Axis.Visible := false;
|
|
|
|
FX2Axis.Position := capEnd;
|
|
|
|
|
|
|
|
FYAxis := TsChartAxis.Create(self);
|
|
|
|
FYAxis.Caption := 'y axis';
|
2023-10-23 18:21:54 +00:00
|
|
|
FYAxis.CaptionFont.Style := [fssBold];
|
|
|
|
FYAxis.CaptionRotation := 90;
|
2023-10-22 08:33:55 +00:00
|
|
|
FYAxis.LabelFont.Size := 9;
|
|
|
|
FYAxis.Position := capStart;
|
|
|
|
|
|
|
|
FY2Axis := TsChartAxis.Create(self);
|
|
|
|
FY2Axis.Caption := 'Secondary y axis';
|
2023-10-23 18:21:54 +00:00
|
|
|
FY2Axis.CaptionFont.Style := [fssBold];
|
|
|
|
FY2Axis.CaptionRotation := 90;
|
2023-10-22 08:33:55 +00:00
|
|
|
FY2Axis.LabelFont.Size := 9;
|
|
|
|
FY2Axis.Visible := false;
|
|
|
|
FY2Axis.Position := capEnd;
|
|
|
|
|
|
|
|
FSeriesList := TsChartSeriesList.Create;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TsChart.Destroy;
|
|
|
|
begin
|
|
|
|
FSeriesList.Free;
|
|
|
|
FXAxis.Free;
|
|
|
|
FYAxis.Free;
|
|
|
|
FY2Axis.Free;
|
|
|
|
FLegend.Free;
|
|
|
|
FTitle.Free;
|
|
|
|
FSubtitle.Free;
|
|
|
|
FFloor.Free;
|
|
|
|
FPlotArea.Free;
|
2023-11-05 00:26:04 +00:00
|
|
|
FGradients.Free;
|
|
|
|
FLineStyles.Free;
|
2023-10-22 08:33:55 +00:00
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChart.AddSeries(ASeries: TsChartSeries): Integer;
|
|
|
|
begin
|
|
|
|
Result := FSeriesList.IndexOf(ASeries);
|
|
|
|
if Result = -1 then
|
|
|
|
Result := FSeriesList.Add(ASeries);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsChart.DeleteSeries(AIndex: Integer);
|
|
|
|
begin
|
|
|
|
if (AIndex >= 0) and (AIndex < FSeriesList.Count) then
|
|
|
|
FSeriesList.Delete(AIndex);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChart.GetCategoryLabelRange: TsCellRange;
|
|
|
|
begin
|
|
|
|
if FSeriesList.Count > 0 then
|
|
|
|
Result := Series[0].LabelRange
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
Result.Row1 := 0;
|
|
|
|
Result.Col1 := 0;
|
|
|
|
Result.Row2 := 0;
|
|
|
|
Result.Col2 := 0;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChart.GetChartType: TsChartType;
|
|
|
|
begin
|
|
|
|
if FSeriesList.Count > 0 then
|
|
|
|
Result := Series[0].ChartType
|
|
|
|
else
|
|
|
|
Result := ctEmpty;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChart.GetLineStyle(AIndex: Integer): TsChartLineStyle;
|
|
|
|
begin
|
|
|
|
if AIndex >= 0 then
|
|
|
|
Result := FLineStyles[AIndex]
|
|
|
|
else
|
|
|
|
Result := nil;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChart.IsScatterChart: Boolean;
|
|
|
|
begin
|
|
|
|
Result := GetChartType = ctScatter;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TsChart.NumLineStyles: Integer;
|
|
|
|
begin
|
|
|
|
Result := FLineStyles.Count;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{ TsChartList }
|
|
|
|
|
|
|
|
function TsChartList.GetItem(AIndex: Integer): TsChart;
|
|
|
|
begin
|
|
|
|
Result := TsChart(inherited Items[AIndex]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TsChartlist.SetItem(AIndex: Integer; AValue: TsChart);
|
|
|
|
begin
|
|
|
|
inherited Items[AIndex] := AValue;
|
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|
|
|