diff --git a/components/fpspreadsheet/examples/other/chart/piechart_write_demo.lpr b/components/fpspreadsheet/examples/other/chart/piechart_write_demo.lpr index 5021d81ab..e3c87ea92 100644 --- a/components/fpspreadsheet/examples/other/chart/piechart_write_demo.lpr +++ b/components/fpspreadsheet/examples/other/chart/piechart_write_demo.lpr @@ -57,11 +57,11 @@ begin // 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.DataPointStyles.AddSolidFill($C47244); + ser.DataPointStyles.AddSolidFill($317DED); + ser.DataPointStyles.AddSolidFill($A5A5A5); + ser.DataPointStyles.AddSolidFill($00C0FF); + ser.DataPointStyles.AddSolidFill($D69B5B); //ser.SetFillColorRange(4, 2, 8, 2); diff --git a/components/fpspreadsheet/source/common/fpschart.pas b/components/fpspreadsheet/source/common/fpschart.pas index ec8375382..98fbebd32 100644 --- a/components/fpspreadsheet/source/common/fpschart.pas +++ b/components/fpspreadsheet/source/common/fpschart.pas @@ -316,6 +316,18 @@ type TsChartDataPointStyle = class(TsChartFillElement); + TsChartDataPointStyleList = class(TFPObjectList) + private + FChart: TsChart; + function GetItem(AIndex: Integer): TsChartDataPointStyle; + procedure SetItem(AIndex: Integer; AValue: TsChartDataPointStyle); + public + constructor Create(AChart: TsChart); + function AddFillAndLine(AFill: TsChartFill; ALine: TsChartline; ACount: Integer = 1): Integer; + function AddSolidFill(AColor: TsColor; ACount: Integer = 1): Integer; + property Items[AIndex: Integer]: TsChartDataPointStyle read GetItem write SetItem; default; + end; + TsChartSeries = class(TsChartElement) private FChartType: TsChartType; @@ -335,14 +347,12 @@ type FLine: TsChartLine; FFill: TsChartFill; FDataLabels: TsChartDataLabels; - FDataPointStyles: TFPObjectList; + FDataPointStyles: TsChartDataPointStyleList; protected function GetChartType: TsChartType; virtual; public constructor Create(AChart: TsChart); virtual; destructor Destroy; override; - procedure AddDataPointStyle(AFill: TsChartFill; ALine: TsChartLine; ACount: Integer = 1); - procedure AddDataPointStyle(AColor: TsColor; ACount: Integer = 1); function GetCount: Integer; function GetXCount: Integer; function GetYCount: Integer; @@ -368,7 +378,7 @@ type property ChartType: TsChartType read GetChartType; property Count: Integer read GetCount; property DataLabels: TsChartDataLabels read FDataLabels write FDataLabels; - property DataPointStyles: TFPObjectList read FDataPointStyles; + property DataPointStyles: TsChartDatapointStyleList read FDataPointStyles; property FillColorRange: TsChartRange read FFillColorRange write FFillColorRange; property LabelBackground: TsChartFill read FLabelBackground write FLabelBackground; property LabelBorder: TsChartLine read FLabelBorder write FLabelBorder; @@ -1203,6 +1213,70 @@ begin inherited; end; +{ TsChartDataPointStyleList } + +constructor TsChartDataPointStyleList.Create(AChart: TsChart); +begin + inherited Create; + FChart := AChart; +end; + +function TsChartDataPointStyleList.AddFillAndLine(AFill: TsChartFill; ALine: TsChartLine; + ACount: Integer = 1): Integer; +var + dataPointStyle: TsChartDataPointStyle; + i: Integer; +begin + if (AFill = nil) and (ALine = nil) then + for i := 1 to ACount do + Result := inherited Add(nil) + else + for i := 1 to ACount do + begin + dataPointStyle := TsChartDataPointStyle.Create(FChart); + if AFill <> nil then + dataPointStyle.Background.CopyFrom(AFill) + else + begin + dataPointStyle.Background.Free; + dataPointStyle.Background := nil; + end; + if ALine <> nil then + dataPointStyle.Border.CopyFrom(ALine) + else + begin + dataPointStyle.Border.Free; + dataPointStyle.Border := nil; + end; + Result := inherited Add(dataPointStyle); + end; +end; + +function TsChartDataPointStyleList.AddSolidFill(AColor: TsColor; ACount: Integer = 1): Integer; +var + fill: TsChartFill; +begin + fill := TsChartFill.Create; + try + fill.Style := cfsSolid; + fill.Color := AColor; + Result := AddFillAndLine(fill, nil, ACount); + finally + fill.Free; + end; +end; + +function TsChartDataPointStyleList.GetItem(AIndex: Integer): TsChartDataPointStyle; +begin + Result := TsChartDataPointStyle(inherited Items[AIndex]); +end; + +procedure TsChartDataPointStyleList.SetItem(AIndex: Integer; + AValue: TsChartDataPointStyle); +begin + inherited Items[AIndex] := AValue; +end; + { TsChartSeries } @@ -1232,7 +1306,7 @@ begin FLine.Width := PtsToMM(DEFAULT_CHART_LINEWIDTH); FLine.Color := DEFAULT_SERIES_COLORS[idx mod Length(DEFAULT_SERIES_COLORS)]; - FDataPointStyles := TFPObjectList.Create; + FDataPointStyles := TsChartDataPointStyleList.Create(AChart); FLabelFont := TsFont.Create; FLabelFont.Size := 9; @@ -1265,39 +1339,6 @@ begin inherited; 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; begin Result := FChartType; diff --git a/components/fpspreadsheet/source/common/fpsopendocumentchart.pas b/components/fpspreadsheet/source/common/fpsopendocumentchart.pas index cabf369ae..955492b9f 100644 --- a/components/fpspreadsheet/source/common/fpsopendocumentchart.pas +++ b/components/fpspreadsheet/source/common/fpsopendocumentchart.pas @@ -1310,7 +1310,7 @@ begin s := GetAttrValue(subnode, 'chart:repeated'); if (s <> '') then n := StrToIntDef(s, 1); - series.AddDataPointStyle(fill, line, n); + series.DataPointStyles.AddFillAndLine(fill, line, n); fill.Free; // the styles have been copied to the series datapoint list and are not needed any more. line.Free; end; @@ -2309,6 +2309,10 @@ begin ); end; +{@@ ---------------------------------------------------------------------------- + Creates an xml string which contains the individual style of the + datapoint with index APointIndex of the series with index ASeriesIndex. +-------------------------------------------------------------------------------} function TsSpreadOpenDocChartWriter.GetChartSeriesDataPointStyleAsXML(AChart: TsChart; ASeriesIndex, APointIndex, AIndent, AStyleID: Integer): String; var @@ -2322,7 +2326,7 @@ begin indent := DupeString(' ', AIndent); series := AChart.Series[ASeriesIndex]; - dataPointStyle := TsChartDataPointStyle(series.DataPointStyles[APointIndex]); + dataPointStyle := series.DataPointStyles[APointIndex]; chartProps := 'chart:solid-type="cuboid" '; diff --git a/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas b/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas index c69b42fa0..3904e3588 100644 --- a/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas +++ b/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas @@ -896,10 +896,16 @@ begin SetRangeFromChart(rngY, YIndex, ARange); end; +{@@ ---------------------------------------------------------------------------- + Extracts the fill color from the DataPointStyle items of the series. All the + other elements are ignored because TAChart does not support them. +-------------------------------------------------------------------------------} procedure TsWorkbookChartSource.UseDataPointColors(ASeries: TsChartSeries); var datapointStyle: TsChartDataPointStyle; i: Integer; + c: TsColor; + g: TsChartGradient; begin if ASeries = nil then begin @@ -910,13 +916,27 @@ begin SetLength(FDataPointColors, ASeries.DataPointStyles.Count); for i := 0 to High(FDataPointColors) do begin - datapointStyle := TsChartDataPointStyle(ASeries.DatapointStyles[i]); + datapointStyle := ASeries.DatapointStyles[i]; FDataPointColors[i] := clTAColor; - if (dataPointStyle <> nil) and (datapointStyle.Background.Style = cfsSolid) then - FDataPointColors[i] := Convert_sColor_to_Color(dataPointStyle.Background.Color); + if (dataPointStyle <> nil) and (dataPointStyle.Background <> nil) then + begin + if (datapointStyle.Background.Style in [cfsSolid, cfsSolidHatched]) then + c := dataPointStyle.Background.Color + else + if (dataPointStyle.Background.Style = cfsGradient) then + begin + // TAChart does not support gradient fills. Let's use the start color + // of the gradient for a solid fill. + g := ASeries.Chart.Gradients[datapointStyle.Background.Gradient]; + c := g.StartColor; + end else + Continue; + FDataPointColors[i] := Convert_sColor_to_Color(c); + end; end; end; + {@@ ---------------------------------------------------------------------------- Setter method for the WorkbookSource -------------------------------------------------------------------------------} @@ -1866,6 +1886,7 @@ end; procedure TsWorkbookChartLink.UpdatePieSeries(AWorkbookSeries: TsPieSeries; AChartSeries: TPieSeries); begin + UpdateChartPen(AWorkbookSeries.Chart, AWorkbookSeries.Line, AChartSeries.EdgePen); AChartSeries.StartAngle := AWorkbookSeries.StartAngle; AChartSeries.Legend.Multiplicity := lmPoint; AChartSeries.Legend.Format := '%2:s';