You've already forked lazarus-ccr
fpspreadsheet: Chart link as well as ods reader/writer support individual data point colors
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9063 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -25,6 +25,7 @@ begin
|
|||||||
sheet.WriteText(1, 0, 'https://en.wikipedia.org/wiki/World_population');
|
sheet.WriteText(1, 0, 'https://en.wikipedia.org/wiki/World_population');
|
||||||
sheet.WriteHyperlink(1, 0, 'https://en.wikipedia.org/wiki/World_population');
|
sheet.WriteHyperlink(1, 0, 'https://en.wikipedia.org/wiki/World_population');
|
||||||
sheet.WriteText(3, 0, 'Continent'); sheet.WriteText (3, 1, 'Population (millions)');
|
sheet.WriteText(3, 0, 'Continent'); sheet.WriteText (3, 1, 'Population (millions)');
|
||||||
|
sheet.WriteFontStyle(3, 0, [fssBold]); sheet.WriteFontStyle(3, 1, [fssBold]);
|
||||||
sheet.WriteText(4, 0, 'Asia'); sheet.WriteNumber(4, 1, 4641); // sheet.WriteChartColor(4, 2, scYellow);
|
sheet.WriteText(4, 0, 'Asia'); sheet.WriteNumber(4, 1, 4641); // sheet.WriteChartColor(4, 2, scYellow);
|
||||||
sheet.WriteText(5, 0, 'Africa'); sheet.WriteNumber(5, 1, 1340); // sheet.WriteChartColor(5, 2, scBrown);
|
sheet.WriteText(5, 0, 'Africa'); sheet.WriteNumber(5, 1, 1340); // sheet.WriteChartColor(5, 2, scBrown);
|
||||||
sheet.WriteText(6, 0, 'America'); sheet.WriteNumber(6, 1, 653 + 368); // sheet.WriteChartColor(6, 2, scRed);
|
sheet.WriteText(6, 0, 'America'); sheet.WriteNumber(6, 1, 653 + 368); // sheet.WriteChartColor(6, 2, scRed);
|
||||||
@ -53,6 +54,15 @@ begin
|
|||||||
ser.LabelPosition := lpOutside;
|
ser.LabelPosition := lpOutside;
|
||||||
ser.Line.Color := scWhite;
|
ser.Line.Color := scWhite;
|
||||||
ser.LabelFormat := '#,##0';
|
ser.LabelFormat := '#,##0';
|
||||||
|
|
||||||
|
// Individual sector colors
|
||||||
|
// Must be complete, otherwise will be ignored by Calc and replaced by default colors
|
||||||
|
ser.AddDataPointStyle(scYellow);
|
||||||
|
ser.AddDataPointStyle(scMaroon);
|
||||||
|
ser.AddDataPointStyle(scRed);
|
||||||
|
ser.AddDataPointStyle(scWhite);
|
||||||
|
ser.AddDatapointStyle(scBlue);
|
||||||
|
|
||||||
//ser.SetFillColorRange(4, 2, 8, 2);
|
//ser.SetFillColorRange(4, 2, 8, 2);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -40,6 +40,7 @@ type
|
|||||||
Width: Double; // mm
|
Width: Double; // mm
|
||||||
Color: TsColor; // in hex: $00bbggrr, r=red, g=green, b=blue
|
Color: TsColor; // in hex: $00bbggrr, r=red, g=green, b=blue
|
||||||
Transparency: Double; // in percent
|
Transparency: Double; // in percent
|
||||||
|
procedure CopyFrom(ALine: TsChartLine);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TsChartGradientStyle = (cgsLinear, cgsAxial, cgsRadial, cgsElliptic, cgsSquare, cgsRectangular);
|
TsChartGradientStyle = (cgsLinear, cgsAxial, cgsRadial, cgsElliptic, cgsSquare, cgsRectangular);
|
||||||
@ -135,6 +136,7 @@ type
|
|||||||
Hatch: Integer;
|
Hatch: Integer;
|
||||||
Image: Integer;
|
Image: Integer;
|
||||||
Transparency: Double; // 0.0 ... 1.0
|
Transparency: Double; // 0.0 ... 1.0
|
||||||
|
procedure CopyFrom(AFill: TsChartFill);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TsChartLineSegment = record
|
TsChartLineSegment = record
|
||||||
@ -312,6 +314,8 @@ type
|
|||||||
TsChartDataLabels = set of TsChartDataLabel;
|
TsChartDataLabels = set of TsChartDataLabel;
|
||||||
TsChartLabelPosition = (lpDefault, lpOutside, lpInside, lpCenter);
|
TsChartLabelPosition = (lpDefault, lpOutside, lpInside, lpCenter);
|
||||||
|
|
||||||
|
TsChartDataPointStyle = class(TsChartFillElement);
|
||||||
|
|
||||||
TsChartSeries = class(TsChartElement)
|
TsChartSeries = class(TsChartElement)
|
||||||
private
|
private
|
||||||
FChartType: TsChartType;
|
FChartType: TsChartType;
|
||||||
@ -331,11 +335,14 @@ type
|
|||||||
FLine: TsChartLine;
|
FLine: TsChartLine;
|
||||||
FFill: TsChartFill;
|
FFill: TsChartFill;
|
||||||
FDataLabels: TsChartDataLabels;
|
FDataLabels: TsChartDataLabels;
|
||||||
|
FDataPointStyles: TFPObjectList;
|
||||||
protected
|
protected
|
||||||
function GetChartType: TsChartType; virtual;
|
function GetChartType: TsChartType; virtual;
|
||||||
public
|
public
|
||||||
constructor Create(AChart: TsChart); virtual;
|
constructor Create(AChart: TsChart); virtual;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
procedure AddDataPointStyle(AFill: TsChartFill; ALine: TsChartLine; ACount: Integer = 1);
|
||||||
|
procedure AddDataPointStyle(AColor: TsColor; ACount: Integer = 1);
|
||||||
function GetCount: Integer;
|
function GetCount: Integer;
|
||||||
function GetXCount: Integer;
|
function GetXCount: Integer;
|
||||||
function GetYCount: Integer;
|
function GetYCount: Integer;
|
||||||
@ -361,6 +368,7 @@ 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 DataPointStyles: TFPObjectList read FDataPointStyles;
|
||||||
property FillColorRange: TsChartRange read FFillColorRange write FFillColorRange;
|
property FillColorRange: TsChartRange read FFillColorRange write FFillColorRange;
|
||||||
property LabelBackground: TsChartFill read FLabelBackground write FLabelBackground;
|
property LabelBackground: TsChartFill read FLabelBackground write FLabelBackground;
|
||||||
property LabelBorder: TsChartLine read FLabelBorder write FLabelBorder;
|
property LabelBorder: TsChartLine read FLabelBorder write FLabelBorder;
|
||||||
@ -659,6 +667,20 @@ implementation
|
|||||||
uses
|
uses
|
||||||
fpSpreadsheet;
|
fpSpreadsheet;
|
||||||
|
|
||||||
|
{ TsChartLine }
|
||||||
|
|
||||||
|
procedure TsChartLine.CopyFrom(ALine: TsChartLine);
|
||||||
|
begin
|
||||||
|
if ALine <> nil then
|
||||||
|
begin
|
||||||
|
Style := ALine.Style;
|
||||||
|
Width := ALine.Width;
|
||||||
|
Color := ALine.Color;
|
||||||
|
Transparency := ALine.Transparency;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TsChartGradient }
|
{ TsChartGradient }
|
||||||
|
|
||||||
constructor TsChartGradient.Create;
|
constructor TsChartGradient.Create;
|
||||||
@ -900,6 +922,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TsChartFill }
|
||||||
|
|
||||||
|
procedure TsChartFill.CopyFrom(AFill: TsChartFill);
|
||||||
|
begin
|
||||||
|
if AFill <> nil then
|
||||||
|
begin
|
||||||
|
Style := AFill.Style;
|
||||||
|
Color := AFill.Color;
|
||||||
|
Gradient := AFill.Gradient;
|
||||||
|
Hatch := AFill.Hatch;
|
||||||
|
Image := AFill.Image;
|
||||||
|
Transparency := AFill.Transparency;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TsChartLineStyle }
|
{ TsChartLineStyle }
|
||||||
|
|
||||||
function TsChartLineStyle.GetID: String;
|
function TsChartLineStyle.GetID: String;
|
||||||
@ -1194,6 +1232,8 @@ begin
|
|||||||
FLine.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
FLine.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH);
|
||||||
FLine.Color := DEFAULT_SERIES_COLORS[idx mod Length(DEFAULT_SERIES_COLORS)];
|
FLine.Color := DEFAULT_SERIES_COLORS[idx mod Length(DEFAULT_SERIES_COLORS)];
|
||||||
|
|
||||||
|
FDataPointStyles := TFPObjectList.Create;
|
||||||
|
|
||||||
FLabelFont := TsFont.Create;
|
FLabelFont := TsFont.Create;
|
||||||
FLabelFont.Size := 9;
|
FLabelFont.Size := 9;
|
||||||
|
|
||||||
@ -1213,6 +1253,7 @@ begin
|
|||||||
FLabelBackground.Free;
|
FLabelBackground.Free;
|
||||||
FLabelBorder.Free;
|
FLabelBorder.Free;
|
||||||
FLabelFont.Free;
|
FLabelFont.Free;
|
||||||
|
FDataPointStyles.Free;
|
||||||
FLine.Free;
|
FLine.Free;
|
||||||
FFill.Free;
|
FFill.Free;
|
||||||
FTitleAddr.Free;
|
FTitleAddr.Free;
|
||||||
@ -1224,6 +1265,39 @@ begin
|
|||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsChartSeries.AddDataPointStyle(AFill: TsChartFill; ALine: TsChartLine;
|
||||||
|
ACount: Integer = 1);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
dataPointStyle: TsChartDataPointStyle;
|
||||||
|
begin
|
||||||
|
if (AFill = nil) and (ALine = nil) then
|
||||||
|
for i := 1 to ACount do
|
||||||
|
FDataPointStyles.Add(nil)
|
||||||
|
else
|
||||||
|
for i := 1 to ACount do
|
||||||
|
begin
|
||||||
|
dataPointStyle := TsChartDataPointStyle.Create(FChart);
|
||||||
|
dataPointStyle.Background.CopyFrom(AFill);
|
||||||
|
dataPointStyle.Border.CopyFrom(ALine);
|
||||||
|
FDataPointStyles.Add(dataPointStyle);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsChartSeries.AddDataPointStyle(AColor: TsColor; ACount: Integer = 1);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
datapointStyle: TsChartDataPointStyle;
|
||||||
|
begin
|
||||||
|
for i := 1 to ACount do
|
||||||
|
begin
|
||||||
|
datapointStyle := TsChartDatapointStyle.Create(FChart);
|
||||||
|
dataPointStyle.Background.Style:= cfsSolid;
|
||||||
|
dataPointStyle.Background.Color := AColor;
|
||||||
|
FDataPointStyles.Add(datapointStyle);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TsChartSeries.GetChartType: TsChartType;
|
function TsChartSeries.GetChartType: TsChartType;
|
||||||
begin
|
begin
|
||||||
Result := FChartType;
|
Result := FChartType;
|
||||||
|
@ -26,8 +26,8 @@ type
|
|||||||
FPieSeriesStartAngle: Integer;
|
FPieSeriesStartAngle: Integer;
|
||||||
FStreamList: TFPObjectList;
|
FStreamList: TFPObjectList;
|
||||||
function FindStyleNode(AStyleNodes: TDOMNode; AStyleName: String): TDOMNode;
|
function FindStyleNode(AStyleNodes: TDOMNode; AStyleName: String): TDOMNode;
|
||||||
procedure GetChartFillProps(ANode: TDOMNode; AChart: TsChart; AFill: TsChartFill);
|
function GetChartFillProps(ANode: TDOMNode; AChart: TsChart; AFill: TsChartFill): Boolean;
|
||||||
procedure GetChartLineProps(ANode: TDOMNode; AChart: TsChart; ALine: TsChartLine);
|
function GetChartLineProps(ANode: TDOMNode; AChart: TsChart; ALine: TsChartLine): Boolean;
|
||||||
procedure GetChartTextProps(ANode: TDOMNode; AFont: TsFont);
|
procedure GetChartTextProps(ANode: TDOMNode; AFont: TsFont);
|
||||||
|
|
||||||
procedure ReadChartAxisGrid(ANode, AStyleNode: TDOMNode; AChart: TsChart; Axis: TsChartAxis);
|
procedure ReadChartAxisGrid(ANode, AStyleNode: TDOMNode; AChart: TsChart; Axis: TsChartAxis);
|
||||||
@ -45,6 +45,8 @@ type
|
|||||||
procedure ReadChartRegressionEquationStyle(AStyleNode: TDOMNode; AChart: TsChart; ASeries: TsChartSeries);
|
procedure ReadChartRegressionEquationStyle(AStyleNode: TDOMNode; AChart: TsChart; ASeries: TsChartSeries);
|
||||||
procedure ReadChartRegressionProps(ANode, AStyleNode: TDOMNode; AChart: TsChart; ASeries: TsChartSeries);
|
procedure ReadChartRegressionProps(ANode, AStyleNode: TDOMNode; AChart: TsChart; ASeries: TsChartSeries);
|
||||||
procedure ReadChartRegressionStyle(AStyleNode: TDOMNode; AChart: TsChart; ASeries: TsChartSeries);
|
procedure ReadChartRegressionStyle(AStyleNode: TDOMNode; AChart: TsChart; ASeries: TsChartSeries);
|
||||||
|
procedure ReadChartSeriesDataPointStyle(AStyleNode: TDOMNode; AChart: TsChart;
|
||||||
|
ASeries: TsChartSeries; var AFill: TsChartFill; var ALine: TsChartLine);
|
||||||
procedure ReadChartSeriesProps(ANode, AStyleNode: TDOMNode; AChart: TsChart);
|
procedure ReadChartSeriesProps(ANode, AStyleNode: TDOMNode; AChart: TsChart);
|
||||||
procedure ReadChartSeriesStyle(AStyleNode: TDOMNode; AChart: TsChart; ASeries: TsChartSeries);
|
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);
|
||||||
@ -89,6 +91,7 @@ type
|
|||||||
function GetChartRegressionEquationStyleAsXML(AChart: TsChart;
|
function GetChartRegressionEquationStyleAsXML(AChart: TsChart;
|
||||||
AEquation: TsRegressionEquation; AIndent, AStyleID: Integer): String;
|
AEquation: TsRegressionEquation; AIndent, AStyleID: Integer): String;
|
||||||
function GetChartRegressionStyleAsXML(AChart: TsChart; ASeriesIndex, AIndent, AStyleID: Integer): String;
|
function GetChartRegressionStyleAsXML(AChart: TsChart; ASeriesIndex, AIndent, AStyleID: Integer): String;
|
||||||
|
function GetChartSeriesDataPointStyleAsXML(AChart: TsChart; ASeriesIndex, APointIndex, AIndent, AStyleID: Integer): String;
|
||||||
function GetChartSeriesStyleAsXML(AChart: TsChart; ASeriesIndex, AIndent, AStyleID: integer): String;
|
function GetChartSeriesStyleAsXML(AChart: TsChart; ASeriesIndex, AIndent, AStyleID: integer): String;
|
||||||
|
|
||||||
function GetNumberFormatID(ANumFormat: String): String;
|
function GetNumberFormatID(ANumFormat: String): String;
|
||||||
@ -403,11 +406,16 @@ begin
|
|||||||
FChartFiles.Add(AFileList);
|
FChartFiles.Add(AFileList);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocChartReader.GetChartFillProps(ANode: TDOMNode;
|
{@@ ----------------------------------------------------------------------------
|
||||||
AChart: TsChart; AFill: TsChartFill);
|
Reads the fill style properties from the specified node. Returns FALSE, if
|
||||||
|
the node contains no fill-specific attributes.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function TsSpreadOpenDocChartReader.GetChartFillProps(ANode: TDOMNode;
|
||||||
|
AChart: TsChart; AFill: TsChartFill): Boolean;
|
||||||
var
|
var
|
||||||
{%H-}nodeName: String;
|
{%H-}nodeName: String;
|
||||||
s: String;
|
sFill: String;
|
||||||
|
sOpac: String;
|
||||||
sc: String;
|
sc: String;
|
||||||
sn: String;
|
sn: String;
|
||||||
opacity: Double;
|
opacity: Double;
|
||||||
@ -417,8 +425,8 @@ var
|
|||||||
begin
|
begin
|
||||||
nodeName := ANode.NodeName;
|
nodeName := ANode.NodeName;
|
||||||
|
|
||||||
s := GetAttrValue(ANode, 'draw:fill');
|
sFill := GetAttrValue(ANode, 'draw:fill');
|
||||||
case s of
|
case sFill of
|
||||||
'none':
|
'none':
|
||||||
AFill.Style := cfsNoFill;
|
AFill.Style := cfsNoFill;
|
||||||
'', 'solid':
|
'', 'solid':
|
||||||
@ -472,13 +480,19 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
s := GetAttrValue(ANode, 'draw:opacity');
|
sOpac := GetAttrValue(ANode, 'draw:opacity');
|
||||||
if (s <> '') and TryPercentStrToFloat(s, opacity) then
|
if (sOpac <> '') and TryPercentStrToFloat(sOpac, opacity) then
|
||||||
AFill.Transparency := 1.0 - opacity;
|
AFill.Transparency := 1.0 - opacity;
|
||||||
|
|
||||||
|
Result := (sFill <> '') or (sc <> '') or (sn <> '') or (sOpac <> '');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocChartReader.GetChartLineProps(ANode: TDOMNode;
|
{ ------------------------------------------------------------------------------
|
||||||
AChart: TsChart; ALine: TsChartLine);
|
Reads the line formatting properties from the specified node.
|
||||||
|
Returns FALSE, if there are no line-related attributes.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function TsSpreadOpenDocChartReader.GetChartLineProps(ANode: TDOMNode;
|
||||||
|
AChart: TsChart; ALine: TsChartLine): Boolean;
|
||||||
var
|
var
|
||||||
{%H-}nodeName: String;
|
{%H-}nodeName: String;
|
||||||
s: String;
|
s: String;
|
||||||
@ -517,9 +531,11 @@ begin
|
|||||||
if (sw <> '') and EvalLengthStr(sw, value, rel) then
|
if (sw <> '') and EvalLengthStr(sw, value, rel) then
|
||||||
ALine.Width := value;
|
ALine.Width := value;
|
||||||
|
|
||||||
so := 'draw:stroke-opacity';
|
so := GetAttrValue(ANode, 'draw:stroke-opacity');
|
||||||
if (so <> '') and TryPercentStrToFloat(so, value) then
|
if (so <> '') and TryPercentStrToFloat(so, value) then
|
||||||
ALine.Transparency := 1.0 - value*0.01;
|
ALine.Transparency := 1.0 - value*0.01;
|
||||||
|
|
||||||
|
Result := (s <> '') or (sc <> '') or (sw <> '') or (so <> '');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocChartReader.GetChartTextProps(ANode: TDOMNode;
|
procedure TsSpreadOpenDocChartReader.GetChartTextProps(ANode: TDOMNode;
|
||||||
@ -1192,14 +1208,42 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadOpenDocChartReader.ReadChartSeriesDataPointStyle(AStyleNode: TDOMNode;
|
||||||
|
AChart: TsChart; ASeries: TsChartSeries; var AFill: TsChartFill; var ALine: TsChartLine);
|
||||||
|
var
|
||||||
|
nodeName: string;
|
||||||
|
grNode: TDOMNode;
|
||||||
|
begin
|
||||||
|
AFill := nil;
|
||||||
|
ALine := nil;
|
||||||
|
|
||||||
|
nodeName := AStyleNode.NodeName;
|
||||||
|
AStyleNode := AStyleNode.FirstChild;
|
||||||
|
while AStyleNode <> nil do
|
||||||
|
begin
|
||||||
|
nodeName := AStyleNode.NodeName;
|
||||||
|
if nodeName = 'style:graphic-properties' then
|
||||||
|
begin
|
||||||
|
AFill := TsChartFill.Create;
|
||||||
|
if not GetChartFillProps(AStyleNode, AChart, AFill) then FreeAndNil(AFill);
|
||||||
|
ALine := TsChartLine.Create;
|
||||||
|
if not GetChartLineProps(AStyleNode, AChart, ALine) then FreeAndNil(ALine);
|
||||||
|
end;
|
||||||
|
AStyleNode := AStyleNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocChartReader.ReadChartSeriesProps(ANode, AStyleNode: TDOMNode;
|
procedure TsSpreadOpenDocChartReader.ReadChartSeriesProps(ANode, AStyleNode: TDOMNode;
|
||||||
AChart: TsChart);
|
AChart: TsChart);
|
||||||
var
|
var
|
||||||
s, nodeName: String;
|
s, nodeName: String;
|
||||||
series: TsChartSeries;
|
series: TsChartSeries;
|
||||||
|
fill: TsChartFill;
|
||||||
|
line: TsChartLine;
|
||||||
subNode: TDOMNode;
|
subNode: TDOMNode;
|
||||||
styleNode: TDOMNode;
|
styleNode: TDOMNode;
|
||||||
xyCounter: Integer;
|
xyCounter: Integer;
|
||||||
|
n: Integer;
|
||||||
begin
|
begin
|
||||||
s := GetAttrValue(ANode, 'chart:class');
|
s := GetAttrValue(ANode, 'chart:class');
|
||||||
case s of
|
case s of
|
||||||
@ -1252,6 +1296,24 @@ begin
|
|||||||
end;
|
end;
|
||||||
'chart:regression-curve':
|
'chart:regression-curve':
|
||||||
ReadChartRegressionProps(subNode, AStyleNode, AChart, series);
|
ReadChartRegressionProps(subNode, AStyleNode, AChart, series);
|
||||||
|
'chart:data-point':
|
||||||
|
begin
|
||||||
|
fill := nil;
|
||||||
|
line := nil;
|
||||||
|
n := 1;
|
||||||
|
s := GetAttrValue(subnode, 'chart:style-name');
|
||||||
|
if s <> '' then
|
||||||
|
begin
|
||||||
|
styleNode := FindStyleNode(AStyleNode, s);
|
||||||
|
ReadChartSeriesDataPointStyle(styleNode, AChart, series, fill, line); // creates fill and line!
|
||||||
|
end;
|
||||||
|
s := GetAttrValue(subnode, 'chart:repeated');
|
||||||
|
if (s <> '') then
|
||||||
|
n := StrToIntDef(s, 1);
|
||||||
|
series.AddDataPointStyle(fill, line, n);
|
||||||
|
fill.Free; // the styles have been copied to the series datapoint list and are not needed any more.
|
||||||
|
line.Free;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
subnode := subNode.NextSibling;
|
subnode := subNode.NextSibling;
|
||||||
end;
|
end;
|
||||||
@ -2247,6 +2309,37 @@ begin
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TsSpreadOpenDocChartWriter.GetChartSeriesDataPointStyleAsXML(AChart: TsChart;
|
||||||
|
ASeriesIndex, APointIndex, AIndent, AStyleID: Integer): String;
|
||||||
|
var
|
||||||
|
series: TsChartSeries;
|
||||||
|
indent: String;
|
||||||
|
chartProps: String;
|
||||||
|
graphProps: String = '';
|
||||||
|
dataPointStyle: TsChartDataPointStyle;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
indent := DupeString(' ', AIndent);
|
||||||
|
|
||||||
|
series := AChart.Series[ASeriesIndex];
|
||||||
|
dataPointStyle := TsChartDataPointStyle(series.DataPointStyles[APointIndex]);
|
||||||
|
|
||||||
|
chartProps := 'chart:solid-type="cuboid" ';
|
||||||
|
|
||||||
|
if dataPointStyle.Background <> nil then
|
||||||
|
graphProps := graphProps + GetChartFillStyleGraphicPropsAsXML(AChart, dataPointStyle.Background);
|
||||||
|
if dataPointStyle.Border <> nil then
|
||||||
|
graphProps := graphProps + GetChartLineStyleGraphicPropsAsXML(AChart, dataPointStyle.Border);
|
||||||
|
|
||||||
|
Result := Format(
|
||||||
|
indent + '<style:style style:name="ch%d" style:family="chart">' + LE +
|
||||||
|
indent + ' <style:chart-properties %s/>' + LE +
|
||||||
|
indent + ' <style:graphic-properties %s/>' + LE +
|
||||||
|
indent + '</style:style>' + LE,
|
||||||
|
[ AStyleID, chartProps, graphProps ]
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ <style:style style:name="ch1400" style:family="chart" style:data-style-name="N0">
|
{ <style:style style:name="ch1400" style:family="chart" style:data-style-name="N0">
|
||||||
<style:chart-properties
|
<style:chart-properties
|
||||||
@ -2326,9 +2419,9 @@ begin
|
|||||||
if pos('\n', labelSeparator) > 0 then
|
if pos('\n', labelSeparator) > 0 then
|
||||||
labelSeparator := StringReplace(labelSeparator, '\n', '<text:line-break/>', [rfReplaceAll, rfIgnoreCase]);
|
labelSeparator := StringReplace(labelSeparator, '\n', '<text:line-break/>', [rfReplaceAll, rfIgnoreCase]);
|
||||||
labelSeparator :=
|
labelSeparator :=
|
||||||
' <chart:label-separator>' + LE +
|
indent + ' <chart:label-separator>' + LE +
|
||||||
' <text:p>' + labelSeparator + '</text:p>' + LE +
|
indent + ' <text:p>' + labelSeparator + '</text:p>' + LE +
|
||||||
' </chart:label-separator>' + LE;
|
indent + ' </chart:label-separator>' + LE;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if series.LabelBorder.Style <> clsNoLine then
|
if series.LabelBorder.Style <> clsNoLine then
|
||||||
@ -2338,9 +2431,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if labelSeparator <> '' then
|
if labelSeparator <> '' then
|
||||||
chartProps := ' <style:chart-properties ' + chartProps + '>' + LE + labelSeparator + ' </style:chart-properties>'
|
chartProps := indent + ' <style:chart-properties ' + chartProps + '>' + LE + labelSeparator + indent + ' </style:chart-properties>'
|
||||||
else
|
else
|
||||||
chartProps := ' <style:chart-properties ' + chartProps + '/>';
|
chartProps := indent + ' <style:chart-properties ' + chartProps + '/>';
|
||||||
|
|
||||||
// Graphic properties
|
// Graphic properties
|
||||||
lineProps := GetChartLineStyleGraphicPropsAsXML(AChart, series.Line);
|
lineProps := GetChartLineStyleGraphicPropsAsXML(AChart, series.Line);
|
||||||
@ -2361,7 +2454,7 @@ begin
|
|||||||
|
|
||||||
Result := Format(
|
Result := Format(
|
||||||
indent + '<style:style style:name="ch%d" style:family="chart" style:data-style-name="%s">' + LE +
|
indent + '<style:style style:name="ch%d" style:family="chart" style:data-style-name="%s">' + LE +
|
||||||
indent + chartProps + LE +
|
chartProps + LE +
|
||||||
indent + ' <style:graphic-properties %s/>' + LE +
|
indent + ' <style:graphic-properties %s/>' + LE +
|
||||||
indent + ' <style:text-properties %s/>' + LE +
|
indent + ' <style:text-properties %s/>' + LE +
|
||||||
indent + '</style:style>' + LE,
|
indent + '</style:style>' + LE,
|
||||||
@ -3196,9 +3289,11 @@ var
|
|||||||
needRegressionEquationStyle: Boolean = false;
|
needRegressionEquationStyle: Boolean = false;
|
||||||
regression: TsChartRegression = nil;
|
regression: TsChartRegression = nil;
|
||||||
titleAddr: String;
|
titleAddr: String;
|
||||||
count: Integer;
|
i, count: Integer;
|
||||||
|
styleID, dpStyleID: Integer;
|
||||||
begin
|
begin
|
||||||
indent := DupeString(' ', AChartIndent);
|
indent := DupeString(' ', AChartIndent);
|
||||||
|
styleID := AStyleID;
|
||||||
|
|
||||||
series := AChart.Series[ASeriesIndex];
|
series := AChart.Series[ASeriesIndex];
|
||||||
|
|
||||||
@ -3324,6 +3419,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
regressionEquation := regressionEquation + Format('chart:style-name="ch%d" ', [AStyleID + 2]);
|
regressionEquation := regressionEquation + Format('chart:style-name="ch%d" ', [AStyleID + 2]);
|
||||||
needRegressionEquationStyle := true;
|
needRegressionEquationStyle := true;
|
||||||
|
styleID := AStyleID + 2;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if regression.DisplayEquation then
|
if regression.DisplayEquation then
|
||||||
@ -3345,20 +3441,43 @@ begin
|
|||||||
indent + ' <chart:equation %s />' + LE +
|
indent + ' <chart:equation %s />' + LE +
|
||||||
indent + ' </chart:regression-curve>' + LE,
|
indent + ' </chart:regression-curve>' + LE,
|
||||||
[ AStyleID + 1, regressionEquation ]
|
[ AStyleID + 1, regressionEquation ]
|
||||||
))
|
));
|
||||||
end else
|
end else
|
||||||
AppendToStream(AChartStream, Format(
|
AppendToStream(AChartStream, Format(
|
||||||
indent + ' <chart:regression-curve chart:style-name="ch%d"/>',
|
indent + ' <chart:regression-curve chart:style-name="ch%d"/>',
|
||||||
[ AStyleID + 1 ]
|
[ AStyleID + 1 ]
|
||||||
));
|
));
|
||||||
needRegressionStyle := true;
|
needRegressionStyle := true;
|
||||||
|
if styleID = AStyleID then
|
||||||
|
styleID := AStyleID + 1;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
AppendToStream(AChartStream, Format(
|
// Individual data point styles
|
||||||
indent + ' <chart:data-point chart:repeated="%d"/>' + LE,
|
if series.DataPointStyles.Count = 0 then
|
||||||
[ count ]
|
AppendToStream(AChartStream, Format(
|
||||||
));
|
indent + ' <chart:data-point chart:repeated="%d"/>' + LE,
|
||||||
|
[ count ]
|
||||||
|
))
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
dpStyleID := styleID + 1;
|
||||||
|
for i := 0 to count - 1 do
|
||||||
|
begin
|
||||||
|
if (i >= series.DataPointStyles.Count) or (series.DataPointStyles[i] = nil) then
|
||||||
|
AppendToStream(AChartStream,
|
||||||
|
indent + ' <chart:data-point chart:repeated="1">' + LE
|
||||||
|
)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
AppendToStream(AChartStream, Format(
|
||||||
|
indent + ' <chart:data-point chart:style-name="ch%d" />' + LE, // ToDo: could contain "chart:repeated"
|
||||||
|
[ dpStyleID ]
|
||||||
|
));
|
||||||
|
inc(dpStyleID);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
AppendToStream(AChartStream,
|
AppendToStream(AChartStream,
|
||||||
indent + '</chart:series>' + LE
|
indent + '</chart:series>' + LE
|
||||||
);
|
);
|
||||||
@ -3386,6 +3505,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Data point styles
|
||||||
|
for i := 0 to series.DataPointStyles.Count - 1 do
|
||||||
|
begin
|
||||||
|
inc(AStyleID);
|
||||||
|
AppendToStream(AStyleStream,
|
||||||
|
GetChartSeriesDataPointStyleAsXML(AChart, ASeriesIndex, i, AStyleIndent, AStyleID)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
|
||||||
// Next style
|
// Next style
|
||||||
inc(AStyleID);
|
inc(AStyleID);
|
||||||
end;
|
end;
|
||||||
|
@ -53,6 +53,7 @@ type
|
|||||||
FTitleCol, FTitleRow: Cardinal;
|
FTitleCol, FTitleRow: Cardinal;
|
||||||
FTitleSheetName: String;
|
FTitleSheetName: String;
|
||||||
FCyclicX: Boolean;
|
FCyclicX: Boolean;
|
||||||
|
FDataPointColors: array of TsColor;
|
||||||
function GetRange(AIndex: TsXYLRange): String;
|
function GetRange(AIndex: TsXYLRange): String;
|
||||||
function GetTitle: String;
|
function GetTitle: String;
|
||||||
function GetWorkbook: TsWorkbook;
|
function GetWorkbook: TsWorkbook;
|
||||||
@ -82,6 +83,7 @@ type
|
|||||||
procedure SetXRange(XIndex: Integer;ARange: TsChartRange);
|
procedure SetXRange(XIndex: Integer;ARange: TsChartRange);
|
||||||
procedure SetYRange(YIndex: Integer; ARange: TsChartRange);
|
procedure SetYRange(YIndex: Integer; ARange: TsChartRange);
|
||||||
procedure SetTitleAddr(Addr: TsChartCellAddr);
|
procedure SetTitleAddr(Addr: TsChartCellAddr);
|
||||||
|
procedure UseDataPointColors(ASeries: TsChartSeries);
|
||||||
property PointsNumber: Cardinal read FPointsNumber;
|
property PointsNumber: Cardinal read FPointsNumber;
|
||||||
property Workbook: TsWorkbook read GetWorkbook;
|
property Workbook: TsWorkbook read GetWorkbook;
|
||||||
public
|
public
|
||||||
@ -481,6 +483,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
FCurItem.Color := clTAColor; // = clDefault
|
FCurItem.Color := clTAColor; // = clDefault
|
||||||
|
if AIndex <= High(FDataPointColors) then
|
||||||
|
FCurItem.Color := FDataPointColors[AIndex];
|
||||||
if FRanges[rngColor] <> nil then
|
if FRanges[rngColor] <> nil then
|
||||||
begin
|
begin
|
||||||
GetXYItem(rngColor, 0, AIndex, dummyNumber, dummyString);
|
GetXYItem(rngColor, 0, AIndex, dummyNumber, dummyString);
|
||||||
@ -537,6 +541,7 @@ end;
|
|||||||
@param APointIndex Index of the data point for which the data are required
|
@param APointIndex Index of the data point for which the data are required
|
||||||
@param ANumber (output) x or y coordinate of the data point
|
@param ANumber (output) x or y coordinate of the data point
|
||||||
@param AText Data point marks label text
|
@param AText Data point marks label text
|
||||||
|
@param AColor Individual data point color
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsWorkbookChartSource.GetXYItem(ARangeIndex:TsXYLRange;
|
procedure TsWorkbookChartSource.GetXYItem(ARangeIndex:TsXYLRange;
|
||||||
AListIndex, APointIndex: Integer; out ANumber: Double; out AText: String);
|
AListIndex, APointIndex: Integer; out ANumber: Double; out AText: String);
|
||||||
@ -891,6 +896,27 @@ begin
|
|||||||
SetRangeFromChart(rngY, YIndex, ARange);
|
SetRangeFromChart(rngY, YIndex, ARange);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsWorkbookChartSource.UseDataPointColors(ASeries: TsChartSeries);
|
||||||
|
var
|
||||||
|
datapointStyle: TsChartDataPointStyle;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
if ASeries = nil then
|
||||||
|
begin
|
||||||
|
SetLength(FDataPointColors, 0);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
SetLength(FDataPointColors, ASeries.DataPointStyles.Count);
|
||||||
|
for i := 0 to High(FDataPointColors) do
|
||||||
|
begin
|
||||||
|
datapointStyle := TsChartDataPointStyle(ASeries.DatapointStyles[i]);
|
||||||
|
FDataPointColors[i] := clTAColor;
|
||||||
|
if (dataPointStyle <> nil) and (datapointStyle.Background.Style = cfsSolid) then
|
||||||
|
FDataPointColors[i] := Convert_sColor_to_Color(dataPointStyle.Background.Color);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Setter method for the WorkbookSource
|
Setter method for the WorkbookSource
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
@ -1038,6 +1064,9 @@ begin
|
|||||||
if not ASeries.FillColorRange.IsEmpty then src.SetColorRange(ASeries.FillColorRange);
|
if not ASeries.FillColorRange.IsEmpty then src.SetColorRange(ASeries.FillColorRange);
|
||||||
src.SetTitleAddr(ASeries.TitleAddr);
|
src.SetTitleAddr(ASeries.TitleAddr);
|
||||||
|
|
||||||
|
// Copy individual data point colors to the chart series.
|
||||||
|
src.UseDataPointColors(ASeries);
|
||||||
|
|
||||||
if stackable then begin
|
if stackable then begin
|
||||||
calcSrc := TCalculatedChartSource.Create(self);
|
calcSrc := TCalculatedChartSource.Create(self);
|
||||||
calcSrc.Origin := src;
|
calcSrc.Origin := src;
|
||||||
|
Reference in New Issue
Block a user