fpspreadsheet: Rename "Regression" property to "Trendline"

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9209 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2024-02-03 22:45:49 +00:00
parent c940344b00
commit 6bbfc0e6fc
5 changed files with 230 additions and 226 deletions

View File

@ -56,26 +56,26 @@ begin
ser.ShowLines := false;
ser.ShowSymbols := true;
ser.Symbol := cssCircle;
ser.Regression.Title := 'Fit curve';
ser.Regression.RegressionType := rtPolynomial; //rtLinear;
ser.Regression.ExtrapolateForwardBy := 10;
ser.Regression.ExtrapolateBackwardBy := 10;
ser.Regression.Line.Color := scRed;
ser.Regression.Line.Style := clsDash;
ser.Regression.ForceYIntercept := true; // not used by logarithmic, power
ser.Regression.YInterceptValue := 10.0; // dto.
ser.Regression.PolynomialDegree := 2;
ser.Regression.DisplayEquation := true;
ser.Regression.DisplayRSquare := true;
ser.Regression.Equation.XName := 'X';
ser.Regression.Equation.YName := 'Y';
ser.Regression.Equation.Border.Style := clsSolid;
ser.Regression.Equation.Border.Color := scRed;
ser.Regression.Equation.Fill.Style := cfsSolid;
ser.Regression.Equation.Fill.Color := scSilver;
ser.Regression.Equation.NumberFormat := '0.000';
//ser.Regression.Equation.Top := 5;
//ser.Regression.Equation.Left := 5;
ser.Trendline.Title := 'Fit curve';
ser.Trendline.TrendlineType := tltPolynomial; //tltLinear;
ser.Trendline.ExtrapolateForwardBy := 10;
ser.Trendline.ExtrapolateBackwardBy := 10;
ser.Trendline.Line.Color := scRed;
ser.Trendline.Line.Style := clsDash;
ser.Trendline.ForceYIntercept := true; // not used by logarithmic, power
ser.Trendline.YInterceptValue := 10.0; // dto.
ser.Trendline.PolynomialDegree := 2;
ser.Trendline.DisplayEquation := true;
ser.Trendline.DisplayRSquare := true;
ser.Trendline.Equation.XName := 'X';
ser.Trendline.Equation.YName := 'Y';
ser.Trendline.Equation.Border.Style := clsSolid;
ser.Trendline.Equation.Border.Color := scRed;
ser.Trendline.Equation.Fill.Style := cfsSolid;
ser.Trendline.Equation.Fill.Color := scSilver;
ser.Trendline.Equation.NumberFormat := '0.000';
//ser.Trendline.Equation.Top := 5;
//ser.Trendline.Equation.Left := 5;
book.WriteToFile(fn + '.xlsx', true);
WriteLn('Data saved with chart to ', fn + '.xlsx');

View File

@ -412,9 +412,9 @@ type
property Items[AIndex: Integer]: TsChartDataPointStyle read GetItem write SetItem; default;
end;
TsRegressionType = (rtNone, rtLinear, rtLogarithmic, rtExponential, rtPower, rtPolynomial);
TsTrendlineType = (tltNone, tltLinear, tltLogarithmic, tltExponential, tltPower, tltPolynomial);
TsRegressionEquation = class
TsTrendlineEquation = class
Fill: TsChartFill;
Font: TsFont;
Border: TsChartLine;
@ -433,9 +433,9 @@ type
function DefaultYName: Boolean;
end;
TsChartRegression = class
TsChartTrendline = class
Title: String;
RegressionType: TsRegressionType;
TrendlineType: TsTrendlineType;
ExtrapolateForwardBy: Double;
ExtrapolateBackwardBy: Double;
ForceYIntercept: Boolean;
@ -443,7 +443,7 @@ type
PolynomialDegree: Integer;
DisplayEquation: Boolean;
DisplayRSquare: Boolean;
Equation: TsRegressionEquation;
Equation: TsTrendlineEquation;
Line: TsChartLine;
constructor Create;
destructor Destroy; override;
@ -515,8 +515,8 @@ type
FDataLabelCalloutShape: TsChartLabelCalloutShape;
FDataPointStyles: TsChartDataPointStyleList;
FOrder: Integer;
FRegression: TsChartRegression;
FSupportsRegression: Boolean;
FTrendline: TsChartTrendline;
FSupportsTrendline: Boolean;
FXErrorBars: TsChartErrorBars;
FYErrorBars: TsChartErrorBars;
FGroupIndex: Integer; // series with the same GroupIndex can be stacked
@ -526,7 +526,7 @@ type
FLine: TsChartLine;
FFill: TsChartFill;
function GetChartType: TsChartType; virtual;
property Regression: TsChartRegression read FRegression write FRegression;
property Trendline: TsChartTrendline read FTrendline write FTrendline;
public
constructor Create(AChart: TsChart); virtual;
destructor Destroy; override;
@ -569,7 +569,7 @@ type
property LineColorRange: TsChartRange read FLineColorRange write FLineColorRange;
property Order: Integer read FOrder write FOrder;
property TitleAddr: TsChartCellAddr read FTitleAddr write FTitleAddr; // use '\n' for line-break
property SupportsRegression: Boolean read FSupportsRegression;
property SupportsTrendline: Boolean read FSupportsTrendline;
property XAxis: TsChartAxisLink read FXAxis write FXAxis;
property XErrorBars: TsChartErrorBars read FXErrorBars write SetXErrorBars;
property XRange: TsChartRange read FXRange write FXRange;
@ -585,13 +585,13 @@ type
TsAreaSeries = class(TsChartSeries)
public
constructor Create(AChart: TsChart); override;
property Regression;
property Trendline;
end;
TsBarSeries = class(TsChartSeries)
public
constructor Create(AChart: TsChart); override;
property Regression;
property Trendline;
end;
TsChartSeriesSymbol = (
@ -625,7 +625,6 @@ type
TsLineSeries = class(TsCustomLineSeries)
public
property Regression;
property Symbol;
property SymbolBorder;
property SymbolFill;
@ -633,6 +632,7 @@ type
property SymbolWidth;
property ShowLines;
property ShowSymbols;
property Trendline;
end;
TsSliceOrder = (soCCW, soCW);
@ -663,7 +663,7 @@ type
TsCustomScatterSeries = class(TsCustomLineSeries)
public
constructor Create(AChart: TsChart); override;
property Regression;
property Trendline;
end;
TsScatterSeries = class(TsCustomScatterSeries)
@ -2140,7 +2140,7 @@ begin
FLabelSeparator := ' ';
FRegression := TsChartRegression.Create;
FTrendline := TsChartTrendline.Create;
FXErrorBars := TsChartErrorBars.Create(Self);
FYErrorBars := TsChartErrorBars.Create(Self);
@ -2150,7 +2150,7 @@ destructor TsChartSeries.Destroy;
begin
FYErrorBars.Free;
FXErrorBars.Free;
FRegression.Free;
FTrendline.Free;
FLabelBackground.Free;
FLabelBorder.Free;
FLabelFont.Free;
@ -2357,7 +2357,7 @@ constructor TsAreaSeries.Create(AChart: TsChart);
begin
inherited Create(AChart);
FChartType := ctArea;
FSupportsRegression := true;
FSupportsTrendline := true;
FGroupIndex := 0;
end;
@ -2368,7 +2368,7 @@ constructor TsBarSeries.Create(AChart: TsChart);
begin
inherited Create(AChart);
FChartType := ctBar;
FSupportsRegression := true;
FSupportsTrendline := true;
FGroupIndex := 0;
end;
@ -2416,7 +2416,7 @@ begin
inherited Create(AChart);
FChartType := ctLine;
FSupportsRegression := true;
FSupportsTrendline := true;
FSymbolWidth := 2.5;
FSymbolHeight := 2.5;
@ -2475,8 +2475,8 @@ begin
end;
{ TsRegressionEquation }
constructor TsRegressionEquation.Create;
{ TsTrendlineEquation }
constructor TsTrendlineEquation.Create;
begin
inherited Create;
Font := TsFont.Create;
@ -2491,7 +2491,7 @@ begin
YName := 'f(x)';
end;
destructor TsRegressionEquation.Destroy;
destructor TsTrendlineEquation.Destroy;
begin
Fill.Free;
Border.Free;
@ -2499,45 +2499,45 @@ begin
inherited;
end;
function TsRegressionEquation.DefaultBorder: Boolean;
function TsTrendlineEquation.DefaultBorder: Boolean;
begin
Result := Border.Style = clsNoLine;
end;
function TsRegressionEquation.DefaultFill: Boolean;
function TsTrendlineEquation.DefaultFill: Boolean;
begin
Result := Fill.Style = cfsNoFill;
end;
function TsRegressionEquation.DefaultFont: Boolean;
function TsTrendlineEquation.DefaultFont: Boolean;
begin
Result := (Font.FontName = '') and (Font.Size = 9) and (Font.Style = []) and
(Font.Color = scBlack);
end;
function TsRegressionEquation.DefaultNumberFormat: Boolean;
function TsTrendlineEquation.DefaultNumberFormat: Boolean;
begin
Result := NumberFormat = '';
end;
function TsRegressionEquation.DefaultPosition: Boolean;
function TsTrendlineEquation.DefaultPosition: Boolean;
begin
Result := (Left = 0) and (Top = 0);
end;
function TsRegressionEquation.DefaultXName: Boolean;
function TsTrendlineEquation.DefaultXName: Boolean;
begin
Result := XName = 'x';
end;
function TsRegressionEquation.DefaultYName: Boolean;
function TsTrendlineEquation.DefaultYName: Boolean;
begin
Result := YName = 'f(x)';
end;
{ TsChartRegression }
constructor TsChartRegression.Create;
{ TsChartTrendline }
constructor TsChartTrendline.Create;
begin
inherited Create;
@ -2546,10 +2546,10 @@ begin
Line.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
Line.Color := scBlack;
Equation := TsRegressionEquation.Create;
Equation := TsTrendlineEquation.Create;
end;
destructor TsChartRegression.Destroy;
destructor TsChartTrendline.Destroy;
begin
Equation.Free;
Line.Free;
@ -2563,7 +2563,7 @@ constructor TsCustomScatterSeries.Create(AChart: TsChart);
begin
inherited Create(AChart);
FChartType := ctScatter;
FSupportsRegression := true;
FSupportsTrendline := true;
end;

View File

@ -104,7 +104,7 @@ type
function GetChartPlotAreaStyleAsXML(AChart: TsChart;
AIndent, AStyleID: Integer): String;
function GetChartRegressionEquationStyleAsXML(AChart: TsChart;
AEquation: TsRegressionEquation; AIndent, AStyleID: Integer): String;
AEquation: TsTrendlineEquation; AIndent, AStyleID: Integer): String;
function GetChartRegressionStyleAsXML(AChart: TsChart;
ASeriesIndex, AIndent, AStyleID: Integer): String;
function GetChartSeriesDataPointStyleAsXML(AChart: TsChart;
@ -173,11 +173,11 @@ uses
type
TAxisKind = 3..6;
TsCustomLineSeriesOpener = class(TsCustomLineSeries);
TsOpenedCustomLineSeries = class(TsCustomLineSeries);
TsOpenRegressionSeries = class(TsChartSeries)
TsOpenedTrendlineSeries = class(TsChartSeries)
public
property Regression;
property Trendline;
end;
const
@ -216,7 +216,7 @@ const
AXIS_ID: array[TAxisKind] of string = ('x', 'y', 'x', 'y');
AXIS_LEVEL: array[TAxisKind] of string = ('primary', 'primary', 'secondary', 'secondary');
REGRESSION_TYPE: array [TsRegressionType] of string = (
REGRESSION_TYPE: array [TsTrendlineType] of string = (
'', 'linear', 'logarithmic', 'exponential', 'power', 'polynomial');
FALSE_TRUE: array[boolean] of string = ('false', 'true');
@ -1210,6 +1210,7 @@ procedure TsSpreadOpenDocChartReader.ReadChartRegressionEquationStyle(AStyleNode
AChart: TsChart; ASeries: TsChartSeries);
var
series: TsCustomScatterSeries;
trendline: TsChartTrendline;
odsReader: TsSpreadOpenDocReader;
s, nodeName: String;
begin
@ -1217,13 +1218,14 @@ begin
exit;
series := TsCustomScatterSeries(ASeries);
trendline := series.Trendline;
odsReader := TsSpreadOpenDocReader(Reader);
nodeName := AStyleNode.NodeName;
s := GetAttrValue(AStyleNode, 'style:data-style-name');
if s <> '' then
s := TsChartNumberFormatList(FNumberFormatList).FindFormatByName(s);
series.Regression.Equation.NumberFormat := s;
trendline.Equation.NumberFormat := s;
AStyleNode := AStyleNode.FirstChild;
while Assigned(AStyleNode) do
@ -1232,20 +1234,20 @@ begin
case nodeName of
'style:graphic-properties':
begin
GetChartLineProps(AStyleNode, AChart, series.Regression.Equation.Border);
GetChartFillProps(AStyleNode, AChart, series.Regression.Equation.Fill);
GetChartLineProps(AStyleNode, AChart, trendline.Equation.Border);
GetChartFillProps(AStyleNode, AChart, trendline.Equation.Fill);
end;
'style:text-properties':
GetChartTextProps(AStyleNode, series.Regression.Equation.Font);
GetChartTextProps(AStyleNode, trendline.Equation.Font);
'style:chart-properties':
begin
s := GetAttrValue(AStyleNode, 'loext:regression-x-name');
if s <> '' then
series.Regression.Equation.XName := s;
trendline.Equation.XName := s;
s := GetAttrValue(AStyleNode, 'loext:regression-y-name');
if s <> '' then
series.Regression.Equation.YName := s;
trendline.Equation.YName := s;
end;
end;
AStyleNode := AStyleNode.NextSibling;
@ -1256,6 +1258,7 @@ procedure TsSpreadOpenDocChartReader.ReadChartRegressionProps(ANode, AStyleNode:
AChart: TsChart; ASeries: TsChartSeries);
var
series: TsCustomScatterSeries;
trendline: TsChartTrendline;
s, nodeName: String;
styleNode: TDOMNode;
subNode: TDOMNode;
@ -1264,6 +1267,7 @@ begin
exit;
series := TsCustomScatterSeries(ASeries);
trendline := series.Trendline;
s := GetAttrValue(ANode, 'chart:style-name');
styleNode := FindStyleNode(AStyleNode, s);
@ -1276,10 +1280,10 @@ begin
if nodeName = 'chart:equation' then
begin
s := GetAttrValue(subNode, 'chart:display-equation');
series.Regression.DisplayEquation := (s = 'true');
trendline.DisplayEquation := (s = 'true');
s := GetAttrValue(subNode, 'chart:display-r-square');
series.Regression.DisplayRSquare := (s = 'true');
trendline.DisplayRSquare := (s = 'true');
s := GetAttrValue(subNode, 'chart:style-name');
styleNode := FindStyleNode(AStyleNode, s);
@ -1293,15 +1297,15 @@ procedure TsSpreadOpenDocChartReader.ReadChartRegressionStyle(AStyleNode: TDOMNo
AChart: TsChart; ASeries: TsChartSeries);
var
s, nodeName: String;
regression: TsChartRegression;
rt: TsRegressionType;
trendline: TsChartTrendline;
rt: TsTrendlineType;
value: Double;
intValue: Integer;
begin
if not ASeries.SupportsRegression then
if not ASeries.SupportsTrendline then
exit;
regression := TsOpenRegressionSeries(ASeries).Regression;
trendline := TsOpenedTrendlineSeries(ASeries).Trendline;
AStyleNode := AStyleNode.FirstChild;
while Assigned(AStyleNode) do
@ -1309,42 +1313,42 @@ begin
nodeName := AStyleNode.NodeName;
case nodeName of
'style:graphic-properties':
GetChartLineProps(AStyleNode, AChart, regression.Line);
GetChartLineProps(AStyleNode, AChart, trendline.Line);
'style:chart-properties':
begin
s := GetAttrValue(AStyleNode, 'chart:regression-name');
regression.Title := s;
trendline.Title := s;
s := GetAttrValue(AStyleNode, 'chart:regression-type');
for rt in TsRegressionType do
for rt in TsTrendlineType do
if (s <> '') and (REGRESSION_TYPE[rt] = s) then
begin
regression.RegressionType := rt;
trendline.TrendlineType := rt;
break;
end;
s := GetAttrValue(AStyleNode, 'chart:regression-max-degree');
if (s <> '') and TryStrToInt(s, intValue) then
regression.PolynomialDegree := intValue;
if TryStrToInt(s, intValue) then
trendline.PolynomialDegree := intValue;
s := GetAttrValue(AStyleNode, 'chart:regression-extrapolate-forward');
if (s <> '') and TryStrToFloat(s, value, FPointSeparatorSettings) then
regression.ExtrapolateForwardBy := value
if TryStrToFloat(s, value, FPointSeparatorSettings) then
trendline.ExtrapolateForwardBy := value
else
regression.ExtrapolateForwardBy := 0.0;
trendline.ExtrapolateForwardBy := 0.0;
s := GetAttrValue(AStyleNode, 'chart:regression-extrapolate-backward');
if (s <> '') and TryStrToFloat(s, value, FPointSeparatorSettings) then
regression.ExtrapolateBackwardBy := value
if TryStrToFloat(s, value, FPointSeparatorSettings) then
trendline.ExtrapolateBackwardBy := value
else
regression.ExtrapolateBackwardBy := 0.0;
trendline.ExtrapolateBackwardBy := 0.0;
s := GetAttrValue(AStyleNode, 'chart:regression-force-intercept');
regression.ForceYIntercept := (s = 'true');
trendline.ForceYIntercept := (s = 'true');
s := GetAttrValue(AStyleNode, 'chart:regression-intercept-value');
if (s <> '') and TryStrToFloat(s, value, FPointSeparatorSettings) then
regression.YInterceptValue := value;
if TryStrToFloat(s, value, FPointSeparatorSettings) then
trendline.YInterceptValue := value;
end;
end;
AStyleNode := AStyleNode.NextSibling;
@ -1693,21 +1697,21 @@ begin
s := GetAttrValue(AStyleNode, 'chart:symbol-name');
if s <> '' then
begin
TsCustomLineSeriesOpener(ASeries).ShowSymbols := true;
TsOpenedCustomLineSeries(ASeries).ShowSymbols := true;
for css in TsChartSeriesSymbol do
if SYMBOL_NAMES[css] = s then
begin
TsCustomLineSeriesOpener(ASeries).Symbol := css;
TsOpenedCustomLineSeries(ASeries).Symbol := css;
break;
end;
s := GetAttrValue(AStyleNode, 'symbol-width');
if (s <> '') and EvalLengthStr(s, value, rel) then
TsCustomLineSeriesOpener(ASeries).SymbolWidth := value;
TsOpenedCustomLineSeries(ASeries).SymbolWidth := value;
s := GetAttrValue(AStyleNode, 'symbol-height');
if (s <> '') and EvalLengthStr(s, value, rel) then
TsCustomLineSeriesOpener(ASeries).SymbolHeight := value;
TsOpenedCustomLineSeries(ASeries).SymbolHeight := value;
end else
TsCustomLineSeriesOpener(ASeries).ShowSymbols := false;
TsOpenedCustomLineSeries(ASeries).ShowSymbols := false;
end;
end;
@ -2597,7 +2601,7 @@ begin
end;
function TsSpreadOpenDocChartWriter.GetChartRegressionEquationStyleAsXML(
AChart: TsChart; AEquation: TsRegressionEquation; AIndent, AStyleID: Integer): String;
AChart: TsChart; AEquation: TsTrendlineEquation; AIndent, AStyleID: Integer): String;
var
indent: String;
numStyle: String = 'N0';
@ -2639,8 +2643,8 @@ end;
function TsSpreadOpenDocChartWriter.GetChartRegressionStyleAsXML(AChart: TsChart;
ASeriesIndex, AIndent, AStyleID: Integer): String;
var
regression: TsChartRegression;
series: TsChartSeries;
trendline: TsChartTrendline;
indent: String;
chartProps: String = '';
graphProps: String = '';
@ -2649,12 +2653,12 @@ begin
indent := DupeString(' ', AIndent);
series := AChart.Series[ASeriesIndex];
if not series.SupportsRegression then
if not series.SupportsTrendline then
exit;
regression := TsOpenRegressionSeries(series).Regression;
trendline := TsOpenedTrendlineSeries(series).Trendline;
if regression.RegressionType = rtNone then
if trendline.TrendlineType = tltNone then
exit;
series := AChart.Series[ASeriesIndex] as TsScatterSeries;
@ -2666,17 +2670,17 @@ begin
'chart:regression-force-intercept="%s" ' +
'chart:regression-intercept-value="%g" ' +
'chart:regression-max-degree="%d" ',
[ regression.Title,
REGRESSION_TYPE[regression.RegressionType] ,
regression.ExtrapolateForwardBy,
regression.ExtrapolateBackwardBy,
FALSE_TRUE[regression.ForceYIntercept],
regression.YInterceptValue,
regression.PolynomialDegree
[ trendline.Title,
REGRESSION_TYPE[trendline.TrendlineType] ,
trendline.ExtrapolateForwardBy,
trendline.ExtrapolateBackwardBy,
FALSE_TRUE[trendline.ForceYIntercept],
trendline.YInterceptValue,
trendline.PolynomialDegree
], FPointSeparatorSettings
);
graphprops := GetChartLineStyleGraphicPropsAsXML(AChart, regression.Line);
graphprops := GetChartLineStyleGraphicPropsAsXML(AChart, trendline.Line);
Result := Format(
indent + '<style:style style:name="ch%d" style:family="chart"> ' + LE +
@ -2883,7 +2887,7 @@ procedure TsSpreadOpenDocChartWriter.ListAllNumberFormats(AChart: TsChart);
var
i: Integer;
series: TsChartSeries;
regression: TsChartRegression;
trendline: TsChartTrendline;
begin
FNumberFormatList.Clear;
FNumberFormatList.Add('');
@ -2905,13 +2909,13 @@ begin
series := AChart.Series[i];
FNumberFormatList.Add(series.LabelFormat);
// Format of fit equation
if series.SupportsRegression then
if series.SupportsTrendline then
begin
regression := TsOpenRegressionSeries(series).Regression;
if (regression.RegressionType <> rtNone) and
(regression.DisplayEquation or regression.DisplayRSquare) then
trendline := TsOpenedTrendlineSeries(series).Trendline;
if (trendline.TrendlineType <> tltNone) and
(trendline.DisplayEquation or trendline.DisplayRSquare) then
begin
FNumberFormatList.Add(regression.Equation.NumberFormat);
FNumberFormatList.Add(trendline.Equation.NumberFormat);
end;
end;
end;
@ -3702,19 +3706,19 @@ var
lineColorRange: String = '';
chartClass: String = '';
seriesYAxis: String = '';
regressionEquation: String = '';
regression: TsChartRegression = nil;
trendlineEquation: String = '';
trendline: TsChartTrendline = nil;
titleAddr: String;
i, count: Integer;
nextStyleID, seriesStyleID, regressionStyleID, regressionEquStyleID: Integer;
nextStyleID, seriesStyleID, trendlineStyleID, trendlineEquStyleID: Integer;
xErrStyleID, yErrStyleID, dataStyleID: Integer;
begin
indent := DupeString(' ', AChartIndent);
nextstyleID := AStyleID;
seriesStyleID := AStyleID;
regressionStyleID := -1;
regressionEquStyleID := -1;
trendlineStyleID := -1;
trendlineEquStyleID := -1;
xErrStyleID := -1;
yErrStyleID := -1;
dataStyleID := -1;
@ -3861,35 +3865,35 @@ begin
// Regression
if (series is TsScatterSeries) then
begin
regression := TsScatterSeries(series).Regression;
if regression.RegressionType <> rtNone then
trendline := TsScatterSeries(series).trendline;
if trendline.TrendlineType <> tltNone then
begin
regressionStyleID := nextStyleID;
trendlineStyleID := nextStyleID;
inc(nextStyleID);
if regression.DisplayEquation or regression.DisplayRSquare then
if trendline.DisplayEquation or trendline.DisplayRSquare then
begin
if (not regression.Equation.DefaultXName) or (not regression.Equation.DefaultYName) or
(not regression.Equation.DefaultBorder) or (not regression.Equation.DefaultFill) or
(not regression.Equation.DefaultFont) or (not regression.Equation.DefaultNumberFormat) or
(not regression.Equation.DefaultPosition) then
if (not trendline.Equation.DefaultXName) or (not trendline.Equation.DefaultYName) or
(not trendline.Equation.DefaultBorder) or (not trendline.Equation.DefaultFill) or
(not trendline.Equation.DefaultFont) or (not trendline.Equation.DefaultNumberFormat) or
(not trendline.Equation.DefaultPosition) then
begin
regressionEquStyleID := nextStyleID;
regressionEquation := regressionEquation + Format('chart:style-name="ch%d" ', [ regressionEquStyleID ]);
trendlineEquStyleID := nextStyleID;
trendlineEquation := trendlineEquation + Format('chart:style-name="ch%d" ', [ trendlineEquStyleID ]);
inc(nextStyleID);
end;
end;
if regression.DisplayEquation then
regressionEquation := regressionEquation + 'chart:display-equation="true" ';
if regression.DisplayRSquare then
regressionEquation := regressionEquation + 'chart:display-r-square="true" ';
if trendline.DisplayEquation then
trendlineEquation := trendlineEquation + 'chart:display-equation="true" ';
if trendline.DisplayRSquare then
trendlineEquation := trendlineEquation + 'chart:display-r-square="true" ';
if regressionEquation <> '' then
if trendlineEquation <> '' then
begin
if not regression.Equation.DefaultPosition then
regressionEquation := regressionEquation + Format(
if not trendline.Equation.DefaultPosition then
trendlineEquation := trendlineEquation + Format(
'svg:x="%.2fmm" svg:y="%.2fmm" ',
[ regression.Equation.Left, regression.Equation.Top ],
[ trendline.Equation.Left, trendline.Equation.Top ],
FPointSeparatorSettings
);
@ -3897,12 +3901,12 @@ begin
indent + ' <chart:regression-curve chart:style-name="ch%d">' + LE +
indent + ' <chart:equation %s />' + LE +
indent + ' </chart:regression-curve>' + LE,
[ regressionStyleID, regressionEquation ]
[ trendlineStyleID, trendlineEquation ]
));
end else
AppendToStream(AChartStream, Format(
indent + ' <chart:regression-curve chart:style-name="ch%d"/>',
[ regressionStyleID ]
[ trendlineStyleID ]
));
end;
end;
@ -3942,17 +3946,17 @@ begin
);
// Regression style
if regressionStyleID <> -1 then
if trendlineStyleID <> -1 then
begin
AppendToStream(AStyleStream,
GetChartRegressionStyleAsXML(AChart, ASeriesIndex, AStyleIndent, regressionStyleID)
GetChartRegressionStyleAsXML(AChart, ASeriesIndex, AStyleIndent, trendlineStyleID)
);
// Style of regression equation
if regressionEquStyleID <> -1 then
if trendlineEquStyleID <> -1 then
begin
AppendToStream(AStyleStream,
GetChartRegressionEquationStyleAsXML(AChart, regression.Equation, AStyleIndent, regressionEquStyleID)
GetChartRegressionEquationStyleAsXML(AChart, trendline.Equation, AStyleIndent, trendlineEquStyleID)
);
end;
end;

View File

@ -163,7 +163,7 @@ const
AX_POS: array[TsChartAxisAlignment] of string = ('l', 't', 'r', 'b');
FALSE_TRUE: Array[boolean] of String = ('0', '1');
LEGEND_POS: Array[TsChartLegendPosition] of string = ('r', 't', 'b', 'l');
TRENDLINE_TYPES: Array[TsRegressionType] of string = ('', 'linear', 'log', 'exp', 'power', 'poly');
TRENDLINE_TYPES: Array[TsTrendlineType] of string = ('', 'linear', 'log', 'exp', 'power', 'poly');
// 'movingAvg' and 'log' not supported, so far
@ -195,7 +195,7 @@ end;
type
TsOpenCustomLineSeries = class(TsCustomLineSeries)
TsOpenedCustomLineSeries = class(TsCustomLineSeries)
public
property Symbol;
property SymbolBorder;
@ -206,9 +206,9 @@ type
property ShowSymbols;
end;
TsOpenRegressionSeries = class(TsChartSeries)
TsOpenedTrendlineSeries = class(TsChartSeries)
public
property Regression;
property Trendline;
end;
@ -1343,14 +1343,14 @@ begin
if nodeName = 'c:marker' then
ANode := ANode.FirstChild;
TsOpenCustomLineSeries(ASeries).ShowSymbols := true;
TsOpenedCustomLineSeries(ASeries).ShowSymbols := true;
while Assigned(ANode) do
begin
nodeName := ANode.NodeName;
s := GetAttrValue(ANode, 'val');
case nodeName of
'c:symbol':
with TsOpenCustomLineSeries(ASeries) do
with TsOpenedCustomLineSeries(ASeries) do
case s of
'none': ShowSymbols := false;
'square': Symbol := cssRect;
@ -1371,14 +1371,14 @@ begin
'c:size':
if TryStrToInt(s, n) then
with TsOpenCustomlineSeries(ASeries) do
with TsOpenedCustomLineSeries(ASeries) do
begin
SymbolWidth := PtsToMM(n div 2);
SymbolHeight := SymbolWidth;
end;
'c:spPr':
with TsOpenCustomLineSeries(ASeries) do
with TsOpenedCustomLineSeries(ASeries) do
ReadChartFillAndLineProps(ANode.FirstChild, Chart, SymbolFill, SymbolBorder);
end;
ANode := ANode.NextSibling;
@ -1978,59 +1978,59 @@ procedure TsSpreadOOXMLChartReader.ReadChartSeriesTrendLine(ANode: TDOMNode;
ASeries: TsChartSeries);
var
nodeName, s: String;
regression: TsChartRegression;
trendline: TsChartTrendline;
child: TDOMNode;
n: Integer;
x: Double;
begin
if ANode = nil then
exit;
if not ASeries.SupportsRegression then
if not ASeries.SupportsTrendline then
exit;
regression := TsOpenRegressionSeries(ASeries).Regression;
trendline := TsOpenedTrendlineSeries(ASeries).Trendline;
while Assigned(ANode) do begin
nodeName := ANode.NodeName;
s := GetAttrValue(ANode, 'val');
case nodeName of
'c:name':
regression.Title := GetNodeValue(ANode);
trendline.Title := GetNodeValue(ANode);
'c:spPr':
ReadChartLineProps(ANode.FirstChild, ASeries.Chart, regression.Line);
ReadChartLineProps(ANode.FirstChild, ASeries.Chart, trendline.Line);
'c:trendlineType':
case s of
'exp': regression.RegressionType := rtExponential;
'linear': regression.RegressionType := rtLinear;
'log': regression.RegressionType := rtNone; // rtLog, but not supported.
'movingAvg': regression.RegressionType := rtNone; // rtMovingAvg, but not supported.
'poly': regression.RegressionType := rtPolynomial;
'power': regression.RegressionType := rtPower;
'exp': trendline.TrendlineType := tltExponential;
'linear': trendline.TrendlineType := tltLinear;
'log': trendline.TrendlineType := tltNone; // rtLog, but not supported.
'movingAvg': trendline.TrendlineType := tltNone; // rtMovingAvg, but not supported.
'poly': trendline.TrendlineType := tltPolynomial;
'power': trendline.TrendlineType := tltPower;
end;
'c:order':
if (s <> '') and TryStrToInt(s, n) then
regression.PolynomialDegree := n;
trendline.PolynomialDegree := n;
'c:period':
if (s <> '') and TryStrToInt(s, n) then ; // not supported
// regression.MovingAvgPeriod := n;
// trendline.MovingAvgPeriod := n;
'c:forward', 'c:backward':
if (s <> '') and TryStrToFloat(s, x, FPointSeparatorSettings) then
case nodeName of
'c:forward': regression.ExtrapolateForwardBy := x;
'c:backward': regression.ExtrapolateBackwardBy := x;
'c:forward': trendline.ExtrapolateForwardBy := x;
'c:backward': trendline.ExtrapolateBackwardBy := x;
end;
'c:intercept':
if (s <> '') and TryStrToFloat(s, x, FPointSeparatorSettings) then
begin
regression.YInterceptValue := x;
regression.ForceYIntercept := true;
trendline.YInterceptValue := x;
trendline.ForceYIntercept := true;
end;
'c:dispRSqr':
if s = '1' then
regression.DisplayRSquare := true;
trendline.DisplayRSquare := true;
'c:dispEq':
if s = '1' then
regression.DisplayEquation := true;
trendline.DisplayEquation := true;
'c:trendlineLbl':
begin
child := ANode.FirstChild;
@ -2041,7 +2041,7 @@ begin
'c:numFmt':
begin
s := GetAttrValue(child, 'formatCode');
regression.Equation.NumberFormat := s;
trendline.Equation.NumberFormat := s;
end;
end;
child := child.NextSibling;
@ -3790,11 +3790,11 @@ var
indent: String;
markerStr: String;
chart: TsChart;
ser: TsOpenCustomLineSeries;
ser: TsOpenedCustomLineSeries;
begin
indent := DupeString(' ', AIndent);
chart := ASeries.Chart;
ser := TsOpencustomLineseries(ASeries);
ser := TsOpenedCustomLineSeries(ASeries);
if ser.ShowSymbols then
case ser.Symbol of
@ -3960,44 +3960,44 @@ procedure TsSpreadOOXMLChartWriter.WriteChartRegression(AStream: TStream;
AIndent: Integer; ASeries: TsChartSeries);
var
indent: String;
regression: TsChartRegression;
trendline: TsChartTrendline;
nameStr: String = '';
orderStr: String = '';
interceptStr: String = '';
backwardStr: String = '';
forwardStr: String = '';
begin
regression := TsOpenRegressionSeries(ASeries).Regression;
if regression.RegressionType = rtNone then
trendline := TsOpenedTrendlineSeries(ASeries).Trendline;
if trendline.TrendlineType = tltNone then
exit;
indent := DupeString(' ', AIndent);
if regression.Title <> '' then
if trendline.Title <> '' then
nameStr := Format(
indent + ' <c:name>%s</c:name>' + LE, [regression.Title]);
indent + ' <c:name>%s</c:name>' + LE, [trendline.Title]);
if regression.RegressionType = rtPolynomial then
if trendline.TrendlineType = tltPolynomial then
orderStr := Format(
indent + ' <c:order val="%d"/>' + LE, [regression.PolynomialDegree]);
indent + ' <c:order val="%d"/>' + LE, [trendline.PolynomialDegree]);
if regression.ForceYIntercept then
if trendline.ForceYIntercept then
interceptStr := Format(
indent + ' <c:intercept val="%g"/>' + LE, [regression.YInterceptValue], FPointSeparatorSettings);
indent + ' <c:intercept val="%g"/>' + LE, [trendline.YInterceptValue], FPointSeparatorSettings);
if regression.ExtrapolateForwardBy <> 0 then
if trendline.ExtrapolateForwardBy <> 0 then
forwardStr := Format(
indent + ' <c:forward val="%g"/>' + LE, [regression.ExtrapolateForwardBy], FPointSeparatorSettings);
indent + ' <c:forward val="%g"/>' + LE, [trendline.ExtrapolateForwardBy], FPointSeparatorSettings);
if regression.ExtrapolateBackwardBy <> 0 then
if trendline.ExtrapolateBackwardBy <> 0 then
backwardStr := Format(
indent + ' <c:backward val="%g"/>' + LE, [regression.ExtrapolateBackwardBy], FPointSeparatorSettings);
indent + ' <c:backward val="%g"/>' + LE, [trendline.ExtrapolateBackwardBy], FPointSeparatorSettings);
AppendToStream(AStream, Format(
indent + '<c:trendline>' + LE +
nameStr +
indent + ' <c:spPr>' + LE +
GetChartLineXML(AIndent + 4, ASeries.Chart, regression.Line) + LE +
GetChartLineXML(AIndent + 4, ASeries.Chart, trendline.Line) + LE +
indent + ' </c:spPr>' + LE +
indent + ' <c:trendlineType val="%s"/>' + LE +
orderStr +
@ -4007,9 +4007,9 @@ begin
indent + ' <c:dispRSqr val="%s"/>' + LE +
indent + ' <c:dispEq val="%s"/>' + LE +
indent + '</c:trendline>' + LE,
[ TRENDLINE_TYPES[regression.RegressionType],
FALSE_TRUE[regression.DisplayRSquare],
FALSE_TRUE[regression.DisplayEquation]
[ TRENDLINE_TYPES[trendline.TrendlineType],
FALSE_TRUE[trendline.DisplayRSquare],
FALSE_TRUE[trendline.DisplayEquation]
]
));
end;
@ -4054,16 +4054,16 @@ begin
// Line & scatter series: symbol markers
if (ASeries is TsCustomLineSeries) then
begin
forceNoLine := not TsOpenCustomLineSeries(ASeries).ShowLines;
forceNoLine := not TsOpenedCustomLineSeries(ASeries).ShowLines;
AppendToStream(AStream,
indent + ' <c:spPr>' + LE +
GetChartLineXML(AIndent, chart, ASeries.Line, forceNoLine) + LE +
indent + ' </c:spPr>' + LE
);
if TsOpenCustomLineSeries(ASeries).ShowSymbols then
if TsOpenedCustomLineSeries(ASeries).ShowSymbols then
AppendToStream(AStream,
indent + ' <c:marker>' + LE +
GetChartSeriesMarkerXML(AIndent + 4, TsOpenCustomLineSeries(ASeries)) + LE +
GetChartSeriesMarkerXML(AIndent + 4, TsOpenedCustomLineSeries(ASeries)) + LE +
indent + ' </c:marker>' + LE
);
end else
@ -4075,7 +4075,7 @@ begin
);
// Regression
if ASeries.SupportsRegression then
if ASeries.SupportsTrendline then
WriteChartRegression(AStream, AIndent + 2, ASeries);
// Cell ranges

View File

@ -221,16 +221,16 @@ const
);
type
TBasicPointSeriesOpener = class(TBasicPointSeries);
TOpenedBasicPointSeries = class(TBasicPointSeries);
TsCustomLineSeriesOpener = class(TsCustomLineSeries);
TsOpenedCustomLineSeries = class(TsCustomLineSeries);
TsRegressionSeries = class(TsChartSeries)
TsOpenedTrendlineSeries = class(TsChartSeries)
public
property Regression;
property Trendline;
end;
TErrorbarSeries = class(TBasicPointSeries)
TOpenedErrorbarSeries = class(TBasicPointSeries)
public
property XErrorBars;
property YErrorBars;
@ -2259,10 +2259,10 @@ const
end;
var
series: TErrorBarSeries;
series: TOpenedErrorbarSeries;
source: TsWorkbookChartSource;
begin
series := TErrorBarSeries(ASeries);
series := TOpenedErrorbarSeries(ASeries);
source := GetChartSource(ASeries.Source);
if source = nil then
exit;
@ -2406,15 +2406,15 @@ begin
if (AChartSeries is TBasicPointSeries) then
case AWorkbookSeries.LabelPosition of
lpDefault:
TBasicPointSeriesOpener(AChartSeries).MarkPositions := lmpOutside;
TOpenedBasicPointSeries(AChartSeries).MarkPositions := lmpOutside;
lpOutside:
TBasicPointSeriesOpener(AChartSeries).MarkPositions := lmpOutside;
TOpenedBasicPointSeries(AChartSeries).MarkPositions := lmpOutside;
lpInside:
TBasicPointSeriesOpener(AChartSeries).MarkPositions := lmpInside;
TOpenedBasicPointSeries(AChartSeries).MarkPositions := lmpInside;
lpCenter:
begin
TBasicPointSeriesOpener(AChartSeries).MarkPositions := lmpInside;
TBasicPointSeriesOpener(AChartSeries).MarkPositionCentered := true;
TOpenedBasicPointSeries(AChartSeries).MarkPositions := lmpInside;
TOpenedBasicPointSeries(AChartSeries).MarkPositionCentered := true;
end;
end;
@ -2434,18 +2434,18 @@ end;
procedure TsWorkbookChartLink.UpdateChartSeriesRegression(AWorkbookSeries: TsChartSeries;
AChartSeries: TChartSeries);
var
regressionSeries: TsRegressionSeries;
regression: TsChartRegression;
trendlineSeries: TsOpenedTrendlineSeries;
trendline: TsChartTrendline;
ser: TFitSeries;
s: String;
begin
if not AWorkbookSeries.SupportsRegression then
if not AWorkbookSeries.SupportsTrendline then
exit;
regressionSeries := TsRegressionSeries(AWorkbookSeries);
regression := regressionSeries.Regression;
trendlineSeries := TsOpenedTrendlineSeries(AWorkbookSeries);
trendline := trendlineSeries.Trendline;
if regression.RegressionType = rtNone then
if trendline.TrendlineType = tltNone then
exit;
// Create series and assign chartsource
@ -2453,54 +2453,54 @@ begin
ser.Source := AChartSeries.Source;
// Fit equation
case regression.RegressionType of
rtLinear: ser.FitEquation := feLinear;
case trendline.TrendlineType of
tltLinear: ser.FitEquation := feLinear;
// rtLogarithmic: ser.FitEquation := feLogarithmic; // to do: implement this!
rtExponential: ser.FitEquation := feExp;
rtPower: ser.FitEquation := fePower;
rtPolynomial:
tltExponential: ser.FitEquation := feExp;
tltPower: ser.FitEquation := fePower;
tltPolynomial:
begin
ser.FitEquation := fePolynomial;
ser.ParamCount := regression.PolynomialDegree + 1;
ser.ParamCount := trendline.PolynomialDegree + 1;
end;
end;
// Take care of y intercept
if regression.ForceYIntercept then
if trendline.ForceYIntercept then
begin
str(regression.YInterceptValue, s);
str(trendline.YInterceptValue, s);
ser.FixedParams := s;
end;
// style of regression line
UpdateChartPen(AWorkbookSeries.Chart, regression.Line, ser.Pen);
// style of trend line
UpdateChartPen(AWorkbookSeries.Chart, trendline.Line, ser.Pen);
ser.AxisIndexX := AChartSeries.AxisIndexX;
ser.AxisIndexY := AChartSeries.AxisIndexY;
FChart.AddSeries(ser);
// Legend text
ser.Title := regression.Title;
ser.Title := trendline.Title;
{
// Show fit curve in legend after series.
ser.Legend.Order := AChartseries.Legend.Order + 1;
}
// Regression equation
if regression.DisplayEquation or regression.DisplayRSquare then
// Trendline equation
if trendline.DisplayEquation or trendline.DisplayRSquare then
begin
ser.ExecFit;
s := '';
if regression.DisplayEquation then
if trendline.DisplayEquation then
s := s + ser.EquationText.
X(regression.Equation.XName).
Y(regression.Equation.YName).
NumFormat(Convert_NumFormatStr_to_FormatStr(regression.Equation.NumberFormat)).
X(trendline.Equation.XName).
Y(trendline.Equation.YName).
NumFormat(Convert_NumFormatStr_to_FormatStr(trendline.Equation.NumberFormat)).
DecimalSeparator('.').
TextFormat(tfHtml).
Get;
if regression.DisplayRSquare then
if trendline.DisplayRSquare then
s := s + LineEnding + 'R<sup>2</sup> = ' + FormatFloat('0.00', ser.FitStatistics.R2);
if s <> '' then
ser.Title := ser.Title + LineEnding + s;
@ -2543,7 +2543,7 @@ procedure TsWorkbookChartLink.UpdateCustomLineSeries(AWorkbookSeries: TsCustomLi
AChartSeries: TBasicPointSeries);
var
ppi: Integer;
openedWorkbookSeries: TsCustomLineSeriesOpener absolute AWorkbookSeries;
openedWorkbookSeries: TsOpenedCustomLineSeries absolute AWorkbookSeries;
lineSeries: TLineSeries absolute AChartSeries;
cubicSplineSeries: TCubicSplineSeries absolute AChartSeries;
bSplineSeries: TBSplineSeries absolute AChartSeries;