From 67a83b5fae2f57f1effccb69f4af58d9df241d9c Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Sat, 27 Jan 2024 19:08:16 +0000 Subject: [PATCH] fpspreadsheet: xlsx reader supports series data point callouts. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9180 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../fpspreadsheet/source/common/fpschart.pas | 7 +++ .../source/common/xlsxooxmlchart.pas | 53 +++++++++++++++++-- .../source/visual/fpspreadsheetchart.pas | 9 ++++ 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/components/fpspreadsheet/source/common/fpschart.pas b/components/fpspreadsheet/source/common/fpschart.pas index 41d8db28e..dce565a22 100644 --- a/components/fpspreadsheet/source/common/fpschart.pas +++ b/components/fpspreadsheet/source/common/fpschart.pas @@ -386,6 +386,11 @@ type TsChartDataLabel = (cdlValue, cdlPercentage, cdlCategory, cdlSeriesName, cdlSymbol); TsChartDataLabels = set of TsChartDataLabel; TsChartLabelPosition = (lpDefault, lpOutside, lpInside, lpCenter); + TsChartLabelCalloutShape = ( + lcsRectangle, lcsRoundRect, lcsEllipse, + lcsLeftArrow, lcsUpArrow, lcsRightArrow, lcsDownArrow, + lcsRectangleWedge, lcsRoundRectWedge, lcsEllipseWedge + ); TsChartDataPointStyle = class(TsChartFillElement); @@ -501,6 +506,7 @@ type FTitleAddr: TsChartCellAddr; FLabelFormat: String; FDataLabels: TsChartDataLabels; + FDataLabelCalloutShape: TsChartLabelCalloutShape; FDataPointStyles: TsChartDataPointStyleList; FOrder: Integer; FRegression: TsChartRegression; @@ -542,6 +548,7 @@ type property ChartType: TsChartType read GetChartType; property Count: Integer read GetCount; property DataLabels: TsChartDataLabels read FDataLabels write FDataLabels; + property DataLabelCalloutShape: TsChartLabelCalloutShape read FDataLabelCalloutShape write FDataLabelCalloutShape; property DataPointStyles: TsChartDatapointStyleList read FDataPointStyles; property FillColorRange: TsChartRange read FFillColorRange write FFillColorRange; property LabelBackground: TsChartFill read FLabelBackground write FLabelBackground; diff --git a/components/fpspreadsheet/source/common/xlsxooxmlchart.pas b/components/fpspreadsheet/source/common/xlsxooxmlchart.pas index 692ed05d6..50a2d491d 100644 --- a/components/fpspreadsheet/source/common/xlsxooxmlchart.pas +++ b/components/fpspreadsheet/source/common/xlsxooxmlchart.pas @@ -1662,7 +1662,7 @@ procedure TsSpreadOOXMLChartReader.ReadChartSeriesLabels(ANode: TDOMNode; ASeries: TsChartSeries); var nodeName, s: String; - child, child2, child3: TDOMNode; + child1, child2, child3: TDOMNode; begin if ANode = nil then exit; @@ -1675,10 +1675,10 @@ begin ReadChartFillAndLineProps(ANode.FirstChild, ASeries.Chart, ASeries.LabelBackground, ASeries.LabelBorder); 'c:txPr': begin - child := ANode.FindNode('a:p'); - if Assigned(child) then + child1 := ANode.FindNode('a:p'); + if Assigned(child1) then begin - child2 := child.FirstChild; + child2 := child1.FirstChild; while Assigned(child2) do begin nodeName := child2.NodeName; @@ -1715,7 +1715,50 @@ begin 'c:showLeaderLines': ; 'c:extLst': - ; + begin + child1 := ANode.FirstChild; + while Assigned(child1) do + begin + nodeName := child1.NodeName; + if nodeName = 'c:ext' then + begin + child2 := child1.FirstChild; + while Assigned(child2) do + begin + nodeName := child2.NodeName; + if nodeName = 'c15:spPr' then + begin + child3 := child2.FindNode('a:prstGeom'); + if Assigned(child3) then + begin + s := GetAttrValue(child3, 'prst'); + case s of + 'rect': ASeries.DataLabelCalloutShape := lcsRectangle; + 'roundRect': ASeries.DataLabelCalloutShape := lcsRoundRect; + 'ellipse': ASeries.DataLabelCalloutShape := lcsEllipse; + 'rightArrowCallout': ASeries.DataLabelCalloutShape := lcsRightArrow; + 'downArrowCallout': ASeries.DataLabelCalloutShape := lcsDownArrow; + 'leftArrowCallout': ASeries.DataLabelCalloutShape := lcsLeftArrow; + 'upArrowCallout': ASeries.DataLabelCalloutShape := lcsUpArrow; + 'wedgeRectCallout': ASeries.DataLabelCalloutShape := lcsRectangleWedge; + 'wedgeRoundRectCallout': ASeries.DataLabelCalloutShape := lcsRoundRectWedge; + 'wedgeEllipseCallout': ASeries.DataLabelCalloutShape := lcsEllipseWedge; + else ASeries.DataLabelCalloutShape := lcsRectangle; + { + 'borderCallout1': ; + 'borderCallout2': ; + 'accentCallout1': ; + 'accentCallout2': ; + } + end; + end; + end; + child2 := child2.NextSibling; + end; + end; + child1 := child1.NextSibling; + end; + end; end; ANode := ANode.NextSibling; end; diff --git a/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas b/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas index c8426164f..571939a79 100644 --- a/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas +++ b/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas @@ -2435,6 +2435,15 @@ begin UpdateChartPen(AWorkbookSeries.Chart, AWorkbookSeries.LabelBorder, AChartSeries.Marks.Frame); UpdateChartBrush(AWorkbookSeries.Chart, AWorkbookSeries.LabelBackground, AChartSeries.Marks.LabelBrush); + case AWorkbookSeries.DataLabelCalloutShape of + lcsRectangle: AChartSeries.Marks.Shape := clsRectangle; + lcsRoundRect: AChartSeries.Marks.Shape := clsRoundRect; + lcsEllipse: AChartSeries.Marks.Shape := clsEllipse; + lcsRectangleWedge: AChartSeries.Marks.Shape := clsRectangle; // replacement + lcsRoundRectWedge: AChartSeries.Marks.Shape := clsRoundRect; // replacement + lcsEllipseWedge: AChartSeries.Marks.Shape := clsEllipse; // replacement + else AChartSeries.Marks.Shape := clsRectangle; // replacement + end; end; procedure TsWorkbookChartLink.UpdateChartSeriesRegression(AWorkbookSeries: TsChartSeries;