You've already forked lazarus-ccr
fpspreadsheet: ods reader supports chart series.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9021 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -7,13 +7,16 @@ uses
|
|||||||
const
|
const
|
||||||
// FILE_NAME = 'test.ods';
|
// FILE_NAME = 'test.ods';
|
||||||
// FILE_NAME = 'area.ods';
|
// FILE_NAME = 'area.ods';
|
||||||
FILE_NAME = 'bars.ods';
|
// FILE_NAME = 'bars.ods';
|
||||||
|
FILE_NAME = 'regression.ods';
|
||||||
|
// FILE_NAME = 'pie.ods';
|
||||||
|
// FILE_NAME = 'radar.ods';
|
||||||
var
|
var
|
||||||
book: TsWorkbook;
|
book: TsWorkbook;
|
||||||
sheet: TsWorksheet;
|
sheet: TsWorksheet;
|
||||||
chart: TsChart;
|
chart: TsChart;
|
||||||
|
series: TsChartSeries;
|
||||||
i, j: Integer;
|
i, j: Integer;
|
||||||
s: String;
|
|
||||||
isODS: Boolean;
|
isODS: Boolean;
|
||||||
begin
|
begin
|
||||||
isODS := ExtractFileExt(FILE_NAME) = '.ods';
|
isODS := ExtractFileExt(FILE_NAME) = '.ods';
|
||||||
@ -194,6 +197,47 @@ begin
|
|||||||
' Width:', chart.YAxis.MinorGridLines.Width:0:0, 'mm',
|
' Width:', chart.YAxis.MinorGridLines.Width:0:0, 'mm',
|
||||||
' Color:', IntToHex(chart.YAxis.MinorGridLines.Color, 6),
|
' Color:', IntToHex(chart.YAxis.MinorGridLines.Color, 6),
|
||||||
' Transparency:', chart.YAxis.MinorGridLines.Transparency:0:2);
|
' Transparency:', chart.YAxis.MinorGridLines.Transparency:0:2);
|
||||||
|
|
||||||
|
for j := 0 to chart.Series.Count-1 do
|
||||||
|
begin
|
||||||
|
series := chart.Series[j];
|
||||||
|
WriteLn;
|
||||||
|
WriteLn(' SERIES #', j, ': ', series.ClassName);
|
||||||
|
with series.TitleAddr do
|
||||||
|
WriteLn(' TITLE: ', GetCellRangeString(Sheet, Sheet, Row, Col, Row, Col, rfAllRel, false));
|
||||||
|
with series.LabelRange do
|
||||||
|
WriteLn(' LABEL RANGE: ', GetCellRangeString(Sheet1, Sheet2, Row1, Col1, Row2, Col2, rfAllRel, false));
|
||||||
|
if (series is TsScatterSeries) or (series is TsBubbleSeries) then with series.XRange do
|
||||||
|
WriteLn(' X RANGE: ', GetCellRangeString(Sheet1, Sheet2, Row1, Col1, Row2, Col2, rfAllRel, false));
|
||||||
|
with series.YRange do
|
||||||
|
WriteLn(' Y RANGE: ', GetCellRangeString(Sheet1, Sheet2, Row1, Col1, Row2, Col2, rfAllRel, false));
|
||||||
|
with series.FillColorRange do
|
||||||
|
WriteLn(' FILL COLOR RANGE: ', GetCellRangeString(Sheet1, Sheet2, Row1, Col1, Row2, Col2, rfAllRel, false));
|
||||||
|
with series.LineColorRange do
|
||||||
|
WriteLn(' LINE COLOR RANGE: ', GetCellRangeString(Sheet1, Sheet2, Row1, Col1, Row2, Col2, rfAllRel, false));
|
||||||
|
if series is TsBubbleSeries then with TsBubbleSeries(series).BubbleRange do
|
||||||
|
WriteLn(' BUBBLE RANGE: ', GetCellRangeString(Sheet1, Sheet2, Row1, Col1, Row2, Col2, rfAllRel, false));
|
||||||
|
if series is TsLineSeries then with TsLineSeries(series) do
|
||||||
|
begin
|
||||||
|
Write(' SYMBOLS: ');
|
||||||
|
if ShowSymbols then
|
||||||
|
WriteLn('Symbol:', GetEnumName(TypeInfo(TsChartSeriesSymbol), ord(Symbol)),
|
||||||
|
' Width:', SymbolWidth:0:1, 'mm',
|
||||||
|
' Height:', SymbolHeight:0:1, 'mm')
|
||||||
|
else
|
||||||
|
WriteLn('none');
|
||||||
|
end;
|
||||||
|
|
||||||
|
WriteLn(' FILL: Style:', GetEnumName(TypeInfo(TsChartFillStyle), ord(series.Fill.Style)),
|
||||||
|
' Color:', IntToHex(series.Fill.Color, 6),
|
||||||
|
' Gradient:', series.Fill.Gradient,
|
||||||
|
' Hatch:', series.Fill.Hatch,
|
||||||
|
' Transparency:', series.Fill.Transparency:0:2);
|
||||||
|
WriteLn(' LINES: Style:', series.Line.Style,
|
||||||
|
' Width:', series.Line.Width:0:0, 'mm',
|
||||||
|
' Color:', IntToHex(series.Line.Color, 6),
|
||||||
|
' Transparency:', series.Line.Transparency:0:2);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
finally
|
finally
|
||||||
|
@ -165,7 +165,7 @@ type
|
|||||||
procedure Assign(ASource: TsChartRange);
|
procedure Assign(ASource: TsChartRange);
|
||||||
function GetSheet1Name: String;
|
function GetSheet1Name: String;
|
||||||
function GetSheet2Name: String;
|
function GetSheet2Name: String;
|
||||||
function IsUsed: Boolean;
|
function IsEmpty: Boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TsChartElement = class
|
TsChartElement = class
|
||||||
@ -298,6 +298,7 @@ type
|
|||||||
FXRange: TsChartRange; // cell range containing the x data
|
FXRange: TsChartRange; // cell range containing the x data
|
||||||
FYRange: TsChartRange;
|
FYRange: TsChartRange;
|
||||||
FFillColorRange: TsChartRange;
|
FFillColorRange: TsChartRange;
|
||||||
|
FLineColorRange: TsChartRange;
|
||||||
FLabelRange: TsChartRange;
|
FLabelRange: TsChartRange;
|
||||||
FLabelFont: TsFont;
|
FLabelFont: TsFont;
|
||||||
FLabelPosition: TsChartLabelPosition;
|
FLabelPosition: TsChartLabelPosition;
|
||||||
@ -329,6 +330,8 @@ type
|
|||||||
procedure SetYRange(ASheet1: String; ARow1, ACol1: Cardinal; ASheet2: String; ARow2, ACol2: Cardinal);
|
procedure SetYRange(ASheet1: String; ARow1, ACol1: Cardinal; ASheet2: String; ARow2, ACol2: Cardinal);
|
||||||
procedure SetFillColorRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
procedure SetFillColorRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
||||||
procedure SetFillColorRange(ASheet1: String; ARow1, ACol1: Cardinal; ASheet2: String; ARow2, ACol2: Cardinal);
|
procedure SetFillColorRange(ASheet1: String; ARow1, ACol1: Cardinal; ASheet2: String; ARow2, ACol2: Cardinal);
|
||||||
|
procedure SetLineColorRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
||||||
|
procedure SetLineColorRange(ASheet1: String; ARow1, ACol1: Cardinal; ASheet2: String; ARow2, ACol2: Cardinal);
|
||||||
function LabelsInCol: Boolean;
|
function LabelsInCol: Boolean;
|
||||||
function XValuesInCol: Boolean;
|
function XValuesInCol: Boolean;
|
||||||
function YValuesInCol: Boolean;
|
function YValuesInCol: Boolean;
|
||||||
@ -336,15 +339,16 @@ type
|
|||||||
property ChartType: TsChartType read GetChartType;
|
property ChartType: TsChartType read GetChartType;
|
||||||
property Count: Integer read GetCount;
|
property Count: Integer read GetCount;
|
||||||
property DataLabels: TsChartDataLabels read FDataLabels write FDataLabels;
|
property DataLabels: TsChartDataLabels read FDataLabels write FDataLabels;
|
||||||
property FillColorRange: TsChartRange read FFillColorRange;
|
property FillColorRange: TsChartRange read FFillColorRange write FFillColorRange;
|
||||||
property LabelFont: TsFont read FLabelFont write FLabelFont;
|
property LabelFont: TsFont read FLabelFont write FLabelFont;
|
||||||
property LabelFormat: String read FLabelFormat write FLabelFormat; // Number format in Excel notation, e.g. '0.00'
|
property LabelFormat: String read FLabelFormat write FLabelFormat; // Number format in Excel notation, e.g. '0.00'
|
||||||
property LabelPosition: TsChartLabelPosition read FLabelPosition write FLabelPosition;
|
property LabelPosition: TsChartLabelPosition read FLabelPosition write FLabelPosition;
|
||||||
property LabelRange: TsChartRange read FLabelRange;
|
property LabelRange: TsChartRange read FLabelRange write FLabelRange;
|
||||||
property LabelSeparator: string read FLabelSeparator write FLabelSeparator;
|
property LabelSeparator: string read FLabelSeparator write FLabelSeparator;
|
||||||
|
property LineColorRange: TsChartRange read FLineColorRange write FLineColorRange;
|
||||||
property TitleAddr: TsChartCellAddr read FTitleAddr write FTitleAddr; // use '\n' for line-break
|
property TitleAddr: TsChartCellAddr read FTitleAddr write FTitleAddr; // use '\n' for line-break
|
||||||
property XRange: TsChartRange read FXRange;
|
property XRange: TsChartRange read FXRange write FXRange;
|
||||||
property YRange: TsChartRange read FYRange;
|
property YRange: TsChartRange read FYRange write FYRange;
|
||||||
property YAxis: TsChartAxisLink read FYAxis write FYAxis;
|
property YAxis: TsChartAxisLink read FYAxis write FYAxis;
|
||||||
|
|
||||||
property Fill: TsChartFill read FFill write FFill;
|
property Fill: TsChartFill read FFill write FFill;
|
||||||
@ -898,11 +902,11 @@ begin
|
|||||||
Result := FChart.GetWorksheet.Name;
|
Result := FChart.GetWorksheet.Name;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsChartRange.IsUsed: Boolean;
|
function TsChartRange.IsEmpty: Boolean;
|
||||||
begin
|
begin
|
||||||
Result :=
|
Result :=
|
||||||
(Row1 <> UNASSIGNED_ROW_COL_INDEX) and (Col1 <> UNASSIGNED_ROW_COL_INDEX) and
|
(Row1 = UNASSIGNED_ROW_COL_INDEX) and (Col1 = UNASSIGNED_ROW_COL_INDEX) and
|
||||||
(Row2 <> UNASSIGNED_ROW_COL_INDEX) and (Col2 <> UNASSIGNED_ROW_COL_INDEX);
|
(Row2 = UNASSIGNED_ROW_COL_INDEX) and (Col2 = UNASSIGNED_ROW_COL_INDEX);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1044,6 +1048,7 @@ begin
|
|||||||
FXRange := TsChartRange.Create(AChart);
|
FXRange := TsChartRange.Create(AChart);
|
||||||
FYRange := TsChartRange.Create(AChart);
|
FYRange := TsChartRange.Create(AChart);
|
||||||
FFillColorRange := TsChartRange.Create(AChart);
|
FFillColorRange := TsChartRange.Create(AChart);
|
||||||
|
FLineColorRange := TsChartRange.Create(AChart);
|
||||||
FLabelRange := TsChartRange.Create(AChart);
|
FLabelRange := TsChartRange.Create(AChart);
|
||||||
FTitleAddr := TsChartCellAddr.Create(AChart);
|
FTitleAddr := TsChartCellAddr.Create(AChart);
|
||||||
|
|
||||||
@ -1070,6 +1075,7 @@ begin
|
|||||||
FFill.Free;
|
FFill.Free;
|
||||||
FTitleAddr.Free;
|
FTitleAddr.Free;
|
||||||
FLabelRange.Free;
|
FLabelRange.Free;
|
||||||
|
FLineColorRange.Free;
|
||||||
FFillColorRange.Free;
|
FFillColorRange.Free;
|
||||||
FYRange.Free;
|
FYRange.Free;
|
||||||
FXRange.Free;
|
FXRange.Free;
|
||||||
@ -1173,6 +1179,24 @@ begin
|
|||||||
FLabelRange.Col2 := ACol2;
|
FLabelRange.Col2 := ACol2;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsChartSeries.SetLineColorRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
||||||
|
begin
|
||||||
|
SetLineColorRange('', ARow1, ACol1, '', ARow2, ACol2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsChartSeries.SetLineColorRange(ASheet1: String; ARow1, ACol1: Cardinal;
|
||||||
|
ASheet2: String; ARow2, ACol2: Cardinal);
|
||||||
|
begin
|
||||||
|
if (ARow1 <> ARow2) and (ACol1 <> ACol2) then
|
||||||
|
raise Exception.Create('Series line color values can only be located in a single column or row.');
|
||||||
|
FLineColorRange.Sheet1 := ASHeet1;
|
||||||
|
FLineColorRange.Row1 := ARow1;
|
||||||
|
FLineColorRange.Col1 := ACol1;
|
||||||
|
FLineColorRange.Sheet2 := ASheet2;
|
||||||
|
FLineColorRange.Row2 := ARow2;
|
||||||
|
FLineColorRange.Col2 := ACol2;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsChartSeries.SetXRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
procedure TsChartSeries.SetXRange(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
||||||
begin
|
begin
|
||||||
SetXRange('', ARow1, ACol1, '', ARow2, ACol2);
|
SetXRange('', ARow1, ACol1, '', ARow2, ACol2);
|
||||||
|
@ -15,6 +15,9 @@ uses
|
|||||||
fpsTypes, fpSpreadsheet, fpsChart, fpsUtils, fpsReaderWriter, fpsXMLCommon;
|
fpsTypes, fpSpreadsheet, fpsChart, fpsUtils, fpsReaderWriter, fpsXMLCommon;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
|
{ TsSpreadOpenDocChartReader }
|
||||||
|
|
||||||
TsSpreadOpenDocChartReader = class(TsBasicSpreadChartReader)
|
TsSpreadOpenDocChartReader = class(TsBasicSpreadChartReader)
|
||||||
private
|
private
|
||||||
FChartFiles: TStrings;
|
FChartFiles: TStrings;
|
||||||
@ -27,12 +30,15 @@ type
|
|||||||
procedure ReadChartAxisProps(ANode, AStyleNode: TDOMNode; AChart: TsChart);
|
procedure ReadChartAxisProps(ANode, AStyleNode: TDOMNode; AChart: TsChart);
|
||||||
procedure ReadChartAxisStyle(AStyleNode: TDOMNode; AChart: TsChart; Axis: TsChartAxis);
|
procedure ReadChartAxisStyle(AStyleNode: TDOMNode; AChart: TsChart; Axis: TsChartAxis);
|
||||||
procedure ReadChartBackgroundStyle(AStyleNode: TDOMNode; AChart: TsChart);
|
procedure ReadChartBackgroundStyle(AStyleNode: TDOMNode; AChart: TsChart);
|
||||||
|
procedure ReadChartCellAddr(ANode: TDOMNode; ANodeName: String; ACellAddr: TsChartCellAddr);
|
||||||
procedure ReadChartCellRange(ANode: TDOMNode; ANodeName: String; ARange: TsChartRange);
|
procedure ReadChartCellRange(ANode: TDOMNode; ANodeName: String; ARange: TsChartRange);
|
||||||
procedure ReadChartProps(AChartNode, AStyleNode: TDOMNode; AChart: TsChart);
|
procedure ReadChartProps(AChartNode, AStyleNode: TDOMNode; AChart: TsChart);
|
||||||
procedure ReadChartPlotAreaProps(ANode, AStyleNode: TDOMNode; AChart: TsChart);
|
procedure ReadChartPlotAreaProps(ANode, AStyleNode: TDOMNode; AChart: TsChart);
|
||||||
procedure ReadChartPlotAreaStyle(AStyleNode: TDOMNode; AChart: TsChart);
|
procedure ReadChartPlotAreaStyle(AStyleNode: TDOMNode; AChart: TsChart);
|
||||||
procedure ReadChartLegendProps(ANode, AStyleNode: TDOMNode; AChart: TsChart);
|
procedure ReadChartLegendProps(ANode, AStyleNode: TDOMNode; AChart: TsChart);
|
||||||
procedure ReadChartLegendStyle(AStyleNode: TDOMNode; AChart: TsChart);
|
procedure ReadChartLegendStyle(AStyleNode: TDOMNode; AChart: TsChart);
|
||||||
|
procedure ReadChartSeriesProps(ANode, AStyleNode: TDOMNode; AChart: TsChart);
|
||||||
|
procedure ReadChartSeriesStyle(AStyleNode: TDOMNode; AChart: TsChart; ASeries: TsChartSeries);
|
||||||
procedure ReadChartTitleProps(ANode, AStyleNode: TDOMNode; AChart: TsChart; ATitle: TsChartText);
|
procedure ReadChartTitleProps(ANode, AStyleNode: TDOMNode; AChart: TsChart; ATitle: TsChartText);
|
||||||
procedure ReadChartTitleStyle(AStyleNode: TDOMNode; AChart: TsChart; ATitle: TsChartText);
|
procedure ReadChartTitleStyle(AStyleNode: TDOMNode; AChart: TsChart; ATitle: TsChartText);
|
||||||
|
|
||||||
@ -78,7 +84,7 @@ type
|
|||||||
|
|
||||||
function GetNumberFormatID(ANumFormat: String): String;
|
function GetNumberFormatID(ANumFormat: String): String;
|
||||||
procedure ListAllNumberFormats(AChart: TsChart);
|
procedure ListAllNumberFormats(AChart: TsChart);
|
||||||
procedure PrepareChartTable(AChart: TsChart; AWorksheet: TsBasicWorksheet);
|
// procedure PrepareChartTable(AChart: TsChart; AWorksheet: TsBasicWorksheet);
|
||||||
|
|
||||||
protected
|
protected
|
||||||
// Object X/styles.xml
|
// Object X/styles.xml
|
||||||
@ -633,6 +639,23 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadOpenDocChartReader.ReadChartCellAddr(ANode: TDOMNode;
|
||||||
|
ANodeName: String; ACellAddr: TsChartCellAddr);
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
sh1, sh2: String;
|
||||||
|
r1, c1, r2, c2: Cardinal;
|
||||||
|
relFlags: TsRelFlags;
|
||||||
|
begin
|
||||||
|
s := GetAttrValue(ANode, ANodeName);
|
||||||
|
if (s <> '') and TryStrToCellRange_ODS(s, sh1, sh2, r1, c1, r2, c2, relFlags) then
|
||||||
|
begin
|
||||||
|
ACellAddr.Sheet := sh1;
|
||||||
|
ACellAddr.Row := r1;
|
||||||
|
ACellAddr.Col := c1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocChartReader.ReadChartCellRange(ANode: TDOMNode;
|
procedure TsSpreadOpenDocChartReader.ReadChartCellRange(ANode: TDOMNode;
|
||||||
ANodeName: String; ARange: TsChartRange);
|
ANodeName: String; ARange: TsChartRange);
|
||||||
var
|
var
|
||||||
@ -768,6 +791,8 @@ begin
|
|||||||
case nodeName of
|
case nodeName of
|
||||||
'chart:axis':
|
'chart:axis':
|
||||||
ReadChartAxisProps(ANode, AStyleNode, AChart);
|
ReadChartAxisProps(ANode, AStyleNode, AChart);
|
||||||
|
'chart:series':
|
||||||
|
ReadChartSeriesProps(ANode, AStyleNode, AChart);
|
||||||
end;
|
end;
|
||||||
ANode := ANode.NextSibling;
|
ANode := ANode.NextSibling;
|
||||||
end;
|
end;
|
||||||
@ -855,6 +880,127 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadOpenDocChartReader.ReadChartSeriesProps(ANode, AStyleNode: TDOMNode;
|
||||||
|
AChart: TsChart);
|
||||||
|
var
|
||||||
|
s, nodeName: String;
|
||||||
|
series: TsChartSeries;
|
||||||
|
subNode: TDOMNode;
|
||||||
|
styleNode: TDOMNode;
|
||||||
|
xyCounter: Integer;
|
||||||
|
begin
|
||||||
|
s := GetAttrValue(ANode, 'chart:class');
|
||||||
|
case s of
|
||||||
|
'chart:area': series := TsAreaSeries.Create(AChart);
|
||||||
|
'chart:bar': series := TsBarSeries.Create(AChart);
|
||||||
|
'chart:bubble': 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:ring': series := TsRingSeries.Create(AChart);
|
||||||
|
'chart:scatter': series := TsScatterSeries.Create(AChart);
|
||||||
|
else raise Exception.Create('Unknown/unsupported series type.');
|
||||||
|
end;
|
||||||
|
AChart.AddSeries(series);
|
||||||
|
|
||||||
|
ReadChartCellAddr(ANode, 'chart:label-cell-address', series.TitleAddr);
|
||||||
|
if (series is TsBubbleSeries) then
|
||||||
|
ReadChartCellRange(ANode, 'chart:values-cell-range-address', TsBubbleSeries(series).BubbleRange)
|
||||||
|
else
|
||||||
|
ReadChartCellRange(ANode, 'chart:values-cell-range-address', series.YRange);
|
||||||
|
|
||||||
|
xyCounter := 0;
|
||||||
|
subnode := ANode.FirstChild;
|
||||||
|
while subnode <> nil do
|
||||||
|
begin
|
||||||
|
nodeName := subNode.NodeName;
|
||||||
|
case nodeName of
|
||||||
|
'chart:domain':
|
||||||
|
begin
|
||||||
|
if xyCounter = 0 then
|
||||||
|
begin
|
||||||
|
ReadChartCellRange(subnode, 'table:cell-range-address', series.XRange);
|
||||||
|
inc(xyCounter);
|
||||||
|
end else
|
||||||
|
if xyCounter = 1 then
|
||||||
|
begin
|
||||||
|
series.YRange.Assign(series.XRange);
|
||||||
|
ReadChartCellRange(subnode, 'table:cell-range-address', series.XRange)
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
'loext:property-mapping':
|
||||||
|
begin
|
||||||
|
s := GetAttrValue(subnode, 'loext:property');
|
||||||
|
case s of
|
||||||
|
'FillColor':
|
||||||
|
ReadChartCellRange(subNode, 'loext:cell-range-address', series.FillColorRange);
|
||||||
|
'BorderColor':
|
||||||
|
ReadChartCellRange(subNode, 'loext:cell-range-address', series.LineColorRange);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
subnode := subNode.NextSibling;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if series.LabelRange.IsEmpty then series.LabelRange.Assign(AChart.XAxis.CategoryRange);
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'chart:style-name');
|
||||||
|
styleNode := FindStyleNode(AStyleNode, s);
|
||||||
|
ReadChartSeriesStyle(styleNode, AChart, series);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadOpenDocChartReader.ReadChartSeriesStyle(AStyleNode: TDOMNode;
|
||||||
|
AChart: TsChart; ASeries: TsChartSeries);
|
||||||
|
var
|
||||||
|
nodeName: String;
|
||||||
|
s: String;
|
||||||
|
css: TsChartSeriesSymbol;
|
||||||
|
value: Double;
|
||||||
|
rel: Boolean;
|
||||||
|
begin
|
||||||
|
nodeName := AStyleNode.NodeName;
|
||||||
|
AStyleNode := AStyleNode.FirstChild;
|
||||||
|
while AStyleNode <> nil do begin
|
||||||
|
nodeName := AStyleNode.NodeName;
|
||||||
|
case nodeName of
|
||||||
|
'style:graphic-properties':
|
||||||
|
begin
|
||||||
|
GetChartLineProps(AStyleNode, AChart, ASeries.Line);
|
||||||
|
GetChartFillProps(AStyleNode, AChart, ASeries.Fill);
|
||||||
|
end;
|
||||||
|
'style:text-properties':
|
||||||
|
TsSpreadOpenDocReader(Reader).ReadFont(AStyleNode, ASeries.LabelFont);
|
||||||
|
'style:chart-properties':
|
||||||
|
begin
|
||||||
|
if (ASeries is TsLineSeries) then
|
||||||
|
begin
|
||||||
|
s := GetAttrValue(AStyleNode, 'chart:symbol-name');
|
||||||
|
if s <> '' then
|
||||||
|
begin
|
||||||
|
TsLineSeries(ASeries).ShowSymbols := true;
|
||||||
|
for css in TsChartSeriesSymbol do
|
||||||
|
if SYMBOL_NAMES[css] = s then
|
||||||
|
begin
|
||||||
|
TsLineSeries(ASeries).Symbol := css;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
s := GetAttrValue(AStyleNode, 'symbol-width');
|
||||||
|
if (s <> '') and EvalLengthStr(s, value, rel) then
|
||||||
|
TsLineSeries(ASeries).SymbolWidth := value;
|
||||||
|
s := GetAttrValue(AStyleNode, 'symbol-height');
|
||||||
|
if (s <> '') and EvalLengthStr(s, value, rel) then
|
||||||
|
TsLineSeries(ASeries).SymbolHeight := value;
|
||||||
|
end else
|
||||||
|
TsLineSeries(ASeries).ShowSymbols := false;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
AStyleNode := AStyleNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocChartReader.ReadChartTitleProps(ANode, AStyleNode: TDOMNode;
|
procedure TsSpreadOpenDocChartReader.ReadChartTitleProps(ANode, AStyleNode: TDOMNode;
|
||||||
AChart: TsChart; ATitle: TsChartText);
|
AChart: TsChart; ATitle: TsChartText);
|
||||||
var
|
var
|
||||||
@ -1823,6 +1969,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
(* DO NOT DELETE THIS! MAYBE NEEDED LATER...
|
||||||
|
|
||||||
{ Extracts the cells needed by the given chart from the chart's worksheet and
|
{ Extracts the cells needed by the given chart from the chart's worksheet and
|
||||||
copies their values into a temporary worksheet, AWorksheet, so that these
|
copies their values into a temporary worksheet, AWorksheet, so that these
|
||||||
@ -1998,6 +2145,7 @@ begin
|
|||||||
auxSheet.WriteComment(1, destCol, refStr); // Store y range reference as comment for svg node
|
auxSheet.WriteComment(1, destCol, refStr); // Store y range reference as comment for svg node
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
*)
|
||||||
|
|
||||||
procedure TsSpreadOpenDocChartWriter.ResetStreams;
|
procedure TsSpreadOpenDocChartWriter.ResetStreams;
|
||||||
var
|
var
|
||||||
@ -2594,6 +2742,7 @@ var
|
|||||||
domainRangeX: String = '';
|
domainRangeX: String = '';
|
||||||
domainRangeY: String = '';
|
domainRangeY: String = '';
|
||||||
fillColorRange: String = '';
|
fillColorRange: String = '';
|
||||||
|
lineColorRange: String = '';
|
||||||
chartClass: String = '';
|
chartClass: String = '';
|
||||||
regressionEquation: String = '';
|
regressionEquation: String = '';
|
||||||
needRegressionStyle: Boolean = false;
|
needRegressionStyle: Boolean = false;
|
||||||
@ -2656,6 +2805,15 @@ begin
|
|||||||
rfAllRel, false
|
rfAllRel, false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Line colors for bars, line series symbols, bubbles etc.
|
||||||
|
if not series.LineColorRange.IsEmpty then
|
||||||
|
lineColorRange := GetSheetCellRangeString_ODS(
|
||||||
|
series.LineColorRange.GetSheet1Name, series.LineColorRange.GetSheet2Name,
|
||||||
|
series.LineColorRange.Row1, series.LineColorRange.Col1,
|
||||||
|
series.LineColorRange.Row2, series.LineColorRange.Col2,
|
||||||
|
rfAllRel, false
|
||||||
|
);
|
||||||
|
|
||||||
// And this is the title of the series for the legend
|
// And this is the title of the series for the legend
|
||||||
titleAddr := GetSheetCellRangeString_ODS(
|
titleAddr := GetSheetCellRangeString_ODS(
|
||||||
series.TitleAddr.GetSheetName, series.TitleAddr.GetSheetName,
|
series.TitleAddr.GetSheetName, series.TitleAddr.GetSheetName,
|
||||||
@ -2675,7 +2833,6 @@ begin
|
|||||||
else
|
else
|
||||||
chartClass := CHART_TYPE_NAMES[series.ChartType];
|
chartClass := CHART_TYPE_NAMES[series.ChartType];
|
||||||
|
|
||||||
|
|
||||||
// Store the series properties
|
// Store the series properties
|
||||||
AppendToStream(AChartStream, Format(
|
AppendToStream(AChartStream, Format(
|
||||||
indent + '<chart:series chart:style-name="ch%d" ' +
|
indent + '<chart:series chart:style-name="ch%d" ' +
|
||||||
@ -2696,17 +2853,14 @@ begin
|
|||||||
));
|
));
|
||||||
if fillColorRange <> '' then
|
if fillColorRange <> '' then
|
||||||
AppendToStream(AChartStream, Format(
|
AppendToStream(AChartStream, Format(
|
||||||
indent + '<loext:propertry-mapping loext:property="FillColor" loext:cell-range-address="%s"/>' + LE,
|
indent + '<loext:property-mapping loext:property="FillColor" loext:cell-range-address="%s"/>' + LE,
|
||||||
[ fillColorRange ]
|
[ fillColorRange ]
|
||||||
));
|
));
|
||||||
|
if lineColorRange <> '' then
|
||||||
{ --- not working...
|
|
||||||
if borderColorRange <> '' then
|
|
||||||
AppendToStream(AChartStream, Format(
|
AppendToStream(AChartStream, Format(
|
||||||
indent + '<loext:property-mapping loext:property="BorderColor" loext:cell-range-address="%s"/>' + LE,
|
indent + '<loext:property-mapping loext:property="BorderColor" loext:cell-range-address="%s"/>' + LE,
|
||||||
[ borderColorRange ]
|
[ lineColorRange ]
|
||||||
));
|
));
|
||||||
}
|
|
||||||
|
|
||||||
// Regression
|
// Regression
|
||||||
if (series is TsScatterSeries) then
|
if (series is TsScatterSeries) then
|
||||||
|
@ -1300,6 +1300,14 @@ end;
|
|||||||
function GetCellRangeString(ASheet1, ASheet2: String; ARow1, ACol1, ARow2, ACol2: Cardinal;
|
function GetCellRangeString(ASheet1, ASheet2: String; ARow1, ACol1, ARow2, ACol2: Cardinal;
|
||||||
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String;
|
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String;
|
||||||
begin
|
begin
|
||||||
|
if (ASheet1 = '') and (ASheet2 = '') and
|
||||||
|
(ARow1 = UNASSIGNED_ROW_COL_INDEX) and (ACol1 = UNASSIGNED_ROW_COL_INDEX) and
|
||||||
|
(ARow2 = UNASSIGNED_ROW_COL_INDEX) and (ACol2 = UNASSIGNED_ROW_COL_INDEX) then
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
Result := GetCellRangeString(ARow1, ACol1, ARow2, ACol2, AFlags, Compact);
|
Result := GetCellRangeString(ARow1, ACol1, ARow2, ACol2, AFlags, Compact);
|
||||||
if (ASheet1 = '') and (ASheet2 = '') then
|
if (ASheet1 = '') and (ASheet2 = '') then
|
||||||
exit;
|
exit;
|
||||||
|
Reference in New Issue
Block a user