You've already forked lazarus-ccr
fpspreadsheet: Introducing ChartStyles for ods writer.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8971 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -8,6 +8,8 @@ var
|
|||||||
ch: TsChart;
|
ch: TsChart;
|
||||||
ser: TsChartSeries;
|
ser: TsChartSeries;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
bg: TsChartFill;
|
||||||
|
frm: TsChartLine;
|
||||||
begin
|
begin
|
||||||
b := TsWorkbook.Create;
|
b := TsWorkbook.Create;
|
||||||
try
|
try
|
||||||
@ -25,6 +27,15 @@ begin
|
|||||||
ser.SetTitleAddr(0, 1);
|
ser.SetTitleAddr(0, 1);
|
||||||
ser.SetLabelRange(1, 0, 7, 0);
|
ser.SetLabelRange(1, 0, 7, 0);
|
||||||
ser.SetYRange(1, 1, 7, 1);
|
ser.SetYRange(1, 1, 7, 1);
|
||||||
|
|
||||||
|
bg.FgColor := scYellow;
|
||||||
|
bg.Style := fsSolidFill;
|
||||||
|
ch.Background := bg;
|
||||||
|
|
||||||
|
frm.color := scRed;
|
||||||
|
frm.Style := clsSolid;
|
||||||
|
ch.Border := frm;
|
||||||
|
|
||||||
ch.Title.Caption := 'HALLO';
|
ch.Title.Caption := 'HALLO';
|
||||||
ch.Title.Visible := true;
|
ch.Title.Visible := true;
|
||||||
ch.SubTitle.Caption := 'hallo';
|
ch.SubTitle.Caption := 'hallo';
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
This package is all you need if you don't want graphical components (such as grids and charts)."/>
|
This package is all you need if you don't want graphical components (such as grids and charts)."/>
|
||||||
<License Value="LGPL with static linking exception. This is the same license as is used in the LCL (Lazarus Component Library)."/>
|
<License Value="LGPL with static linking exception. This is the same license as is used in the LCL (Lazarus Component Library)."/>
|
||||||
<Version Major="1" Minor="17"/>
|
<Version Major="1" Minor="17"/>
|
||||||
<Files Count="58">
|
<Files Count="59">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="source\fps.inc"/>
|
<Filename Value="source\fps.inc"/>
|
||||||
<Type Value="Include"/>
|
<Type Value="Include"/>
|
||||||
@ -305,6 +305,10 @@ This package is all you need if you don't want graphical components (such a
|
|||||||
<Filename Value="source\common\fpspreadsheet_chart.inc"/>
|
<Filename Value="source\common\fpspreadsheet_chart.inc"/>
|
||||||
<Type Value="Binary"/>
|
<Type Value="Binary"/>
|
||||||
</Item58>
|
</Item58>
|
||||||
|
<Item59>
|
||||||
|
<Filename Value="source\common\fpschartstyles.pas"/>
|
||||||
|
<UnitName Value="fpschartstyles"/>
|
||||||
|
</Item59>
|
||||||
</Files>
|
</Files>
|
||||||
<CompatibilityMode Value="True"/>
|
<CompatibilityMode Value="True"/>
|
||||||
<i18n>
|
<i18n>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
unit fpschart;
|
unit fpschart;
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
{$modeswitch advancedrecords}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ const
|
|||||||
|
|
||||||
{@@ Pre-defined chart line styles given as indexes into the chart's LineStyles
|
{@@ Pre-defined chart line styles given as indexes into the chart's LineStyles
|
||||||
list. Get their value in the constructor of TsChart. Default here to -1
|
list. Get their value in the constructor of TsChart. Default here to -1
|
||||||
while is the code for a solid line, just in case that something goes wrong }
|
which is the code for a solid line, just in case that something goes wrong }
|
||||||
var
|
var
|
||||||
clsFineDot: Integer = -1;
|
clsFineDot: Integer = -1;
|
||||||
clsDot: Integer = -1;
|
clsDot: Integer = -1;
|
||||||
@ -30,6 +31,7 @@ type
|
|||||||
Style: TsFillStyle;
|
Style: TsFillStyle;
|
||||||
FgColor: TsColor;
|
FgColor: TsColor;
|
||||||
BgColor: TsColor;
|
BgColor: TsColor;
|
||||||
|
class operator = (A, B: TsChartFill): Boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TsChartLineSegment = record
|
TsChartLineSegment = record
|
||||||
@ -193,7 +195,8 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
TsChartSeriesSymbol = (
|
TsChartSeriesSymbol = (
|
||||||
cssRect, cssDiamond, cssTriangle, cssTriangleDown, cssCircle, cssStar
|
cssRect, cssDiamond, cssTriangle, cssTriangleDown, cssTriangleLeft,
|
||||||
|
cssTriangleRight, cssCircle, cssStar, cssX, cssPlus, cssAsterisk
|
||||||
);
|
);
|
||||||
|
|
||||||
TsLineSeries = class(TsChartSeries)
|
TsLineSeries = class(TsChartSeries)
|
||||||
@ -282,6 +285,10 @@ type
|
|||||||
{ Height of the chart, in mm }
|
{ Height of the chart, in mm }
|
||||||
property Height: double read FHeight write FHeight;
|
property Height: double read FHeight write FHeight;
|
||||||
|
|
||||||
|
{ Attributes of the entire chart background }
|
||||||
|
property Background: TsChartFill read FBackground write FBackground;
|
||||||
|
property Border: TsChartLine read FBorder write FBorder;
|
||||||
|
|
||||||
{ Attributes of the plot area (rectangle enclosed by axes) }
|
{ Attributes of the plot area (rectangle enclosed by axes) }
|
||||||
property PlotArea: TsChartFillElement read FPlotArea write FPlotArea;
|
property PlotArea: TsChartFillElement read FPlotArea write FPlotArea;
|
||||||
{ Attributes of the floor of a 3D chart }
|
{ Attributes of the floor of a 3D chart }
|
||||||
@ -323,6 +330,14 @@ implementation
|
|||||||
const
|
const
|
||||||
DEFAULT_LINE_WIDTH = 0.75; // pts
|
DEFAULT_LINE_WIDTH = 0.75; // pts
|
||||||
|
|
||||||
|
{ TsChartFill }
|
||||||
|
|
||||||
|
class operator TsChartFill.= (A, B: TsChartFill): Boolean;
|
||||||
|
begin
|
||||||
|
Result := (A.Style = B.Style) and (A.FgColor = B.FgColor) and (A.BgColor = B.BgColor);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TsChartLineStyle }
|
{ TsChartLineStyle }
|
||||||
|
|
||||||
function TsChartLineStyle.GetID: String;
|
function TsChartLineStyle.GetID: String;
|
||||||
@ -648,6 +663,9 @@ begin
|
|||||||
FWidth := 12;
|
FWidth := 12;
|
||||||
FHeight := 9;
|
FHeight := 9;
|
||||||
|
|
||||||
|
FBackground.Style := fsNoFill;
|
||||||
|
FBorder.Style := clsNoLine;
|
||||||
|
|
||||||
FPlotArea := TsChartFillElement.Create(self);
|
FPlotArea := TsChartFillElement.Create(self);
|
||||||
FFloor := TsChartFillElement.Create(self);
|
FFloor := TsChartFillElement.Create(self);
|
||||||
|
|
||||||
|
98
components/fpspreadsheet/source/common/fpschartstyles.pas
Normal file
98
components/fpspreadsheet/source/common/fpschartstyles.pas
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
unit fpsChartStyles;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, fpsTypes, fpsChart;
|
||||||
|
|
||||||
|
type
|
||||||
|
TsChartStyle = class
|
||||||
|
public
|
||||||
|
procedure ApplyToChart(AChart: TsChart); virtual; abstract;
|
||||||
|
procedure ExtractFromChart(AChart: TsChart); virtual; abstract;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TsChartBackgroundStyle = class(TsChartStyle)
|
||||||
|
private
|
||||||
|
FBackground: TsChartFill;
|
||||||
|
FBorder: TsChartLine;
|
||||||
|
public
|
||||||
|
procedure ApplyToChart(AChart: TsChart); override;
|
||||||
|
procedure ExtractFromChart(AChart: TsChart); override;
|
||||||
|
property Background: TsChartFill read FBackground;
|
||||||
|
property Border: TsChartLine read FBorder;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TsChartStyleList = class(TFPList)
|
||||||
|
public
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure Clear;
|
||||||
|
function FindChartBackgroundStyle(AChart: TsChart): Integer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{ TsChartBackgroundstyle }
|
||||||
|
|
||||||
|
procedure TsChartBackgroundStyle.ApplyToChart(AChart: TsChart);
|
||||||
|
begin
|
||||||
|
AChart.Background := FBackground;
|
||||||
|
AChart.Border := FBorder;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsChartBackgroundStyle.ExtractFromChart(AChart: TsChart);
|
||||||
|
begin
|
||||||
|
FBackground := AChart.Background;
|
||||||
|
FBorder := AChart.Border;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TsChartStyleList }
|
||||||
|
|
||||||
|
destructor TsChartStyleList.Destroy;
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsChartStyleList.Clear;
|
||||||
|
var
|
||||||
|
j: Integer;
|
||||||
|
begin
|
||||||
|
for j := 0 to Count-1 do
|
||||||
|
TsChartStyle(Items[j]).Free;
|
||||||
|
inherited Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Searches whether the background style of the specified chart is already in the
|
||||||
|
list. If not, a new style is created and added.
|
||||||
|
Returns the index of the style. }
|
||||||
|
function TsChartStyleList.FindChartBackgroundStyle(AChart: TsChart): Integer;
|
||||||
|
var
|
||||||
|
newStyle, style: TsChartBackgroundStyle;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
Result := -1;
|
||||||
|
newStyle := TsChartBackgroundStyle.Create;
|
||||||
|
newStyle.ExtractFromChart(AChart);
|
||||||
|
for i := 0 to Count-1 do
|
||||||
|
begin
|
||||||
|
if (TsChartStyle(Items[i]) is TsChartBackgroundStyle) then
|
||||||
|
begin
|
||||||
|
style := TsChartBackgroundStyle(Items[i]);
|
||||||
|
if style.FBackground = newStyle.FBackground then
|
||||||
|
begin
|
||||||
|
Result := i;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Result = -1 then
|
||||||
|
Result := Add(newStyle)
|
||||||
|
else
|
||||||
|
newStyle.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -224,6 +224,7 @@ type
|
|||||||
|
|
||||||
TsSpreadOpenDocWriter = class(TsCustomSpreadWriter)
|
TsSpreadOpenDocWriter = class(TsCustomSpreadWriter)
|
||||||
private
|
private
|
||||||
|
FChartStyleList: TFPList;
|
||||||
FColumnStyleList: TFPList;
|
FColumnStyleList: TFPList;
|
||||||
FRowStyleList: TFPList;
|
FRowStyleList: TFPList;
|
||||||
FRichTextFontList: TStringList;
|
FRichTextFontList: TStringList;
|
||||||
@ -318,6 +319,7 @@ type
|
|||||||
out AStyleName: String; out AHeight: Single);
|
out AStyleName: String; out AHeight: Single);
|
||||||
}
|
}
|
||||||
procedure InternalWriteToStream(AStream: TStream);
|
procedure InternalWriteToStream(AStream: TStream);
|
||||||
|
procedure ListAllChartStyles;
|
||||||
procedure ListAllColumnStyles;
|
procedure ListAllColumnStyles;
|
||||||
procedure ListAllHeaderFooterFonts;
|
procedure ListAllHeaderFooterFonts;
|
||||||
procedure ListAllNumFormats; override;
|
procedure ListAllNumFormats; override;
|
||||||
@ -374,7 +376,7 @@ uses
|
|||||||
StrUtils, Variants, LazFileUtils, URIParser, LazUTF8,
|
StrUtils, Variants, LazFileUtils, URIParser, LazUTF8,
|
||||||
{%H-}fpsPatches,
|
{%H-}fpsPatches,
|
||||||
fpsStrings, fpsStreams, fpsCrypto, fpsClasses, fpspreadsheet,
|
fpsStrings, fpsStreams, fpsCrypto, fpsClasses, fpspreadsheet,
|
||||||
fpsExprParser, fpsImages, fpsConditionalFormat;
|
fpsExprParser, fpsImages, fpsConditionalFormat, fpsChartStyles;
|
||||||
|
|
||||||
const
|
const
|
||||||
LE = LineEnding;
|
LE = LineEnding;
|
||||||
@ -509,6 +511,11 @@ const
|
|||||||
'', 'bar', 'line', 'area', 'barLine', 'scatter'
|
'', 'bar', 'line', 'area', 'barLine', 'scatter'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CHART_SYMBOL_NAMES: array[TsChartSeriesSymbol] of String = (
|
||||||
|
'square', 'diamond', 'arrow-up', 'arrow-down', 'arrow-left',
|
||||||
|
'arrow-right', 'circle', 'star', 'x', 'plus', 'asterisk'
|
||||||
|
); // unsupported: bow-tie, hourglass, horizontal-bar, vertical-bar
|
||||||
|
|
||||||
|
|
||||||
function CFOperandToStr(v: variant; AWorksheet: TsWorksheet;
|
function CFOperandToStr(v: variant; AWorksheet: TsWorksheet;
|
||||||
const AFormatSettings: TFormatSettings): String;
|
const AFormatSettings: TFormatSettings): String;
|
||||||
@ -5823,6 +5830,7 @@ var
|
|||||||
begin
|
begin
|
||||||
{ Analyze the workbook and collect all information needed }
|
{ Analyze the workbook and collect all information needed }
|
||||||
ListAllNumFormats;
|
ListAllNumFormats;
|
||||||
|
ListAllChartStyles;
|
||||||
ListAllColumnStyles;
|
ListAllColumnStyles;
|
||||||
ListAllRowStyles;
|
ListAllRowStyles;
|
||||||
ListAllHeaderFooterFonts;
|
ListAllHeaderFooterFonts;
|
||||||
@ -5864,6 +5872,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadOpenDocWriter.ListAllChartStyles;
|
||||||
|
var
|
||||||
|
book: TsWorkbook;
|
||||||
|
chart: TsChart;
|
||||||
|
i: Integer;
|
||||||
|
styles: TsChartStyleList;
|
||||||
|
begin
|
||||||
|
book := TsWorkbook(FWorkbook);
|
||||||
|
styles := TsChartStyleList(FChartStyleList);
|
||||||
|
for i := 0 to book.GetChartCount-1 do
|
||||||
|
begin
|
||||||
|
chart := book.GetChartByIndex(i);
|
||||||
|
styles.FindChartBackGroundStyle(chart);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocWriter.ListAllColumnStyles;
|
procedure TsSpreadOpenDocWriter.ListAllColumnStyles;
|
||||||
var
|
var
|
||||||
i, j, c: Integer;
|
i, j, c: Integer;
|
||||||
@ -6677,6 +6701,7 @@ end;
|
|||||||
procedure TsSpreadOpenDocWriter.WriteChart(AStream: TStream; AChart: TsChart);
|
procedure TsSpreadOpenDocWriter.WriteChart(AStream: TStream; AChart: TsChart);
|
||||||
var
|
var
|
||||||
chartClass: String;
|
chartClass: String;
|
||||||
|
idx: Integer;
|
||||||
begin
|
begin
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
XML_HEADER + LE);
|
XML_HEADER + LE);
|
||||||
@ -6731,12 +6756,14 @@ begin
|
|||||||
if chartClass <> '' then
|
if chartClass <> '' then
|
||||||
chartClass := ' chart:class="chart:' + chartClass + '"';
|
chartClass := ' chart:class="chart:' + chartClass + '"';
|
||||||
|
|
||||||
|
idx := TsChartStyleList(FChartStyleList).FindChartBackgroundStyle(AChart);
|
||||||
AppendToStream(AStream, Format(
|
AppendToStream(AStream, Format(
|
||||||
' <chart:chart svg:width="%.3fmm" svg:height="%.3fmm" xlink:href=".." ' + LE +
|
' <chart:chart svg:width="%.3fmm" svg:height="%.3fmm" xlink:href=".." ' + LE +
|
||||||
' xlink:type="simple"' + chartClass + ' chart:style-name="ch1"> ' + LE,
|
' xlink:type="simple"' + chartClass + ' chart:style-name="ch%d"> ' + LE,
|
||||||
[
|
[
|
||||||
AChart.Width, // Width, Height are in mm
|
AChart.Width, // Width, Height are in mm
|
||||||
AChart.Height
|
AChart.Height,
|
||||||
|
idx + 1
|
||||||
], FPointSeparatorSettings
|
], FPointSeparatorSettings
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -6941,6 +6968,45 @@ end;
|
|||||||
{ To do: The list of styles must be updated to the real chart element settings. }
|
{ To do: The list of styles must be updated to the real chart element settings. }
|
||||||
procedure TsSpreadOpenDocWriter.WriteChartStyles(AStream: TStream;
|
procedure TsSpreadOpenDocWriter.WriteChartStyles(AStream: TStream;
|
||||||
AChart: TsChart; AIndent: Integer);
|
AChart: TsChart; AIndent: Integer);
|
||||||
|
|
||||||
|
function GetChartBackgroundStyleXML(AIndent: Integer): String;
|
||||||
|
var
|
||||||
|
ind: String;
|
||||||
|
idx: Integer;
|
||||||
|
style: TsChartBackgroundStyle;
|
||||||
|
s, drawStroke, strokeColor, drawFillColor: String;
|
||||||
|
begin
|
||||||
|
idx := TsChartStyleList(FChartStyleList).FindChartBackgroundStyle(AChart);
|
||||||
|
if idx = -1 then
|
||||||
|
raise Exception.Create('Chart background style not found.');
|
||||||
|
style := TsChartBackgroundStyle(FChartStyleList[idx]);
|
||||||
|
|
||||||
|
case style.Border.Style of
|
||||||
|
clsNoLine: s := 'none';
|
||||||
|
clsSolid: s := 'solid';
|
||||||
|
else s := 'none'; // FIXME: get correct line styles from chart
|
||||||
|
end;
|
||||||
|
drawStroke := 'draw:stroke="' + s + '" ';
|
||||||
|
|
||||||
|
if style.Border.Style <> clsNoLine then
|
||||||
|
strokeColor := 'svg:stroke-color="' + ColorToHTMLColorStr(style.Border.Color) + '" '
|
||||||
|
else
|
||||||
|
strokeColor := '';
|
||||||
|
|
||||||
|
if style.Background.Style = fsSolidFill then
|
||||||
|
drawFillColor := 'draw:fill-color="' + ColorToHTMLColorStr(style.Background.FGColor) + '" '
|
||||||
|
else
|
||||||
|
drawFillColor := '';
|
||||||
|
|
||||||
|
ind := DupeString(' ', AIndent);
|
||||||
|
Result := Format(
|
||||||
|
ind + '<style:style style:name="ch%d" style:family="chart">' + LE +
|
||||||
|
ind + ' <style:graphic-properties %s%s%s />' + LE +
|
||||||
|
ind + '</style:style>' + LE,
|
||||||
|
[ idx+1, drawStroke, strokeColor, drawFillColor ]
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
ind: String;
|
ind: String;
|
||||||
begin
|
begin
|
||||||
@ -6953,10 +7019,12 @@ begin
|
|||||||
ind + ' </number:number-style>' + LE +
|
ind + ' </number:number-style>' + LE +
|
||||||
|
|
||||||
// ch1: style for <chart:chart> element
|
// ch1: style for <chart:chart> element
|
||||||
|
GetChartBackgroundStyleXML(AIndent + 2) +
|
||||||
|
{
|
||||||
ind + ' <style:style style:name="ch1" style:family="chart">' + LE +
|
ind + ' <style:style style:name="ch1" style:family="chart">' + LE +
|
||||||
ind + ' <style:graphic-properties draw:stroke="none"/>' + LE +
|
ind + ' <style:graphic-properties draw:stroke="solid"/>' + LE + // '
|
||||||
ind + ' </style:style>' + LE +
|
ind + ' </style:style>' + LE +
|
||||||
|
}
|
||||||
// ch2: style for <chart:title> element
|
// ch2: style for <chart:title> element
|
||||||
ind + ' <style:style style:name="ch2" style:family="chart">' + LE +
|
ind + ' <style:style style:name="ch2" style:family="chart">' + LE +
|
||||||
ind + ' <style:chart-properties chart:auto-position="true" style:rotation-angle="0"/>' + LE +
|
ind + ' <style:chart-properties chart:auto-position="true" style:rotation-angle="0"/>' + LE +
|
||||||
@ -8956,6 +9024,7 @@ constructor TsSpreadOpenDocWriter.Create(AWorkbook: TsBasicWorkbook);
|
|||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
|
|
||||||
|
FChartStyleList := TsChartStyleList.Create;
|
||||||
FColumnStyleList := TFPList.Create;
|
FColumnStyleList := TFPList.Create;
|
||||||
FRowStyleList := TFPList.Create;
|
FRowStyleList := TFPList.Create;
|
||||||
FRichTextFontList := TStringList.Create;
|
FRichTextFontList := TStringList.Create;
|
||||||
@ -8980,6 +9049,7 @@ begin
|
|||||||
|
|
||||||
FRichTextFontList.Free; // Do not destroy fonts, they are owned by Workbook
|
FRichTextFontList.Free; // Do not destroy fonts, they are owned by Workbook
|
||||||
FHeaderFooterFontList.Free;
|
FHeaderFooterFontList.Free;
|
||||||
|
FChartStyleList.Free;
|
||||||
|
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
Reference in New Issue
Block a user