fpspreadsheet: Radar series support in xlsx chart reader/writer. Fix some issues with radar series in ods.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9222 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
45ec507997
commit
76c0221e9e
@ -51,11 +51,6 @@
|
|||||||
<DebugInfoType Value="dsDwarf3"/>
|
<DebugInfoType Value="dsDwarf3"/>
|
||||||
</Debugging>
|
</Debugging>
|
||||||
</Linking>
|
</Linking>
|
||||||
<Other>
|
|
||||||
<ConfigFile>
|
|
||||||
<WriteConfigFilePath Value=""/>
|
|
||||||
</ConfigFile>
|
|
||||||
</Other>
|
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
<Debugging>
|
<Debugging>
|
||||||
<Exceptions>
|
<Exceptions>
|
||||||
|
@ -12,8 +12,13 @@ var
|
|||||||
book: TsWorkbook;
|
book: TsWorkbook;
|
||||||
sheet: TsWorksheet;
|
sheet: TsWorksheet;
|
||||||
ch: TsChart;
|
ch: TsChart;
|
||||||
ser: TsChartSeries;
|
ser: TsRadarSeries;
|
||||||
|
fn, dir: String;
|
||||||
begin
|
begin
|
||||||
|
dir := ExtractFilePath(ParamStr(0)) + 'files/';
|
||||||
|
ForceDirectories(dir);
|
||||||
|
fn := dir + FILE_NAME;
|
||||||
|
|
||||||
book := TsWorkbook.Create;
|
book := TsWorkbook.Create;
|
||||||
try
|
try
|
||||||
// worksheet
|
// worksheet
|
||||||
@ -51,25 +56,29 @@ begin
|
|||||||
ser.SetLabelRange(3, 0, 10, 0);
|
ser.SetLabelRange(3, 0, 10, 0);
|
||||||
ser.SetYRange(3, 1, 10, 1);
|
ser.SetYRange(3, 1, 10, 1);
|
||||||
ser.Line.Color := scDarkRed;
|
ser.Line.Color := scDarkRed;
|
||||||
ser.Fill.Color := scRed;
|
//ser.Fill.Style := cfsNoFill; // --> non-filled radar chrt
|
||||||
ser.Fill.Transparency := 0.35;
|
ser.ShowSymbols := true;
|
||||||
|
ser.Symbol := cssDiamond;
|
||||||
|
ser.SymbolFill.Style := cfsSolid;
|
||||||
|
ser.SymbolFill.Color := scYellow;
|
||||||
|
// in ods the symbol color is always equal to the line color
|
||||||
|
ser.SymbolWidth := 12; //3;
|
||||||
|
ser.SymbolHeight := 12; // 3;
|
||||||
|
|
||||||
// Add 2nd radar series ("Student 2")
|
// Add 2nd radar series ("Student 2")
|
||||||
ser := TsRadarSeries.Create(ch);
|
ser := TsFilledRadarSeries.Create(ch);
|
||||||
ser.SetTitleAddr(2, 2);
|
ser.SetTitleAddr(2, 2);
|
||||||
ser.SetLabelRange(3, 0, 10, 0);
|
ser.SetLabelRange(3, 0, 10, 0);
|
||||||
ser.SetYRange(3, 2, 10, 2);
|
ser.SetYRange(3, 2, 10, 2);
|
||||||
ser.Line.Color := scDarkBlue;
|
ser.Line.Color := scDarkBlue;
|
||||||
ser.Fill.Color := scBlue;
|
ser.Fill.Color := $FFCC99;
|
||||||
ser.Fill.Transparency := 0.35;
|
ser.Fill.Transparency := 0.35;
|
||||||
|
|
||||||
{
|
book.WriteToFile(fn + '.xlsx', true);
|
||||||
book.WriteToFile(FILE_NAME + '.xlsx', true); // Excel fails to open the file
|
WriteLn('Data saved with chart in ', fn + '.xlsx');
|
||||||
WriteLn('Data saved with chart in ', FILE_NAME, '.xlsx');
|
|
||||||
}
|
|
||||||
|
|
||||||
book.WriteToFile(FILE_NAME + '.ods', true);
|
book.WriteToFile(fn + '.ods', true);
|
||||||
WriteLn('Data saved with chart in ', FILE_NAME, '.ods');
|
WriteLn('Data saved with chart in ', fn + '.ods');
|
||||||
finally
|
finally
|
||||||
book.Free;
|
book.Free;
|
||||||
end;
|
end;
|
||||||
|
@ -6,7 +6,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils,
|
||||||
LCLVersion, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
|
LCLVersion, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, FileUtil,
|
||||||
TAGraph, TASources,
|
TAGraph, TASources,
|
||||||
fpSpreadsheet, fpsTypes, fpsOpenDocument, xlsxOOXML,
|
fpSpreadsheet, fpsTypes, fpsOpenDocument, xlsxOOXML,
|
||||||
fpSpreadsheetCtrls, fpSpreadsheetGrid, fpSpreadsheetChart;
|
fpSpreadsheetCtrls, fpSpreadsheetGrid, fpSpreadsheetChart;
|
||||||
@ -35,6 +35,7 @@ type
|
|||||||
procedure FormCreate(Sender: TObject);
|
procedure FormCreate(Sender: TObject);
|
||||||
procedure sWorkbookSource1Error(Sender: TObject; const AMsg: String);
|
procedure sWorkbookSource1Error(Sender: TObject; const AMsg: String);
|
||||||
private
|
private
|
||||||
|
FDir: String;
|
||||||
sChartLink: TsWorkbookChartLink;
|
sChartLink: TsWorkbookChartLink;
|
||||||
procedure LoadFile(AFileName: String);
|
procedure LoadFile(AFileName: String);
|
||||||
|
|
||||||
@ -114,13 +115,27 @@ procedure TForm1.ComboBox1CloseUp(Sender: TObject);
|
|||||||
begin
|
begin
|
||||||
if ComboBox1.ItemIndex > -1 then
|
if ComboBox1.ItemIndex > -1 then
|
||||||
begin
|
begin
|
||||||
Combobox1.Text := Combobox1.Items[Combobox1.ItemIndex];
|
Combobox1.Text := FDir + Combobox1.Items[Combobox1.ItemIndex];
|
||||||
LoadFile(Combobox1.Text);
|
LoadFile(Combobox1.Text);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TForm1.FormCreate(Sender: TObject);
|
procedure TForm1.FormCreate(Sender: TObject);
|
||||||
|
var
|
||||||
|
L: TStrings;
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
|
FDir := ExpandFileName(Application.Location + '../../../other/chart/files/');
|
||||||
|
L := TStringList.Create;
|
||||||
|
try
|
||||||
|
FindAllFiles(L, FDir, '*.xlsx;*.ods', false);
|
||||||
|
for i := 0 to L.Count-1 do
|
||||||
|
L[i] := ExtractFileName(L[i]);
|
||||||
|
Combobox1.Items.Assign(L);
|
||||||
|
finally
|
||||||
|
L.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
{$IF LCL_FullVersion >= 2020000}
|
{$IF LCL_FullVersion >= 2020000}
|
||||||
ComboBox1.TextHint := 'Enter or select file name';
|
ComboBox1.TextHint := 'Enter or select file name';
|
||||||
{$IFEND}
|
{$IFEND}
|
||||||
|
@ -619,13 +619,12 @@ type
|
|||||||
FSymbolWidth: Double; // in mm
|
FSymbolWidth: Double; // in mm
|
||||||
FShowLines: Boolean;
|
FShowLines: Boolean;
|
||||||
FShowSymbols: Boolean;
|
FShowSymbols: Boolean;
|
||||||
FBorder: TsChartLine;
|
FSymbolBorder: TsChartLine;
|
||||||
function GetSymbolFill: TsChartFill;
|
FSymbolFill: TsChartFill;
|
||||||
procedure SetSymbolFill(Value: TsChartFill);
|
|
||||||
protected
|
protected
|
||||||
property Symbol: TsChartSeriesSymbol read FSymbol write FSymbol;
|
property Symbol: TsChartSeriesSymbol read FSymbol write FSymbol;
|
||||||
property SymbolBorder: TsChartLine read FBorder write FBorder;
|
property SymbolBorder: TsChartLine read FSymbolBorder write FSymbolBorder;
|
||||||
property SymbolFill: TsChartFill read GetSymbolFill write SetSymbolFill;
|
property SymbolFill: TsChartFill read FSymbolFill write FSymbolFill;
|
||||||
property SymbolHeight: double read FSymbolHeight write FSymbolHeight;
|
property SymbolHeight: double read FSymbolHeight write FSymbolHeight;
|
||||||
property SymbolWidth: double read FSymbolWidth write FSymbolWidth;
|
property SymbolWidth: double read FSymbolWidth write FSymbolWidth;
|
||||||
property ShowLines: Boolean read FShowLines write FShowLines;
|
property ShowLines: Boolean read FShowLines write FShowLines;
|
||||||
@ -666,18 +665,15 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
TsRadarSeries = class(TsLineSeries)
|
TsRadarSeries = class(TsLineSeries)
|
||||||
protected
|
|
||||||
function GetChartType: TsChartType; override;
|
|
||||||
end;
|
|
||||||
{
|
|
||||||
TsRingSeries = class(TsPieSeries)
|
|
||||||
private
|
|
||||||
FInnerRadiusPercent: Integer;
|
|
||||||
public
|
public
|
||||||
constructor Create(AChart: TsChart); override;
|
constructor Create(AChart: TsChart); override;
|
||||||
property InnerRadiusPercent: Integer read FInnerRadiusPercent write FInnerRadiusPercent;
|
|
||||||
end;
|
end;
|
||||||
}
|
|
||||||
|
TsFilledRadarSeries = class(TsRadarSeries)
|
||||||
|
public
|
||||||
|
constructor Create(AChart: TsChart); override;
|
||||||
|
end;
|
||||||
|
|
||||||
TsCustomScatterSeries = class(TsCustomLineSeries)
|
TsCustomScatterSeries = class(TsCustomLineSeries)
|
||||||
public
|
public
|
||||||
constructor Create(AChart: TsChart); override;
|
constructor Create(AChart: TsChart); override;
|
||||||
@ -2490,27 +2486,22 @@ begin
|
|||||||
FShowSymbols := false;
|
FShowSymbols := false;
|
||||||
FShowLines := true;
|
FShowLines := true;
|
||||||
|
|
||||||
FBorder := TsChartLine.Create;
|
FSymbolBorder := TsChartLine.Create;
|
||||||
FBorder.Style := clsSolid;
|
FSymbolBorder.Style := clsSolid;
|
||||||
FBorder.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
FSymbolBorder.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
||||||
FBorder.Color := scBlack;
|
FSymbolBorder.Color := scBlack;
|
||||||
|
|
||||||
|
FSymbolFill := TsChartFill.Create;
|
||||||
|
FSymbolFill.Style := cfsNoFill;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TsCustomLineSeries.Destroy;
|
destructor TsCustomLineSeries.Destroy;
|
||||||
begin
|
begin
|
||||||
FBorder.Free;
|
FSymbolBorder.Free;
|
||||||
|
FSymbolFill.Free;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsCustomLineSeries.GetSymbolFill: TsChartFill;
|
|
||||||
begin
|
|
||||||
Result := FFill;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TsCustomLineSeries.SetSymbolFill(Value: TsChartFill);
|
|
||||||
begin
|
|
||||||
FFill := Value;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TsPieSeries }
|
{ TsPieSeries }
|
||||||
constructor TsPieSeries.Create(AChart: TsChart);
|
constructor TsPieSeries.Create(AChart: TsChart);
|
||||||
@ -2545,23 +2536,21 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
{ TsRadarSeries }
|
{ TsRadarSeries }
|
||||||
function TsRadarSeries.GetChartType: TsChartType;
|
constructor TsRadarSeries.Create(AChart: TsChart);
|
||||||
begin
|
|
||||||
if Fill.Style <> cfsNoFill then
|
|
||||||
Result := ctFilledRadar
|
|
||||||
else
|
|
||||||
Result := ctRadar;
|
|
||||||
end;
|
|
||||||
|
|
||||||
(*
|
|
||||||
{ TsRingSeries }
|
|
||||||
constructor TsRingSeries.Create(AChart: TsChart);
|
|
||||||
begin
|
begin
|
||||||
inherited Create(AChart);
|
inherited Create(AChart);
|
||||||
FChartType := ctRing;
|
FChartType := ctRadar;
|
||||||
FLine.Color := scBlack;
|
FFill.Style := cfsNoFill; // to make the series default to ctRadar rather than ctFilledRadar
|
||||||
FInnerRadiusPercent := 50;
|
end;
|
||||||
end; *)
|
|
||||||
|
|
||||||
|
{ TsFilledRadarSeries }
|
||||||
|
constructor TsFilledRadarSeries.Create(AChart: TsChart);
|
||||||
|
begin
|
||||||
|
inherited Create(AChart);
|
||||||
|
FChartType := ctFilledRadar;
|
||||||
|
Fill.Style := cfsSolid;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TsTrendlineEquation }
|
{ TsTrendlineEquation }
|
||||||
|
@ -1491,20 +1491,18 @@ begin
|
|||||||
series := TsBarSeries.Create(AChart);
|
series := TsBarSeries.Create(AChart);
|
||||||
'chart:bubble':
|
'chart:bubble':
|
||||||
series := TsBubbleSeries.Create(AChart);
|
series := TsBubbleSeries.Create(AChart);
|
||||||
// 'chart:circle':
|
|
||||||
// series := TsPieSeries.Create(AChart);
|
|
||||||
'chart:filled-radar':
|
|
||||||
series := TsRadarSeries.Create(AChart);
|
|
||||||
'chart:line':
|
|
||||||
series := TsLineSeries.Create(AChart);
|
|
||||||
'chart:radar':
|
|
||||||
series := TsRadarSeries.Create(AChart);
|
|
||||||
'chart:circle':
|
'chart:circle':
|
||||||
begin
|
begin
|
||||||
series := TsPieSeries.Create(AChart);
|
series := TsPieSeries.Create(AChart);
|
||||||
if FChartType = ctRing then
|
if FChartType = ctRing then
|
||||||
TsPieSeries(series).InnerRadiusPercent := 50;
|
TsPieSeries(series).InnerRadiusPercent := 50;
|
||||||
end;
|
end;
|
||||||
|
'chart:line':
|
||||||
|
series := TsLineSeries.Create(AChart);
|
||||||
|
'chart:radar':
|
||||||
|
series := TsRadarSeries.Create(AChart);
|
||||||
|
'chart:filled-radar':
|
||||||
|
series := TsFilledRadarSeries.Create(AChart);
|
||||||
'chart:scatter':
|
'chart:scatter':
|
||||||
series := TsScatterSeries.Create(AChart);
|
series := TsScatterSeries.Create(AChart);
|
||||||
// 'chart:stock': --- has already been created
|
// 'chart:stock': --- has already been created
|
||||||
@ -1650,6 +1648,13 @@ begin
|
|||||||
if ASeries.ChartType in [ctBar] then
|
if ASeries.ChartType in [ctBar] then
|
||||||
ASeries.Line.Style := clsSolid;
|
ASeries.Line.Style := clsSolid;
|
||||||
GetChartLineProps(AStyleNode, AChart, ASeries.Line);
|
GetChartLineProps(AStyleNode, AChart, ASeries.Line);
|
||||||
|
if ((ASeries is TsRadarSeries) and (ASeries.ChartType = ctRadar)) or (ASeries is TsCustomLineSeries) then
|
||||||
|
begin
|
||||||
|
// In ods, symbols and lines have the same color
|
||||||
|
TsRadarSeries(ASeries).SymbolFill.Style := cfsSolid;
|
||||||
|
TsRadarSeries(ASeries).SymbolFill.Color := ASeries.Line.Color;
|
||||||
|
TsRadarSeries(ASeries).SymbolBorder.Style := clsNoLine;
|
||||||
|
end else
|
||||||
GetChartFillProps(AStyleNode, AChart, ASeries.Fill);
|
GetChartFillProps(AStyleNode, AChart, ASeries.Fill);
|
||||||
end;
|
end;
|
||||||
'style:text-properties':
|
'style:text-properties':
|
||||||
@ -1739,10 +1744,10 @@ begin
|
|||||||
TsOpenedCustomLineSeries(ASeries).Symbol := css;
|
TsOpenedCustomLineSeries(ASeries).Symbol := css;
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
s := GetAttrValue(AStyleNode, 'symbol-width');
|
s := GetAttrValue(AStyleNode, 'chart:symbol-width');
|
||||||
if (s <> '') and EvalLengthStr(s, value, rel) then
|
if (s <> '') and EvalLengthStr(s, value, rel) then
|
||||||
TsOpenedCustomLineSeries(ASeries).SymbolWidth := value;
|
TsOpenedCustomLineSeries(ASeries).SymbolWidth := value;
|
||||||
s := GetAttrValue(AStyleNode, 'symbol-height');
|
s := GetAttrValue(AStyleNode, 'chart:symbol-height');
|
||||||
if (s <> '') and EvalLengthStr(s, value, rel) then
|
if (s <> '') and EvalLengthStr(s, value, rel) then
|
||||||
TsOpenedCustomLineSeries(ASeries).SymbolHeight := value;
|
TsOpenedCustomLineSeries(ASeries).SymbolHeight := value;
|
||||||
end else
|
end else
|
||||||
@ -2607,7 +2612,7 @@ begin
|
|||||||
ciStepCenterY: interpolationStr := 'chart:interpolation="step-center-y" ';
|
ciStepCenterY: interpolationStr := 'chart:interpolation="step-center-y" ';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not (AChart.GetChartType in [ctRadar, ctPie]) then
|
if not (AChart.GetChartType in [ctRadar, ctFilledRadar, ctPie]) then
|
||||||
rightAngledAxes := 'chart:right-angled-axes="true" ';
|
rightAngledAxes := 'chart:right-angled-axes="true" ';
|
||||||
|
|
||||||
for i := 0 to AChart.Series.Count-1 do
|
for i := 0 to AChart.Series.Count-1 do
|
||||||
@ -2784,7 +2789,7 @@ function TsSpreadOpenDocChartWriter.GetChartSeriesStyleAsXML(AChart: TsChart;
|
|||||||
ASeriesIndex, AIndent, AStyleID: Integer): String;
|
ASeriesIndex, AIndent, AStyleID: Integer): String;
|
||||||
var
|
var
|
||||||
series: TsChartSeries;
|
series: TsChartSeries;
|
||||||
lineser: TsLineSeries = nil;
|
lineser: TsOpenedCustomLineSeries = nil;
|
||||||
indent: String;
|
indent: String;
|
||||||
numStyle: String;
|
numStyle: String;
|
||||||
forceNoLine: Boolean = false;
|
forceNoLine: Boolean = false;
|
||||||
@ -2809,7 +2814,7 @@ begin
|
|||||||
if ((series is TsLineSeries) and (series.ChartType <> ctFilledRadar)) or
|
if ((series is TsLineSeries) and (series.ChartType <> ctFilledRadar)) or
|
||||||
(series is TsScatterSeries) then
|
(series is TsScatterSeries) then
|
||||||
begin
|
begin
|
||||||
lineser := TsLineSeries(series);
|
lineser := TsOpenedCustomLineSeries(series);
|
||||||
if lineser.ShowSymbols then
|
if lineser.ShowSymbols then
|
||||||
chartProps := Format(
|
chartProps := Format(
|
||||||
'chart:symbol-type="named-symbol" chart:symbol-name="%s" chart:symbol-width="%.1fmm" chart:symbol-height="%.1fmm" ',
|
'chart:symbol-type="named-symbol" chart:symbol-name="%s" chart:symbol-width="%.1fmm" chart:symbol-height="%.1fmm" ',
|
||||||
@ -2870,9 +2875,10 @@ begin
|
|||||||
|
|
||||||
// Graphic properties
|
// Graphic properties
|
||||||
lineProps := GetChartLineStyleGraphicPropsAsXML(AChart, series.Line, forceNoLine);
|
lineProps := GetChartLineStyleGraphicPropsAsXML(AChart, series.Line, forceNoLine);
|
||||||
fillProps := GetChartFillStyleGraphicPropsAsXML(AChart, series.Fill);
|
|
||||||
if (series is TsLineSeries) and (series.ChartType <> ctFilledRadar) then
|
if (series is TsLineSeries) and (series.ChartType <> ctFilledRadar) then
|
||||||
begin
|
begin
|
||||||
|
lineSer := TsOpenedCustomLineSeries(series);
|
||||||
|
fillProps := GetChartFillStyleGraphicPropsAsXML(AChart, lineser.SymbolFill);
|
||||||
if lineSer.ShowSymbols then
|
if lineSer.ShowSymbols then
|
||||||
graphProps := graphProps + fillProps;
|
graphProps := graphProps + fillProps;
|
||||||
if lineSer.ShowLines and (lineser.Line.Style <> clsNoLine) then
|
if lineSer.ShowLines and (lineser.Line.Style <> clsNoLine) then
|
||||||
@ -2880,7 +2886,10 @@ begin
|
|||||||
else
|
else
|
||||||
graphProps := graphProps + 'draw:stroke="none" ';
|
graphProps := graphProps + 'draw:stroke="none" ';
|
||||||
end else
|
end else
|
||||||
|
begin
|
||||||
|
fillProps := GetChartFillStyleGraphicPropsAsXML(AChart, series.Fill);
|
||||||
graphProps := fillProps + lineProps;
|
graphProps := fillProps + lineProps;
|
||||||
|
end;
|
||||||
|
|
||||||
// Text properties
|
// Text properties
|
||||||
textProps := TsSpreadOpenDocWriter(Writer).WriteFontStyleXMLAsString(series.LabelFont);
|
textProps := TsSpreadOpenDocWriter(Writer).WriteFontStyleXMLAsString(series.LabelFont);
|
||||||
|
@ -102,7 +102,7 @@ type
|
|||||||
procedure WriteChartAxisTitle(AStream: TStream; AIndent: Integer; Axis: TsChartAxis);
|
procedure WriteChartAxisTitle(AStream: TStream; AIndent: Integer; Axis: TsChartAxis);
|
||||||
procedure WriteChartLegendNode(AStream: TStream; AIndent: Integer; ALegend: TsChartLegend);
|
procedure WriteChartLegendNode(AStream: TStream; AIndent: Integer; ALegend: TsChartLegend);
|
||||||
procedure WriteChartPlotAreaNode(AStream: TStream; AIndent: Integer; AChart: TsChart);
|
procedure WriteChartPlotAreaNode(AStream: TStream; AIndent: Integer; AChart: TsChart);
|
||||||
procedure WriteChartRegression(AStream: TStream; AIndent: Integer; ASeries: TsChartSeries);
|
procedure WriteChartTrendline(AStream: TStream; AIndent: Integer; ASeries: TsChartSeries);
|
||||||
procedure WriteChartSeriesDatapointLabels(AStream: TStream; AIndent: Integer; ASeries: TsChartSeries);
|
procedure WriteChartSeriesDatapointLabels(AStream: TStream; AIndent: Integer; ASeries: TsChartSeries);
|
||||||
procedure WriteChartSeriesDatapointStyles(AStream: TStream; AIndent: Integer; ASeries: TsChartSeries);
|
procedure WriteChartSeriesDatapointStyles(AStream: TStream; AIndent: Integer; ASeries: TsChartSeries);
|
||||||
procedure WriteChartSeriesNode(AStream: TStream; AIndent: Integer; ASeries: TsChartSeries; ASeriesIndex: Integer);
|
procedure WriteChartSeriesNode(AStream: TStream; AIndent: Integer; ASeries: TsChartSeries; ASeriesIndex: Integer);
|
||||||
@ -114,6 +114,7 @@ type
|
|||||||
procedure WriteBarSeries(AStream: TStream; AIndent: Integer; ASeries: TsBarSeries; ASeriesIndex: Integer);
|
procedure WriteBarSeries(AStream: TStream; AIndent: Integer; ASeries: TsBarSeries; ASeriesIndex: Integer);
|
||||||
procedure WriteBubbleSeries(AStream: TStream; AIndent: Integer; ASeries: TsBubbleSeries; ASeriesIndex: Integer);
|
procedure WriteBubbleSeries(AStream: TStream; AIndent: Integer; ASeries: TsBubbleSeries; ASeriesIndex: Integer);
|
||||||
procedure WritePieSeries(AStream: TStream; AIndent: Integer; ASeries: TsPieSeries; ASeriesIndex: Integer);
|
procedure WritePieSeries(AStream: TStream; AIndent: Integer; ASeries: TsPieSeries; ASeriesIndex: Integer);
|
||||||
|
procedure WriteRadarSeries(AStream: TStream; AIndent: Integer; ASeries: TsRadarSeries; ASeriesIndex: Integer);
|
||||||
procedure WriteScatterSeries(AStream: TStream; AIndent: Integer; ASeries: TsScatterSeries; ASeriesIndex: Integer);
|
procedure WriteScatterSeries(AStream: TStream; AIndent: Integer; ASeries: TsScatterSeries; ASeriesIndex: Integer);
|
||||||
|
|
||||||
procedure WriteChartLabels(AStream: TStream; AIndent: Integer; AFont: TsFont);
|
procedure WriteChartLabels(AStream: TStream; AIndent: Integer; AFont: TsFont);
|
||||||
@ -1395,7 +1396,7 @@ begin
|
|||||||
if TryStrToInt(s, n) then
|
if TryStrToInt(s, n) then
|
||||||
with TsOpenedCustomLineSeries(ASeries) do
|
with TsOpenedCustomLineSeries(ASeries) do
|
||||||
begin
|
begin
|
||||||
SymbolWidth := PtsToMM(n div 2);
|
SymbolWidth := PtsToMM(n);
|
||||||
SymbolHeight := SymbolWidth;
|
SymbolHeight := SymbolWidth;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1550,28 +1551,47 @@ end;
|
|||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadOOXMLChartReader.ReadChartRadarSeries(ANode: TDOMNode; AChart: TsChart);
|
procedure TsSpreadOOXMLChartReader.ReadChartRadarSeries(ANode: TDOMNode; AChart: TsChart);
|
||||||
var
|
var
|
||||||
nodeName: String;
|
node: TDOMNode;
|
||||||
|
nodeName, s: String;
|
||||||
ser: TsRadarSeries;
|
ser: TsRadarSeries;
|
||||||
radarStyle: String = '';
|
filled: Boolean = false;
|
||||||
begin
|
begin
|
||||||
if ANode = nil then
|
if ANode = nil then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
while Assigned(ANode) do
|
// At first, we need the value of c:radarStyle because it determines the
|
||||||
|
// series class to be created.
|
||||||
|
node := ANode;
|
||||||
|
while Assigned(node) do
|
||||||
begin
|
begin
|
||||||
nodeName := ANode.NodeName;
|
nodeName := node.NodeName;
|
||||||
case nodeName of
|
case nodeName of
|
||||||
'c:radarStyle':
|
'c:radarStyle':
|
||||||
radarStyle := GetAttrValue(ANode, 'val');
|
begin
|
||||||
|
s := GetAttrValue(node, 'val');
|
||||||
|
filled := s = 'filled';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
node := node.NextSibling;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Search the series node. Then create the series and read its properties
|
||||||
|
// from the subnodes.
|
||||||
|
node := ANode;
|
||||||
|
while Assigned(node) do
|
||||||
|
begin
|
||||||
|
nodeName := node.NodeName;
|
||||||
|
case nodeName of
|
||||||
'c:ser':
|
'c:ser':
|
||||||
begin
|
begin
|
||||||
|
if filled then
|
||||||
|
ser := TsFilledRadarSeries.Create(AChart)
|
||||||
|
else
|
||||||
ser := TsRadarSeries.Create(AChart);
|
ser := TsRadarSeries.Create(AChart);
|
||||||
ReadChartSeriesProps(ANode.FirstChild, ser);
|
ReadChartSeriesProps(node.FirstChild, ser);
|
||||||
if radarStyle <> 'filled' then
|
|
||||||
ser.Fill.Style := cfsNoFill;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
ANode := ANode.NextSibling;
|
node := node.NextSibling;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3827,6 +3847,7 @@ var
|
|||||||
markerStr: String;
|
markerStr: String;
|
||||||
chart: TsChart;
|
chart: TsChart;
|
||||||
ser: TsOpenedCustomLineSeries;
|
ser: TsOpenedCustomLineSeries;
|
||||||
|
symbolSizePts: Integer;
|
||||||
begin
|
begin
|
||||||
indent := DupeString(' ', AIndent);
|
indent := DupeString(' ', AIndent);
|
||||||
chart := ASeries.Chart;
|
chart := ASeries.Chart;
|
||||||
@ -3835,7 +3856,7 @@ begin
|
|||||||
if ser.ShowSymbols then
|
if ser.ShowSymbols then
|
||||||
case ser.Symbol of
|
case ser.Symbol of
|
||||||
cssRect: markerStr := 'square';
|
cssRect: markerStr := 'square';
|
||||||
cssDiamond: markerStr := 'diamong';
|
cssDiamond: markerStr := 'diamond';
|
||||||
cssTriangle: markerStr := 'triangle';
|
cssTriangle: markerStr := 'triangle';
|
||||||
cssTriangleDown: markerStr := 'triangle'; // !!!!
|
cssTriangleDown: markerStr := 'triangle'; // !!!!
|
||||||
cssTriangleLeft: markerStr := 'triangle'; // !!!!
|
cssTriangleLeft: markerStr := 'triangle'; // !!!!
|
||||||
@ -3852,13 +3873,16 @@ begin
|
|||||||
else
|
else
|
||||||
markerStr := 'none';
|
markerStr := 'none';
|
||||||
|
|
||||||
|
symbolSizePts := round(mmToPts((ser.SymbolWidth + ser.SymbolHeight)/2));
|
||||||
|
if symbolSizePts > 72 then symbolSizePts := 72;
|
||||||
|
|
||||||
Result := Format(
|
Result := Format(
|
||||||
indent + '<c:symbol val="%s"/>' + LE +
|
indent + '<c:symbol val="%s"/>' + LE +
|
||||||
indent + '<c:size val="%.0f"/>' + LE +
|
indent + '<c:size val="%d"/>' + LE +
|
||||||
indent + '<c:spPr>' + LE +
|
indent + '<c:spPr>' + LE +
|
||||||
GetChartFillAndLineXML(AIndent + 2, chart, ser.SymbolFill, ser.SymbolBorder) + LE +
|
GetChartFillAndLineXML(AIndent + 2, chart, ser.SymbolFill, ser.SymbolBorder) + LE +
|
||||||
indent + '</c:spPr>',
|
indent + '</c:spPr>',
|
||||||
[ markerStr, mmToPts(ser.SymbolWidth + ser.SymbolHeight) ]
|
[ markerStr, symbolSizePts ]
|
||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3903,6 +3927,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
ctPie, ctRing:
|
ctPie, ctRing:
|
||||||
WritePieSeries(AStream, AIndent + 2, TsPieSeries(ser), i);
|
WritePieSeries(AStream, AIndent + 2, TsPieSeries(ser), i);
|
||||||
|
ctRadar, ctFilledRadar:
|
||||||
|
WriteRadarSeries(AStream, AIndent + 2, TsRadarSeries(ser), i);
|
||||||
ctScatter:
|
ctScatter:
|
||||||
begin
|
begin
|
||||||
WriteScatterSeries(AStream, AIndent + 2, TsScatterSeries(ser), i);
|
WriteScatterSeries(AStream, AIndent + 2, TsScatterSeries(ser), i);
|
||||||
@ -3972,6 +3998,39 @@ begin
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadOOXMLChartWriter.WriteRadarSeries(AStream: TStream;
|
||||||
|
AIndent: Integer; ASeries: TsRadarSeries; ASeriesIndex: Integer);
|
||||||
|
var
|
||||||
|
indent: String;
|
||||||
|
chart: TsChart;
|
||||||
|
radarStyle: String;
|
||||||
|
begin
|
||||||
|
indent := DupeString(' ', AIndent);
|
||||||
|
chart := ASeries.Chart;
|
||||||
|
|
||||||
|
if ASeries.ChartType = ctFilledRadar then
|
||||||
|
radarStyle := 'filled'
|
||||||
|
else
|
||||||
|
radarStyle := 'marker';
|
||||||
|
|
||||||
|
AppendToStream(AStream,
|
||||||
|
indent + '<c:radarChart>' + LE +
|
||||||
|
indent + ' <c:radarStyle val="' + radarStyle + '"/>' + LE
|
||||||
|
);
|
||||||
|
|
||||||
|
WriteChartSeriesNode(AStream, AIndent + 4, ASeries, ASeriesIndex);
|
||||||
|
|
||||||
|
AppendToStream(AStream, Format(
|
||||||
|
indent + ' <c:axId val="%d"/>' + LE +
|
||||||
|
indent + ' <c:axId val="%d"/>' + LE +
|
||||||
|
indent + '</c:radarChart>' + LE,
|
||||||
|
[
|
||||||
|
FAxisID[chart.XAxis.Alignment], // <c:axId>
|
||||||
|
FAxisID[chart.YAxis.Alignment] // <c:axId>
|
||||||
|
]
|
||||||
|
));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOOXMLChartWriter.WriteScatterSeries(AStream: TStream;
|
procedure TsSpreadOOXMLChartWriter.WriteScatterSeries(AStream: TStream;
|
||||||
AIndent: Integer; ASeries: TsScatterSeries; ASeriesIndex: Integer);
|
AIndent: Integer; ASeries: TsScatterSeries; ASeriesIndex: Integer);
|
||||||
var
|
var
|
||||||
@ -4015,7 +4074,7 @@ end;
|
|||||||
Writes the <c:trendline> node for the specified chart series if a trendline
|
Writes the <c:trendline> node for the specified chart series if a trendline
|
||||||
is activated.
|
is activated.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadOOXMLChartWriter.WriteChartRegression(AStream: TStream;
|
procedure TsSpreadOOXMLChartWriter.WriteChartTrendline(AStream: TStream;
|
||||||
AIndent: Integer; ASeries: TsChartSeries);
|
AIndent: Integer; ASeries: TsChartSeries);
|
||||||
var
|
var
|
||||||
indent: String;
|
indent: String;
|
||||||
@ -4182,9 +4241,6 @@ var
|
|||||||
xRng, yRng: TsChartRange;
|
xRng, yRng: TsChartRange;
|
||||||
forceNoLine: Boolean;
|
forceNoLine: Boolean;
|
||||||
xValName, yValName, xRefName, yRefName: String;
|
xValName, yValName, xRefName, yRefName: String;
|
||||||
explosionStr: String = '';
|
|
||||||
dps: TsChartDataPointStyle;
|
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
indent := DupeString(' ', AIndent);
|
indent := DupeString(' ', AIndent);
|
||||||
chart := ASeries.Chart;
|
chart := ASeries.Chart;
|
||||||
@ -4217,8 +4273,16 @@ begin
|
|||||||
indent + ' </c:spPr>' + LE
|
indent + ' </c:spPr>' + LE
|
||||||
);
|
);
|
||||||
end else
|
end else
|
||||||
// Line & scatter series: symbol markers
|
// Line & scatter & radar series: symbol markers
|
||||||
if (ASeries is TsCustomLineSeries) then
|
if (ASeries is TsCustomLineSeries) then
|
||||||
|
begin
|
||||||
|
if (ASeries.ChartType = ctFilledRadar) then
|
||||||
|
AppendToStream(AStream,
|
||||||
|
indent + ' <c:spPr>' + LE +
|
||||||
|
GetChartFillAndLineXML(AIndent + 4, chart, ASeries.Fill, ASeries.Line) + LE +
|
||||||
|
indent + ' </c:spPr>' + LE
|
||||||
|
)
|
||||||
|
else
|
||||||
begin
|
begin
|
||||||
forceNoLine := not TsOpenedCustomLineSeries(ASeries).ShowLines;
|
forceNoLine := not TsOpenedCustomLineSeries(ASeries).ShowLines;
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
@ -4226,6 +4290,7 @@ begin
|
|||||||
GetChartLineXML(AIndent + 4, chart, ASeries.Line, forceNoLine) + LE +
|
GetChartLineXML(AIndent + 4, chart, ASeries.Line, forceNoLine) + LE +
|
||||||
indent + ' </c:spPr>' + LE
|
indent + ' </c:spPr>' + LE
|
||||||
);
|
);
|
||||||
|
end;
|
||||||
if TsOpenedCustomLineSeries(ASeries).ShowSymbols then
|
if TsOpenedCustomLineSeries(ASeries).ShowSymbols then
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
indent + ' <c:marker>' + LE +
|
indent + ' <c:marker>' + LE +
|
||||||
@ -4242,7 +4307,7 @@ begin
|
|||||||
|
|
||||||
// Trend line
|
// Trend line
|
||||||
if ASeries.SupportsTrendline then
|
if ASeries.SupportsTrendline then
|
||||||
WriteChartRegression(AStream, AIndent + 2, ASeries);
|
WriteChartTrendline(AStream, AIndent + 2, ASeries);
|
||||||
|
|
||||||
// Data point labels
|
// Data point labels
|
||||||
WriteChartSeriesDatapointLabels(AStream, AIndent + 2, ASeries);
|
WriteChartSeriesDatapointLabels(AStream, AIndent + 2, ASeries);
|
||||||
|
@ -550,10 +550,11 @@ begin
|
|||||||
if FIntegerX then
|
if FIntegerX then
|
||||||
value := trunc(value);
|
value := trunc(value);
|
||||||
end else
|
end else
|
||||||
if FCyclicX then
|
|
||||||
value := AIndex / FPointsNumber * TWO_PI
|
|
||||||
else
|
|
||||||
value := AIndex;
|
value := AIndex;
|
||||||
|
// For polar series we rescale the x values to a full circle.
|
||||||
|
// And the angle begins at the 90° position.
|
||||||
|
if FCyclicX then
|
||||||
|
value := value / FPointsNumber * TWO_PI + pi/2;
|
||||||
FCurItem.SetX(i, value);
|
FCurItem.SetX(i, value);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2651,8 +2652,8 @@ begin
|
|||||||
UpdateChartBrush(AWorkbookSeries.Chart, openedWorkbookSeries.SymbolFill, seriesPointer.Brush);
|
UpdateChartBrush(AWorkbookSeries.Chart, openedWorkbookSeries.SymbolFill, seriesPointer.Brush);
|
||||||
UpdateChartPen(AWorkbookSeries.Chart, openedWorkbookSeries.SymbolBorder, seriesPointer.Pen);
|
UpdateChartPen(AWorkbookSeries.Chart, openedWorkbookSeries.SymbolBorder, seriesPointer.Pen);
|
||||||
seriesPointer.Style := POINTER_STYLES[openedWorkbookSeries.Symbol];
|
seriesPointer.Style := POINTER_STYLES[openedWorkbookSeries.Symbol];
|
||||||
seriesPointer.HorizSize := mmToPx(openedWorkbookSeries.SymbolWidth, ppi);
|
seriesPointer.HorizSize := mmToPx(openedWorkbookSeries.SymbolWidth / 2, ppi);
|
||||||
seriesPointer.VertSize := mmToPx(openedWorkbookSeries.SymbolHeight, ppi);
|
seriesPointer.VertSize := mmToPx(openedWorkbookSeries.SymbolHeight / 2, ppi);
|
||||||
|
|
||||||
// Error bars
|
// Error bars
|
||||||
UpdateChartErrorBars(AWorkbookSeries, AChartSeries);
|
UpdateChartErrorBars(AWorkbookSeries, AChartSeries);
|
||||||
@ -2694,14 +2695,15 @@ begin
|
|||||||
(AChartSeries.Source as TsWorkbookChartSource).CyclicX := true;
|
(AChartSeries.Source as TsWorkbookChartSource).CyclicX := true;
|
||||||
|
|
||||||
UpdateChartPen(AWorkbookSeries.Chart, AWorkbookSeries.Line, AChartSeries.LinePen);
|
UpdateChartPen(AWorkbookSeries.Chart, AWorkbookSeries.Line, AChartSeries.LinePen);
|
||||||
|
if AWorkbookSeries.ChartType = ctFilledRadar then
|
||||||
UpdateChartBrush(AWorkbookSeries.Chart, AWorkbookSeries.Fill, AChartSeries.Brush);
|
UpdateChartBrush(AWorkbookSeries.Chart, AWorkbookSeries.Fill, AChartSeries.Brush);
|
||||||
if AWorkbookSeries.ShowSymbols then
|
if AWorkbookSeries.ShowSymbols then
|
||||||
begin
|
begin
|
||||||
UpdateChartBrush(AWorkbookSeries.Chart, AWorkbookSeries.SymbolFill, AChartSeries.Pointer.Brush);
|
UpdateChartBrush(AWorkbookSeries.Chart, AWorkbookSeries.SymbolFill, AChartSeries.Pointer.Brush);
|
||||||
UpdateChartPen(AWorkbookSeries.Chart, AWorkbookSeries.SymbolBorder, AChartSeries.Pointer.Pen);
|
UpdateChartPen(AWorkbookSeries.Chart, AWorkbookSeries.SymbolBorder, AChartSeries.Pointer.Pen);
|
||||||
AChartSeries.Pointer.Style := POINTER_STYLES[AWorkbookSeries.Symbol];
|
AChartSeries.Pointer.Style := POINTER_STYLES[AWorkbookSeries.Symbol];
|
||||||
AChartSeries.Pointer.HorizSize := mmToPx(AWorkbookSeries.SymbolWidth, ppi);
|
AChartSeries.Pointer.HorizSize := mmToPx(AWorkbookSeries.SymbolWidth / 2, ppi);
|
||||||
AChartSeries.Pointer.VertSize := mmToPx(AWorkbookSeries.SymbolHeight, ppi);
|
AChartSeries.Pointer.VertSize := mmToPx(AWorkbookSeries.SymbolHeight / 2, ppi);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
FChart.LeftAxis.Minors.Clear;
|
FChart.LeftAxis.Minors.Clear;
|
||||||
|
Loading…
Reference in New Issue
Block a user