From dbe0f0dec50b45c44d8fa2f6dbe1a5d96a077fc2 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Tue, 16 Jan 2024 12:55:53 +0000 Subject: [PATCH] fpspreadsheet: xlsx reader supports bubble series. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9145 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../source/common/xlsxooxmlchart.pas | 64 ++++++++++++++++++- .../source/visual/fpspreadsheetchart.pas | 4 ++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/components/fpspreadsheet/source/common/xlsxooxmlchart.pas b/components/fpspreadsheet/source/common/xlsxooxmlchart.pas index ceb2b0001..83f9f5e44 100644 --- a/components/fpspreadsheet/source/common/xlsxooxmlchart.pas +++ b/components/fpspreadsheet/source/common/xlsxooxmlchart.pas @@ -40,6 +40,7 @@ type procedure ReadChartAxisScaling(ANode: TDOMNode; AChartAxis: TsChartAxis); function ReadChartAxisTickMarks(ANode: TDOMNode): TsChartAxisTicks; procedure ReadChartBarSeries(ANode: TDOMNode; AChart: TsChart); + procedure ReadChartBubbleSeries(ANode: TDOMNode; AChart: TsChart); procedure ReadChartLegend(ANode: TDOMNode; AChartLegend: TsChartLegend); procedure ReadChartLineSeries(ANode: TDOMNode; AChart: TsChart); procedure ReadChartPlotArea(ANode: TDOMNode; AChart: TsChart); @@ -390,6 +391,44 @@ begin end; end; +{@@ ---------------------------------------------------------------------------- + Creates a bubble series and reads its parameters. + + @@param ANode Child of a node. + @@param AChart Chart into which the series will be inserted. +-------------------------------------------------------------------------------} +procedure TsSpreadOOXMLChartReader.ReadChartBubbleSeries(ANode: TDOMNode; + AChart: TsChart); +var + nodeName: String; + s: String; + ser: TsBubbleSeries; + smooth: Boolean; +begin + if ANode = nil then + exit; + while Assigned(ANode) do + begin + nodeName := ANode.NodeName; + s := GetAttrValue(ANode, 'val'); + case nodeName of + 'c:bubbleScale': ; + 'c:showNegBubbles': ; + 'c:varyColors': ; + 'c:ser': + begin + ser := TsBubbleSeries.Create(AChart); + ReadChartSeriesProps(ANode.FirstChild, ser); + end; + 'c:dLbls': + ; + 'c:axId': + ReadChartSeriesAxis(ANode, ser); + end; + ANode := ANode.NextSibling; + end; +end; + function TsSpreadOOXMLChartReader.ReadChartColor(ANode: TDOMNode; ADefault: TsColor): TsColor; var @@ -462,6 +501,18 @@ begin s := GetAttrValue(ANode, 'val'); if s <> '' then AColor := HTMLColorStrToColor(s); + child := ANode.FirstChild; + while Assigned(child) do + begin + nodeName := child.NodeName; + s := GetAttrValue(child, 'val'); + case nodeName of + 'a:alpha': + if TryStrToInt(s, n) then + Alpha := n / 100000; + end; + child := child.NextSibling; + end; end; end; end; @@ -480,6 +531,7 @@ begin if ANode = nil then exit; + alpha := 1.0; while Assigned(ANode) do begin nodeName := ANode.NodeName; @@ -488,7 +540,8 @@ begin 'a:solidFill': begin AFill.Style := cfsSolid; - AFill.Color := ReadChartColor(ANode.FirstChild, scWhite); + ReadChartColor(ANode.FirstChild, AFill.Color, alpha); + AFill.Transparency := 1.0 - alpha; end; // Gradient fill @@ -915,7 +968,7 @@ begin while Assigned(workNode) do begin nodeName := workNode.NodeName; - if nodeName = 'c:scatterChart' then + if (nodeName = 'c:scatterChart') or (nodeName = 'c:bubbleChart') then begin isScatterChart := true; break; @@ -991,6 +1044,8 @@ begin ReadChartAreaSeries(workNode.FirstChild, AChart); 'c:barChart': ReadChartBarSeries(workNode.FirstChild, AChart); + 'c:bubbleChart': + ReadChartBubbleSeries(workNode.FirstChild, AChart); 'c:lineChart': ReadChartLineSeries(workNode.FirstChild, AChart); 'c:scatterChart': @@ -1277,6 +1332,11 @@ begin ReadChartSeriesRange(ANode.FirstChild, ASeries.XRange); 'c:val', 'c:yVal': ReadChartSeriesRange(ANode.FirstChild, ASeries.YRange); + 'c:bubbleSize': + if ASeries is TsBubbleSeries then + ReadChartSeriesRange(ANode.FirstChild, TsBubbleSeries(ASeries).BubbleRange); + 'c:bubble3D': + ; 'c:spPr': ReadChartFillAndLineProps(ANode.FirstChild, ASeries.Chart, ASeries.Fill, ASeries.Line); 'c:dLbls': diff --git a/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas b/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas index 7c73d2335..5f1d7171e 100644 --- a/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas +++ b/components/fpspreadsheet/source/visual/fpspreadsheetchart.pas @@ -1800,6 +1800,7 @@ procedure TsWorkbookChartLink.UpdateAreaSeries(AWorkbookSeries: TsAreaSeries; begin UpdateChartBrush(AWorkbookSeries.Chart, AWorkbookSeries.Fill, AChartSeries.AreaBrush); UpdateChartPen(AWorkbookSeries.Chart, AWorkbookSeries.Line, AChartSeries.AreaContourPen); + AChartSeries.Transparency := round(AWorkbookSeries.Fill.Transparency * 255); AChartSeries.AreaLinesPen.Style := psClear; AChartSeries.Stacked := AWorkbookSeries.Chart.StackMode <> csmSideBySide; AChartSeries.UseZeroLevel := true; @@ -1818,6 +1819,7 @@ procedure TsWorkbookChartLink.UpdateBarSeries(AWorkbookSeries: TsBarSeries; begin UpdateChartBrush(AWorkbookSeries.Chart, AWorkbookSeries.Fill, AChartSeries.BarBrush); UpdateChartPen(AWorkbookSeries.Chart, AWorkbookSeries.Line, AChartSeries.BarPen); + AChartSeries.Transparency := round(AWorkbookSeries.Fill.Transparency * 255); AChartSeries.BarWidthPercent := AWorkbookSeries.BarWidthPercent; AChartSeries.BarOffsetPercent := AWorkbookSeries.BarOffsetPercent; AChartSeries.BarWidthStyle := bwPercentMin; @@ -1834,6 +1836,8 @@ procedure TsWorkbookChartlink.UpdateBubbleSeries(AWorkbookSeries: TsBubbleSeries begin UpdateChartBrush(AWorkbookSeries.Chart, AWorkbookSeries.Fill, AChartSeries.BubbleBrush); UpdateChartPen(AWorkbookSeries.Chart, AWorkbookSeries.Line, AChartSeries.BubblePen); + AChartSeries.Transparency := round(255*AWorkbookSeries.Fill.Transparency); + {$IF LCL_FullVersion >= 3990000} AChartSeries.BubbleRadiusUnits := bruPercentage; AChartSeries.ParentChart.ExpandPercentage := 10;