diff --git a/components/fpspreadsheet/examples/other/chart/barchart_date_write_demo.lpi b/components/fpspreadsheet/examples/other/chart/barchart_date_write_demo.lpi new file mode 100644 index 000000000..9dd6f7dcd --- /dev/null +++ b/components/fpspreadsheet/examples/other/chart/barchart_date_write_demo.lpi @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes> + <Item Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <RequiredPackages> + <Item> + <PackageName Value="laz_fpspreadsheet"/> + </Item> + </RequiredPackages> + <Units> + <Unit> + <Filename Value="barchart_date_write_demo.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="barchart_date_write_demo"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf3"/> + </Debugging> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/components/fpspreadsheet/examples/other/chart/barchart_date_write_demo.lpr b/components/fpspreadsheet/examples/other/chart/barchart_date_write_demo.lpr new file mode 100644 index 000000000..f4d3c50d5 --- /dev/null +++ b/components/fpspreadsheet/examples/other/chart/barchart_date_write_demo.lpr @@ -0,0 +1,90 @@ +program barchart_date_write_demo; + +{.$DEFINE DARK_MODE} + +uses + SysUtils, + fpspreadsheet, fpstypes, fpsUtils, fpschart, xlsxooxml, fpsopendocument; + +const + FILE_NAME = 'bars_date'; +var + book: TsWorkbook; + sheet: TsWorksheet; + ch: TsChart; + ser: TsChartSeries; + dir, fn: String; + i: Integer; +begin + fn := FILE_NAME; + dir := 'files/'; + ForceDirectories(dir); + + book := TsWorkbook.Create; + try + // worksheet + sheet := book.AddWorksheet('bar_series'); + + // Enter data + sheet.WriteText( 0, 0, 'Sales'); + sheet.WriteFont( 0, 0, '', 12, [fssBold], scBlack); + + sheet.WriteText( 2, 0, ''); + sheet.WriteText( 2, 1, 'Product A'); + sheet.WriteText( 2, 2, 'Product B'); + + sheet.WriteDateTime( 3, 0, EncodeDate(2024,1,1), 'mmm yyyy' ); sheet.WriteNumber( 3, 1, 12); sheet.WriteNumber( 3, 2, 15); + sheet.WriteDateTime( 4, 0, EncodeDate(2024,2,1), 'mmm yyyy' ); sheet.WriteNumber( 4, 1, 11); sheet.WriteNumber( 4, 2, 13); + sheet.WriteDateTime( 5, 0, EncodeDate(2024,3,1), 'mmm yyyy' ); sheet.WriteNumber( 5, 1, 16); sheet.WriteNumber( 5, 2, 11); + sheet.WriteDateTime( 6, 0, EncodeDate(2024,4,1), 'mmm yyyy' ); sheet.WriteNumber( 6, 1, 18); sheet.WriteNumber( 6, 2, 11); + sheet.WriteDateTime( 7, 0, EncodeDate(2024,5,1), 'mmm yyyy' ); sheet.WriteNumber( 7, 1, 16); sheet.WriteNumber( 7, 2, 7); + sheet.WriteDateTime( 8, 0, EncodeDate(2024,6,1), 'mmm yyyy' ); sheet.WriteNumber( 8, 1, 10); sheet.WriteNumber( 8, 2, 17); + + // Create chart: left/top in cell D4, 160 mm x 100 mm + ch := sheet.AddChart(160, 100, 2, 3); + + // Chart properties + ch.Border.Style := clsNoLine; + ch.Title.Caption := 'Sales'; + ch.Title.Font.Style := [fssBold]; + ch.Legend.Border.Style := clsNoLine; + //ch.XAxis.DateTime := true; // Switches the axis to date/time labels, not needed for Excel + //ch.XAxis.LabelFormatDateTime := 'mm yyyy'; // Defines the label format of the dates + ch.XAxis.Title.Caption := ''; + ch.YAxis.Title.Caption := 'Total'; + ch.YAxis.AxisLine.Color := ChartColor(scSilver); + ch.YAxis.MajorTicks := []; + ch.BarGapWidthPercent := 75; + + // Add 1st bar series ("Product A") + ser := TsBarSeries.Create(ch); + ser.SetTitleAddr(2, 1); // series 1, title in cell B3 + ser.SetLabelRange(3, 0, 8, 0); // series 1, x labels in A4:A11 + ser.SetYRange(3, 1, 8, 1); // series 1, y values in B4:B11 + ser.Line.Color := ChartColor(scDarkRed); + ser.Fill.Style := cfsSolidHatched; + ser.Fill.Hatch := ch.Hatches.AddLineHatch('Crossed', chsDouble, ChartColor(scDarkRed), 2, 0.1, 45); + ser.Fill.Color := ChartColor(scRed); + ser.DataLabels := [cdlValue]; // Show sales as datapoint labels + + // Add 2nd bar series ("Product B") + ser := TsBarSeries.Create(ch); + ser.SetTitleAddr(2, 2); // series 2, title in cell C3 + ser.SetLabelRange(3, 0, 8, 0); // series 2, x labels in A4:A11 + ser.SetYRange(3, 2, 8, 2); // series 2, y values in C4:C11 + ser.Line.Color := ChartColor(scDarkBlue); + ser.Fill.Style := cfsSolidHatched; + ser.Fill.Hatch := ch.Hatches.AddLineHatch('Forward', chsSingle, ChartColor(scWhite), 1.5, 0.1, 45); + ser.Fill.Color := ChartColor(scBlue); + ser.DataLabels := [cdlValue]; // Show sales as datapoint labels + + book.WriteToFile(dir + fn + '.xlsx', true); + WriteLn('... ', fn + '.xlsx'); + + book.WriteToFile(dir + fn + '.ods', true); + WriteLn('... ', fn + '.ods'); + finally + book.Free; + end; +end. + diff --git a/components/fpspreadsheet/examples/other/chart/scatter_date_write_demo.lpi b/components/fpspreadsheet/examples/other/chart/scatter_date_write_demo.lpi new file mode 100644 index 000000000..39ec075d6 --- /dev/null +++ b/components/fpspreadsheet/examples/other/chart/scatter_date_write_demo.lpi @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectOptions> + <Version Value="12"/> + <PathDelim Value="\"/> + <General> + <Flags> + <MainUnitHasCreateFormStatements Value="False"/> + <MainUnitHasTitleStatement Value="False"/> + <MainUnitHasScaledStatement Value="False"/> + </Flags> + <SessionStorage Value="InProjectDir"/> + <Title Value="scatter_date_write_demo"/> + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes> + <Item Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <RequiredPackages> + <Item> + <PackageName Value="laz_fpspreadsheet"/> + </Item> + </RequiredPackages> + <Units> + <Unit> + <Filename Value="scatter_date_write_demo.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="scatter_date_write_demo"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf3"/> + </Debugging> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/components/fpspreadsheet/examples/other/chart/scatter_date_write_demo.lpr b/components/fpspreadsheet/examples/other/chart/scatter_date_write_demo.lpr new file mode 100644 index 000000000..d0c54e8ac --- /dev/null +++ b/components/fpspreadsheet/examples/other/chart/scatter_date_write_demo.lpr @@ -0,0 +1,79 @@ +program scatter_date_write_demo; + +{$mode objfpc}{$H+} + +uses + SysUtils, + fpspreadsheet, fpstypes, fpsUtils, fpschart, xlsxooxml, fpsopendocument; + +const + FILE_NAME = 'scatter-date'; + FMT = 'yyyy-mm-dd'; +var + book: TsWorkbook; + sheet: TsWorksheet; + ch: TsChart; + ser: TsScatterSeries; + dir, fn: String; + +begin + dir := 'files/'; + ForceDirectories(dir); + fn := FILE_NAME; + + book := TsWorkbook.Create; + try + // Worksheet + sheet := book.AddWorksheet('scatter_date'); + + // Enter data + sheet.WriteText( 0, 0, 'Data'); + sheet.WriteFont( 0, 0, '', 12, [fssBold], scBlack); + sheet.WriteText( 2, 0, 'x'); + sheet.WriteText( 2, 1, 'y'); + + sheet.WriteDateTime( 3, 0, EncodeDate(2024, 1, 1), FMT); sheet.WriteNumber( 3, 1, 12.4); + sheet.WriteDateTime( 4, 0, EncodeDate(2024, 2,15), FMT); sheet.WriteNumber( 4, 1, 18.8); + sheet.WriteDateTime( 5, 0, EncodeDate(2024, 6,20), FMT); sheet.WriteNumber( 5, 1, 21.3); + sheet.WriteDateTime( 6, 0, EncodeDate(2024, 7, 9), FMT); sheet.WriteNumber( 6, 1, 20.5); + sheet.WriteDateTime( 7, 0, EncodeDate(2024, 8,21), FMT); sheet.WriteNumber( 7, 1, 22.9); + sheet.WriteDateTime( 8, 0, EncodeDate(2024, 8,31), FMT); sheet.WriteNumber( 8, 1, 19.4); + sheet.WriteDateTime( 9, 0, EncodeDate(2024,11, 3), FMT); sheet.WriteNumber( 9, 1, 17.7); + sheet.WriteDateTime(10, 0, EncodeDate(2024,12,28), FMT); sheet.WriteNumber(10, 1, 12.9); + + // Create chart: left/top in cell D4, 160 mm x 100 mm + ch := sheet.AddChart(160, 100, 2, 2); + + // Chart properties + ch.Border.Style := clsNoLine; + ch.Legend.Border.Style := clsNoLine; + ch.xAxis.LabelFormatDateTime := FMT; + ch.xAxis.DateTime := true; + + // Add scatter series + ser := TsScatterSeries.Create(ch); + + // Series properties + ser.SetTitleAddr(0, 0); // A1 + ser.SetXRange(3, 0, 10, 0); // A4:A11 + ser.SetYRange(3, 1, 10, 1); // B4:B11 + ser.ShowLines := true; + ser.ShowSymbols := true; + ser.Symbol := cssCircle; + ser.SymbolFill.Style := cfsSolid; + ser.SymbolFill.Color := ChartColor(scRed); + ser.SymbolBorder.Style := clsNoLine; +// ser.Line.Style := clsDash; + ser.Line.Width := 0.5; // mm + + book.WriteToFile(dir + fn + '.xlsx', true); + WriteLn('... ', fn + '.xlsx'); + + book.Options := book.Options + [boCalcBeforeSaving]; + book.WriteToFile(dir + fn + '.ods', true); + WriteLn('... ', fn + '.ods'); + finally + book.Free; + end; +end. + diff --git a/components/fpspreadsheet/examples/other/chart/scatter_write_demo.lpr b/components/fpspreadsheet/examples/other/chart/scatter_write_demo.lpr index 5e1611a1d..06a5f2b1a 100644 --- a/components/fpspreadsheet/examples/other/chart/scatter_write_demo.lpr +++ b/components/fpspreadsheet/examples/other/chart/scatter_write_demo.lpr @@ -62,7 +62,8 @@ begin // Enter data sheet.WriteText(0, 0, 'Data'); sheet.WriteFont(0, 0, '', 12, [fssBold], scBlack); - sheet.WriteText ( 2, 0, 'x'); sheet.WriteText ( 2, 1, 'y'); + sheet.WriteText( 2, 0, 'x'); + sheet.WriteText( 2, 1, 'y'); case mode of 0: begin // linear sheet.WriteNumber( 3, 0, 0.1); sheet.WriteFormula( 3, 1, 'A4^2'); diff --git a/components/fpspreadsheet/source/common/fpschart.pas b/components/fpspreadsheet/source/common/fpschart.pas index eee9735ef..237cd9995 100644 --- a/components/fpspreadsheet/source/common/fpschart.pas +++ b/components/fpspreadsheet/source/common/fpschart.pas @@ -33,6 +33,7 @@ const ); type + {@@ Record describing a color used by charts, includes a Transparency element } TsChartColor = record Transparency: single; // 0.0 (opaque) ... 1.0 (transparent) case Integer of @@ -41,7 +42,7 @@ type end; const - sccTransparent: TsChartColor = (Transparency: 255; Color: 0); + sccTransparent: TsChartColor = (Transparency: 1.0; Color: 0); type TsChart = class; @@ -51,8 +52,7 @@ type TsChartLine = class Style: Integer; // index into chart's LineStyle list or predefined clsSolid/clsNoLine Width: Double; // mm - Color: TsChartColor; // in hex: $00bbggrr, r=red, g=green, b=blue - Transparency: Double; // in percent + Color: TsChartColor; // in hex: $00bbggrr, r=red, g=green, b=blue; contains Transparency constructor CreateSolid(AColor: TsChartColor; AWidth: Double); procedure CopyFrom(ALine: TsChartLine); end; @@ -928,6 +928,14 @@ uses { TsChartColor } +{@@ Helper function to create a record with a color for the fpspreadsheet charts. + The record contains a Transparency field. + + @param AColor RGB color + @param ATransparency Transparency of the color, value between 0.0 and 1.0 + + @returns A TsChartColor record + @seeAlso TsColor } function ChartColor(AColor: TsColor; ATransparency: Single = 0.0): TsChartColor; begin Result.Color := AColor; @@ -952,7 +960,6 @@ begin Style := ALine.Style; Width := ALine.Width; Color := ALine.Color; - Transparency := ALine.Transparency; end; end; diff --git a/components/fpspreadsheet/source/common/fpstypes.pas b/components/fpspreadsheet/source/common/fpstypes.pas index 30a29da01..d4b9b7653 100644 --- a/components/fpspreadsheet/source/common/fpstypes.pas +++ b/components/fpspreadsheet/source/common/fpstypes.pas @@ -289,7 +289,7 @@ type TsRelFlags = set of TsRelFlag; const - {@@ Abbreviation of all-relative cell reference flags (@seeAlso(TsRelFlag))} + {@@ Abbreviation of all-relative cell reference flags (@seeAlso TsRelFlag)} rfAllRel = [rfRelRow, rfRelCol, rfRelRow2, rfRelCol2]; {@@ Separator between worksheet name and cell (range) reference in an address }