FPSpreadsheet: Improved presentation of date axis in chart. Testing to build documentation.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9448 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2024-09-18 17:57:40 +00:00
parent 712ce264ee
commit 7b43bd5894
11 changed files with 136 additions and 45 deletions

View File

@ -7,5 +7,6 @@
../../source/common/fpsrpn.pas
../../source/common/fpscurrency.pas
../../source/common/fpsconditionalformat.pas
../../source/common/fpschart.pas
../../source/visual/fpspreadsheetctrls.pas
../../source/visual/fpspreadsheetgrid.pas

View File

@ -4,13 +4,14 @@ rem set FMT=html
set FMT=chm
echo Downloading wiki...
wikiget --page=FPSpreadsheet --page=FPSpreadsheet:_Examples --page=FPSpreadsheet:_List_of_formulas --page=RPN_Formulas_in_FPSpreadsheet
wikiget --page=FPSpreadsheet --page=FPSpreadsheet:_Examples --page=FPSpreadsheet:_List_of_formulas --page=RPN_Formulas_in_FPSpreadsheet
wikiget --page=FPSpreadsheet:_Chart_Tutorial
wikiget --page=FPSpreadsheet_tutorial:_Writing_a_mini_spreadsheet_application
wikiget --page=TsWorksheetGrid --page=TsWorksheetChartSource
echo.
echo Converting wiki to chm...
wikiconvert --format=%FMT% --css=css/wiki.css --root="FPSpreadsheet wiki pages" --title="FPSpreadsheet wiki pages (offline version, created %DATE%)" --chm="..\fpspreadsheet-wiki.chm" wikixml/FPSpreadsheet.s00.xml wikixml/FPSpreadsheet=3A_Examples.s0300.xml wikixml/FPSpreadsheet=3A_List_of_formulas.s03000.xml wikixml/RPN_Formulas_in_FPSpreadsheet.u03g00.xml wikixml/FPSpreadsheet_tutorial=3A_Writing_a_mini_spreadsheet_application.s000c0000000.xml wikixml/TsWorksheetGrid.k08.xml
wikiconvert --format=%FMT% --css=css/wiki.css --root="FPSpreadsheet wiki pages" --title="FPSpreadsheet wiki pages (offline version, created %DATE%)" --chm="..\fpspreadsheet-wiki.chm" wikixml/FPSpreadsheet.s00.xml wikixml/FPSpreadsheet=3A_Examples.s0300.xml wikixml/FPSpreadsheet=3A_List_of_formulas.s03000.xml wikixml/RPN_Formulas_in_FPSpreadsheet.u03g00.xml wikixml/FPSpreadsheet_tutorial=3A_Writing_a_mini_spreadsheet_application.s000c0000000.xml wikixml/TsWorksheetGrid.k08.xml wikixml/FPSpreadsheet=3A_Chart_Tutorial.s03100.xml
set FMT=

View File

@ -68,11 +68,6 @@
<Debugging>
<DebugInfoType Value="dsDwarf3"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>

View File

@ -20,7 +20,7 @@ interface
uses
Classes, SysUtils, fpimage;
{$IF FPC_FullVersion < 30000}
{$IFDEF FPS_NO_RAWBYTESTRING}
{@@ This string type is not re-encoded by FPC. It is a standard type of FPC 3.0+,
its declaration must be repeated here in order to keep fpSpreadsheet usable by
older FPC versions. }
@ -92,8 +92,8 @@ type
@member LineEnding Specification for the line endings to be written (write-only)
@member Delimiter Column delimiter (read/write)
@member QuoteChar Character used for quoting text in special cases (read/write)
@member QuoteOuterWhiteSpace ...Determines whether cell content beginning/ending with white space will be quoted (write-only)
@member IgnoreOuterWhiteSpace...Ignores white space before/after cell content (read-only)
@member QuoteOuterWhiteSpace Determines whether cell content beginning/ending with white space will be quoted (write-only)
@member IgnoreOuterWhiteSpace Ignores white space before/after cell content (read-only)
@member Encoding String identifying the endoding of the file, such as 'utf8', 'cp1252' etc (read/write)
@member DetectContentType Try to convert strings to their content type (read-only)
@member NumberFormat If empty numbers are written like in worksheet, otherwise this format string is applied (write-only)

View File

@ -59,7 +59,7 @@ type
procedure ReadChartSeriesLabels(ANode: TDOMNode; ASeries: TsChartSeries);
procedure ReadChartSeriesMarker(ANode: TDOMNode; ASeries: TsCustomLineSeries);
procedure ReadChartSeriesProps(ANode: TDOMNode; ASeries: TsChartSeries);
procedure ReadChartSeriesRange(ANode: TDOMNode; ARange: TsChartRange);
procedure ReadChartSeriesRange(ANode: TDOMNode; ARange: TsChartRange; var AFormat: String);
procedure ReadChartSeriesTitle(ANode: TDOMNode; ASeries: TsChartSeries);
procedure ReadChartSeriesTrendLine(ANode: TDOMNode; ASeries: TsChartSeries);
procedure ReadChartStockSeries(ANode: TDOMNode; AChart: TsChart);
@ -374,6 +374,7 @@ var
n: LongInt;
x: Single;
node: TDOMNode;
srcLinked: Boolean;
begin
if ANode = nil then
exit;
@ -415,11 +416,20 @@ begin
ReadChartTitle(ANode.FirstChild, AChartAxis.Title);
'c:numFmt':
begin
s := GetAttrValue(ANode, 'formatCode');
if s = 'm/d/yyyy' then
AChartAxis.LabelFormat := FReader.Workbook.FormatSettings.ShortDateFormat
else
AChartAxis.LabelFormat := s;
srcLinked := GetAttrValue(ANode, 'sourceLinked') = '1';
if not srcLinked then
begin
s := GetAttrValue(ANode, 'formatCode');
if s = 'm/d/yyyy' then
AChartAxis.LabelFormat := FReader.Workbook.FormatSettings.ShortDateFormat
else
if IsDateTimeFormat(s) then
begin
AChartAxis.DateTime := true;
AChartAxis.LabelFormatDateTime := s;
end else
AChartAxis.LabelFormat := s;
end;
end;
'c:majorTickMark':
AChartAxis.MajorTicks := ReadChartAxisTickMarks(ANode);
@ -1806,6 +1816,7 @@ var
val: Double;
errorBars: TsChartErrorBars = nil;
part: String = '';
fmt: String = '';
begin
if ANode = nil then
exit;
@ -1877,9 +1888,9 @@ begin
errorBars.ValueNeg := val;
end;
'c:plus':
ReadChartSeriesRange(node.FirstChild, errorBars.RangePos);
ReadChartSeriesRange(node.FirstChild, errorBars.RangePos, fmt);
'c:minus':
ReadChartSeriesRange(node.FirstChild, errorBars.RangeNeg);
ReadChartSeriesRange(node.FirstChild, errorBars.RangeNeg, fmt);
'c:spPr':
ReadChartLineProps(node.FirstChild, ASeries.Chart, errorBars.Line);
'c:noEndCap':
@ -2021,9 +2032,10 @@ end;
procedure TsSpreadOOXMLChartReader.ReadChartSeriesProps(ANode: TDOMNode; ASeries: TsChartSeries);
var
nodeName, s: String;
nodeName, fmt, s: String;
n: Integer;
idx: Integer;
ax: TsChartAxis;
smooth: Boolean = false;
begin
if ANode = nil then
@ -2040,16 +2052,32 @@ begin
ASeries.Order := n;
'c:tx':
ReadChartSeriesTitle(ANode.FirstChild, ASeries);
'c:cat':
ReadChartSeriesRange(ANode.FirstChild, ASeries.LabelRange);
'c:xVal':
ReadChartSeriesRange(ANode.FirstChild, ASeries.XRange);
'c:val', 'c:yVal':
'c:cat': // Category axis
begin
ReadChartSeriesRange(ANode.FirstChild, ASeries.LabelRange, fmt);
ax := ASeries.GetXAxis;
if IsDateTimeFormat(fmt) then
begin
if ax.LabelFormatDateTime = '' then
ax.LabelFormatDateTime := fmt;
end else
begin
if ax.LabelFormat = '' then
ax.LabelFormat := fmt;
end;
end;
'c:xVal': // x value axis
ReadChartSeriesRange(ANode.FirstChild, ASeries.XRange, fmt);
'c:val', // y value axis in categorized series
'c:yVal': // y value axis
if ASeries.YRange.IsEmpty then // TcStockSeries already has read the y range...
ReadChartSeriesRange(ANode.FirstChild, ASeries.YRange);
begin
ReadChartSeriesRange(ANode.FirstChild, ASeries.YRange, fmt);
ASeries.LabelFormat := fmt;
end;
'c:bubbleSize':
if ASeries is TsBubbleSeries then
ReadChartSeriesRange(ANode.FirstChild, TsBubbleSeries(ASeries).BubbleRange);
ReadChartSeriesRange(ANode.FirstChild, TsBubbleSeries(ASeries).BubbleRange, fmt);
'c:bubble3D':
;
'c:spPr':
@ -2084,14 +2112,18 @@ end;
@@param ANode First child of a <c:val>, <c:yval> or <c:cat> node below <c:ser>.
@@param ARange Cell range to which the range parameters will be assigned.
@@param AFormat Numberformat string
-------------------------------------------------------------------------------}
procedure TsSpreadOOXMLChartReader.ReadChartSeriesRange(ANode: TDOMNode; ARange: TsChartRange);
procedure TsSpreadOOXMLChartReader.ReadChartSeriesRange(ANode: TDOMNode;
ARange: TsChartRange; var AFormat: String);
var
node, child: TDomNode;
nodeName, s: String;
sheet1, sheet2: String;
r1, c1, r2, c2: Cardinal;
flags: TsRelFlags;
begin
AFormat := '';
if ANode = nil then
exit;
while Assigned(ANode) do
@ -2099,6 +2131,38 @@ begin
nodeName := ANode.NodeName;
if (nodeName = 'c:strRef') or (nodeName = 'c:numRef') then
begin
node := ANode.FirstChild;
while Assigned(node) do
begin
nodeName := node.NodeName;
case nodeName of
'c:f':
begin
s := GetNodeValue(node);
if ParseCellRangeString(s, sheet1, sheet2, r1, c1, r2, c2, flags) then
begin
if sheet2 = '' then sheet2 := sheet1;
ARange.Sheet1 := sheet1;
ARange.Sheet2 := sheet2;
ARange.Row1 := r1;
ARange.Col1 := c1;
ARange.Row2 := r2;
ARange.Col2 := c2;
end;
end;
'c:numCache':
begin
child := node.FindNode('c:formatCode');
if Assigned(child) then
AFormat := GetNodeValue(child);
end;
end;
node := node.NextSibling;
end;
end;
ANode := ANode.NextSibling;
(*
ANode := ANode.FindNode('c:f');
if ANode <> nil then
begin
@ -2117,6 +2181,7 @@ begin
end;
end;
ANode := ANode.NextSibling;
*)
end;
end;
@ -2234,7 +2299,7 @@ procedure TsSpreadOOXMLChartReader.ReadChartStockSeries(ANode: TDOMNode;
AChart: TsChart);
var
ser: TsStockSeries;
nodeName: String;
nodeName, fmt: String;
sernode, child: TDOMNode;
begin
if ANode = nil then
@ -2266,14 +2331,14 @@ begin
}
'c:val':
if ser.CloseRange.IsEmpty then
ReadChartSeriesRange(child.FirstChild, ser.CloseRange)
ReadChartSeriesRange(child.FirstChild, ser.CloseRange, fmt)
else if ser.LowRange.IsEmpty then
ReadChartSeriesRange(child.FirstChild, ser.LowRange)
ReadChartSeriesRange(child.FirstChild, ser.LowRange, fmt)
else if ser.HighRange.IsEmpty then
ReadChartSeriesRange(child.FirstChild, ser.HighRange)
ReadChartSeriesRange(child.FirstChild, ser.HighRange, fmt)
else if ser.OpenRange.IsEmpty then
begin
ReadChartSeriesRange(child.FirstChild, ser.OpenRange);
ReadChartSeriesRange(child.FirstChild, ser.OpenRange, fmt);
ser.CandleStick := true;
end;
end;

View File

@ -25,6 +25,15 @@
{ The next defines activate code duplicated from new compiler versions in case
an old compiler is used. }
{ Activate the following define if your Lazarus version is older than v1.8 }
{.$DEFINE LCL_FullVersion_LT_v180}
{ Activate the following define if your Lazarus version is older than v1.9 }
{.$DEFINE LCL_FullVersion_LT_v190}
{ Activate the following define if your Lazarus version is older than v2.0 }
{.$DEFINE LCL_FullVersion_LT_v200}
{ fpspreadsheet requires the function VarIsBool which was introduced by
fpc 2.6.4. If an older FPC versions is used define FPS_VARISBOOL. Keep
undefined for the current FPC version. }
@ -66,7 +75,22 @@
e.g. before v3.0 }
{.$DEFINE FPS_NO_STRING_SPLIT}
{ FPC versions before 3.0 did not support TRawByteString.
Enable the define FPS_NO_RAWBYTESTRING here if this is the case. }
{.$DEFINE FPS_NO_RAWBYTESTRING}
{ Very old FPC versions do not contain zip support in the unit zipper, and
until v3.3 zipper did not read pass-word protected ods files correctly.
Therefore, the following define must be activated if FPC is v3.3 or older. }
{$DEFINE FPS_PATCHED_ZIPPER}
// Fix dependent defines
{$IFDEF LCL_FULLVERSION_LT_200}
{$DEFINE LCL_FULLVERSION_LT_190}
{$ENDIF}
{$IFDEF LCL_FULLVERSION_LT_190}
{$DEFINE LCL_FULLVERSION_LT_180}
{$ENDIF}

View File

@ -688,11 +688,17 @@ begin
if cell <> nil then
case cell^.ContentType of
cctUTF8String, cctDateTime: // !!! Simplification here: we do not support real date values
cctUTF8String:
begin
ANumber := APointIndex;
AText := FWorksheets[ARangeIndex, AListIndex].ReadAsText(cell);
end;
cctDateTime:
begin
if not FWorksheets[ARangeIndex, AListIndex].ReadAsDateTime(cell, ANumber) then
ANumber := APointIndex;
AText := FWorksheets[ARangeIndex, AListIndex].ReadAsText(cell);
end;
else
ANumber := FWorksheets[ARangeIndex, AListIndex].ReadAsNumber(cell);
AText := '';
@ -2385,7 +2391,7 @@ begin
FChart.BottomAxis.Marks.Style := smsLabel;
end;
end;
(*
// Date/time?
if AWorkbookChart.XAxis.DateTime then
begin
@ -2398,7 +2404,6 @@ begin
DateTimeFormat := AWorkbookChart.XAxis.LabelFormat;
end;
end;
*)
end;
procedure TsWorkbookChartLink.UpdateChartBackground(AWorkbookChart: TsChart);

View File

@ -702,7 +702,7 @@ type
function SpreadsheetFormatInClipboard: Boolean;
{$IF LCL_FullVersion < 1080000}
{$IFDEF LCL_FULLVERSION_LT_180}
function ScalePPI(ALength: Integer): Integer;
{$IFEND}
@ -741,7 +741,7 @@ begin
end;
{$IF LCL_FullVersion < 1080000}
{$IFDEF LCL_FullVersion_LT_180}
function ScalePPI(ALength: Integer): Integer;
begin
Result := MulDiv(ALength, Screen.PixelsPerInch, 96);

View File

@ -330,7 +330,7 @@ type
const ACellRect: TGridRect): Boolean;
function MouseOnHeader(X, Y: Integer): Boolean;
procedure MouseUp(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override;
{$IF LCL_FullVersion >= 1090000}
{$IFNDEF LCL_FullVersion_LT_190000}
function MoveNextSelectable(Relative: Boolean; DCol, DRow: Integer): Boolean; override;
{$ENDIF}
procedure MoveSelection; override;
@ -596,10 +596,10 @@ type
defined by the rectangle. }
property TextRotations[ALeft, ATop, ARight, ABottom: Integer]: TsTextRotation
read GetTextRotations write SetTextRotations;
{$IF LCL_FullVersion >= 1080000}
{$IFNDEF LCL_FullVersion_LT_180}
{@@ Pixel coordinates of the top-left corner of the grid's cell area}
property TopLeftPx: TPoint read GetPxTopLeft;
{$IFEND}
{$ENDIF}
{@@ Parameter for vertical text alignment in the cell at column ACol and row ARow. }
property VertAlignment[ACol, ARow: Integer]: TsVertAlignment
read GetVertAlignment write SetVertAlignment;
@ -2771,11 +2771,11 @@ begin
Canvas.Brush.Color := clRed;
Canvas.Brush.Style := bsSolid;
Canvas.Pen.Style := psClear;
{$IF LCL_FullVersion >= 1080000}
commentSize := Scale96ToFont(COMMENT_SIZE);
{$ELSE}
{$IFDEF LCL_FULLVERSION_LT_180}
commentSize := ScalePPI(COMMENT_SIZE);
{$IFEND}
{$ELSE}
commentSize := Scale96ToFont(COMMENT_SIZE);
{$ENDIF}
if IsRightToLeft then
begin
P[0] := Point(ARect.Left, ARect.Top);
@ -5256,7 +5256,7 @@ begin
Refresh;
end;
{$IF LCL_FullVersion >= 1090000}
{$IFNDEF LCL_FULLVERSION_LT_v190} // Supported by Laz v1.9+
function TsCustomWorksheetGrid.MoveNextSelectable(Relative: Boolean; DCol, DRow: Integer
): Boolean;
var