From: PJ Fanning Date: Sun, 7 Aug 2022 22:19:10 +0000 (+0000) Subject: basic bubble chart support X-Git-Tag: REL_5_2_3~81 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=72983be27667ecb2d290ee22258f0299612196e0;p=poi.git basic bubble chart support git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1903272 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFArea3DChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFArea3DChartData.java index ebc0ee6305..397b8d8854 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFArea3DChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFArea3DChartData.java @@ -150,6 +150,13 @@ public class XDDFArea3DChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTAreaSer getCTAreaSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFAreaChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFAreaChartData.java index e09121225c..a6488d7415 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFAreaChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFAreaChartData.java @@ -23,12 +23,7 @@ import java.util.Map; import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; import org.apache.poi.xddf.usermodel.XDDFShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAreaChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAreaSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; @Beta public class XDDFAreaChartData extends XDDFChartData { @@ -131,6 +126,13 @@ public class XDDFAreaChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTAreaSer getCTAreaSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFBar3DChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFBar3DChartData.java index 3f6984f6e4..b4ba523573 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFBar3DChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFBar3DChartData.java @@ -24,12 +24,7 @@ import org.apache.poi.ooxml.util.POIXMLUnits; import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; import org.apache.poi.xddf.usermodel.XDDFShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTBar3DChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; @Beta public class XDDFBar3DChartData extends XDDFChartData { @@ -202,6 +197,13 @@ public class XDDFBar3DChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTBarSer getCTBarSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFBarChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFBarChartData.java index 9ff0bc0d94..26c2069db7 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFBarChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFBarChartData.java @@ -24,12 +24,7 @@ import org.apache.poi.ooxml.util.POIXMLUnits; import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; import org.apache.poi.xddf.usermodel.XDDFShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; @Beta public class XDDFBarChartData extends XDDFChartData { @@ -192,6 +187,13 @@ public class XDDFBarChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTBarSer getCTBarSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFBubbleChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFBubbleChartData.java new file mode 100644 index 0000000000..a55ae5e36b --- /dev/null +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFBubbleChartData.java @@ -0,0 +1,224 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.xddf.usermodel.chart; + +import java.util.List; +import java.util.Map; +import java.util.Collections; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.apache.poi.xddf.usermodel.XDDFShapeProperties; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBubbleChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBubbleSer; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData; + +/** + * @since POI 5.2.3 + */ +@Beta +public class XDDFBubbleChartData extends XDDFChartData { + private CTBubbleChart chart; + + public XDDFBubbleChartData( + XDDFChart parent, + CTBubbleChart chart, + XDDFChartAxis category, + XDDFValueAxis values) { + super(parent); + this.chart = chart; + Map categories = null; + Map mapValues = null; + categories = Collections.singletonMap(category.getId(), category); + mapValues = Collections.singletonMap(values.getId(), values); + for (CTBubbleSer series : chart.getSerList()) { + this.series.add(new Series(series, series.getXVal(), series.getYVal())); + } + defineAxes(categories, mapValues); + } + + @Internal + protected XDDFBubbleChartData( + XDDFChart parent, + CTBubbleChart chart, + Map categories, + Map values) { + super(parent); + this.chart = chart; + for (CTBubbleSer series : chart.getSerList()) { + this.series.add(new Series(series, series.getXVal(), series.getYVal())); + } + defineAxes(categories, values); + } + + private void defineAxes(Map categories, Map values) { + if (chart.sizeOfAxIdArray() == 0) { + for (Long id : categories.keySet()) { + chart.addNewAxId().setVal(id); + } + for (Long id : values.keySet()) { + chart.addNewAxId().setVal(id); + } + } + defineAxes(chart.getAxIdArray(), categories, values); + } + + @Internal + @Override + protected void removeCTSeries(int n) { + chart.removeSer(n); + } + + @Override + public void setVaryColors(Boolean varyColors) { + if (varyColors == null) { + if (chart.isSetVaryColors()) { + chart.unsetVaryColors(); + } + } else { + if (chart.isSetVaryColors()) { + chart.getVaryColors().setVal(varyColors); + } else { + chart.addNewVaryColors().setVal(varyColors); + } + } + } + + @Override + public XDDFChartData.Series addSeries(XDDFDataSource category, + XDDFNumericalDataSource values) { + final long index = this.parent.incrementSeriesCount(); + try { + final CTBubbleSer ctSer = this.chart.addNewSer(); + ctSer.addNewXVal(); + ctSer.addNewYVal(); + ctSer.addNewIdx().setVal(index); + ctSer.addNewOrder().setVal(index); + final Series added = new Series(ctSer, category, values); + this.series.add(added); + return added; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + public class Series extends XDDFChartData.Series { + private CTBubbleSer series; + + protected Series(CTBubbleSer series, XDDFDataSource category, XDDFNumericalDataSource values) { + super(category, values); + this.series = series; + } + + /** + * @since POI 5.2.3 + */ + public CTBubbleSer getCTBubbleSer() { + return series; + } + + protected Series(CTBubbleSer series, CTAxDataSource category, CTNumDataSource values) { + super(XDDFDataSourcesFactory.fromDataSource(category), XDDFDataSourcesFactory.fromDataSource(values)); + this.series = series; + } + + public void setBubbleSizes(XDDFNumericalDataSource values) { + try { + if (series.isSetBubbleSize()) series.unsetBubbleSize(); + CTNumDataSource bubbleSizes = series.addNewBubbleSize(); + CTNumData cache = retrieveNumCache(bubbleSizes, values); + values.fillNumericalCache(cache); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + @Override + protected CTSerTx getSeriesText() { + if (series.isSetTx()) { + return series.getTx(); + } else { + return series.addNewTx(); + } + } + + @Override + public void setShowLeaderLines(boolean showLeaderLines) { + if (!series.isSetDLbls()) { + series.addNewDLbls(); + } + if (series.getDLbls().isSetShowLeaderLines()) { + series.getDLbls().getShowLeaderLines().setVal(showLeaderLines); + } else { + series.getDLbls().addNewShowLeaderLines().setVal(showLeaderLines); + } + } + + @Override + public XDDFShapeProperties getShapeProperties() { + if (series.isSetSpPr()) { + return new XDDFShapeProperties(series.getSpPr()); + } else { + return null; + } + } + + @Override + public void setShapeProperties(XDDFShapeProperties properties) { + if (properties == null) { + if (series.isSetSpPr()) { + series.unsetSpPr(); + } + } else { + if (series.isSetSpPr()) { + series.setSpPr(properties.getXmlObject()); + } else { + series.addNewSpPr().set(properties.getXmlObject()); + } + } + } + + @Override + protected CTAxDataSource getAxDS() { + return series.getXVal(); + } + + @Override + protected CTNumDataSource getNumDS() { + return series.getYVal(); + } + + @Override + protected void setIndex(long val) { + series.getIdx().setVal(val); + } + + @Override + protected void setOrder(long val) { + series.getOrder().setVal(val); + } + + @Override + protected List getDPtList() { + return series.getDPtList(); + } + } +} diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFChartData.java index 4669e2e707..c8e92fea64 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFChartData.java @@ -380,7 +380,7 @@ public abstract class XDDFChartData { return strCache; } - private CTNumData retrieveNumCache(final CTNumDataSource numDataSource, XDDFDataSource data) { + protected CTNumData retrieveNumCache(final CTNumDataSource numDataSource, XDDFDataSource data) { CTNumData numCache; if (data.isReference()) { CTNumRef numRef; diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFDoughnutChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFDoughnutChartData.java index 23020f842a..56137092f6 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFDoughnutChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFDoughnutChartData.java @@ -23,12 +23,7 @@ import org.apache.poi.ooxml.util.POIXMLUnits; import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; import org.apache.poi.xddf.usermodel.XDDFShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTDoughnutChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; @Beta public class XDDFDoughnutChartData extends XDDFChartData { @@ -142,6 +137,13 @@ public class XDDFDoughnutChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTPieSer getCTPieSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFLine3DChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFLine3DChartData.java index 5313e8825d..68a60bcfc5 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFLine3DChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFLine3DChartData.java @@ -87,31 +87,31 @@ public class XDDFLine3DChartData extends XDDFChartData { return Grouping.valueOf(chart.getGrouping().getVal()); } - public void setGrouping(Grouping grouping) { - if (chart.getGrouping() != null) { - chart.getGrouping().setVal(grouping.underlying); - } else { - chart.addNewGrouping().setVal(grouping.underlying); - } - } - - public Integer getGapDepth() { - return (chart.isSetGapDepth()) ? POIXMLUnits.parsePercent(chart.getGapDepth().xgetVal()) / 1000 : null; - } - - public void setGapDepth(Integer depth) { - if (depth == null) { - if (chart.isSetGapDepth()) { - chart.unsetGapDepth(); - } - } else { - if (chart.isSetGapDepth()) { - chart.getGapDepth().setVal(depth); - } else { - chart.addNewGapDepth().setVal(depth); - } - } - } + public void setGrouping(Grouping grouping) { + if (chart.getGrouping() != null) { + chart.getGrouping().setVal(grouping.underlying); + } else { + chart.addNewGrouping().setVal(grouping.underlying); + } + } + + public Integer getGapDepth() { + return (chart.isSetGapDepth()) ? POIXMLUnits.parsePercent(chart.getGapDepth().xgetVal()) / 1000 : null; + } + + public void setGapDepth(Integer depth) { + if (depth == null) { + if (chart.isSetGapDepth()) { + chart.unsetGapDepth(); + } + } else { + if (chart.isSetGapDepth()) { + chart.getGapDepth().setVal(depth); + } else { + chart.addNewGapDepth().setVal(depth); + } + } + } @Override public XDDFChartData.Series addSeries(XDDFDataSource category, @@ -141,6 +141,13 @@ public class XDDFLine3DChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTLineSer getCTLineSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFLineChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFLineChartData.java index 0a94cf96e9..5e9e51d757 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFLineChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFLineChartData.java @@ -23,13 +23,7 @@ import java.util.Map; import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; import org.apache.poi.xddf.usermodel.XDDFShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTMarker; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; @Beta public class XDDFLineChartData extends XDDFChartData { @@ -122,6 +116,13 @@ public class XDDFLineChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTLineSer getCTLineSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFPie3DChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFPie3DChartData.java index d2a5059847..95670cf63d 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFPie3DChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFPie3DChartData.java @@ -22,12 +22,7 @@ import java.util.List; import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; import org.apache.poi.xddf.usermodel.XDDFShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPie3DChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; @Beta public class XDDFPie3DChartData extends XDDFChartData { @@ -91,6 +86,13 @@ public class XDDFPie3DChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTPieSer getCTPieSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFPieChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFPieChartData.java index 6a3a28c576..3d69e0f163 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFPieChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFPieChartData.java @@ -116,6 +116,13 @@ public class XDDFPieChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTPieSer getCTPieSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFRadarChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFRadarChartData.java index f7f2edac6d..4693773c27 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFRadarChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFRadarChartData.java @@ -23,13 +23,7 @@ import java.util.Map; import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; import org.apache.poi.xddf.usermodel.XDDFShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTRadarChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTRadarSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTRadarStyle; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; @Beta public class XDDFRadarChartData extends XDDFChartData { @@ -122,6 +116,13 @@ public class XDDFRadarChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTRadarSer getCTRadarSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFScatterChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFScatterChartData.java index ba9864bf00..1bf6ead501 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFScatterChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFScatterChartData.java @@ -23,14 +23,7 @@ import java.util.Map; import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; import org.apache.poi.xddf.usermodel.XDDFShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTMarker; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterStyle; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; @Beta public class XDDFScatterChartData extends XDDFChartData { @@ -128,6 +121,13 @@ public class XDDFScatterChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTScatterSer getCTScatterSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFSurface3DChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFSurface3DChartData.java index b61764f168..41c9700797 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFSurface3DChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFSurface3DChartData.java @@ -23,12 +23,7 @@ import java.util.Map; import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; import org.apache.poi.xddf.usermodel.XDDFShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSurface3DChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSurfaceSer; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; @Beta public class XDDFSurface3DChartData extends XDDFChartData { @@ -128,6 +123,13 @@ public class XDDFSurface3DChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTSurfaceSer getCTSurfaceSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFSurfaceChartData.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFSurfaceChartData.java index 0547a19362..8e5e755882 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFSurfaceChartData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/chart/XDDFSurfaceChartData.java @@ -128,6 +128,13 @@ public class XDDFSurfaceChartData extends XDDFChartData { this.series = series; } + /** + * @since POI 5.2.3 + */ + public CTSurfaceSer getCTSurfaceSer() { + return series; + } + @Override protected CTSerTx getSeriesText() { if (series.isSetTx()) { diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/charts/TestXSSFBubbleChartData.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/charts/TestXSSFBubbleChartData.java new file mode 100644 index 0000000000..34a2baba1a --- /dev/null +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/charts/TestXSSFBubbleChartData.java @@ -0,0 +1,231 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ==================================================================== */ + +package org.apache.poi.xssf.usermodel.charts; + +import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.DataFormat; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellReference; +import org.apache.poi.xddf.usermodel.PresetColor; +import org.apache.poi.xddf.usermodel.XDDFColor; +import org.apache.poi.xddf.usermodel.XDDFShapeProperties; +import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties; +import org.apache.poi.xddf.usermodel.chart.*; +import org.apache.poi.xssf.usermodel.*; +import org.junit.jupiter.api.Test; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; + +import java.io.IOException; +import java.util.GregorianCalendar; + +/** + * Tests for XSSFBubbleChartData. + */ +public final class TestXSSFBubbleChartData { + + @Test + void testExample() throws IOException { + Object[][] chartData = new Object[][]{ + new Object[]{"", "Category 1"}, + new Object[]{"Bubble Size", "Bubble Date"}, + new Object[]{1000, new GregorianCalendar(2020, 0, 1)}, + new Object[]{10, new GregorianCalendar(2020, 0, 1)}, + new Object[]{300, new GregorianCalendar(2021, 0, 1)}, + new Object[]{"", ""}, + new Object[]{"", "Category 2"}, + new Object[]{"Bubble Size", "Bubble Date"}, + new Object[]{100, new GregorianCalendar(2018, 0, 1)}, + new Object[]{100, new GregorianCalendar(2020, 0, 1)} + }; + + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFSheet sheet = wb.createSheet("bubblechart"); + DataFormat format = wb.createDataFormat(); + XSSFCellStyle dateStyle = wb.createCellStyle(); + dateStyle.setDataFormat(14); + + // put sheet data + Row row; + Cell cell; + int rowIndex = 0; + int colIndex = 0; + for (Object[] dataRow : chartData) { + row = sheet.createRow((short) rowIndex); + colIndex = 0; + for (Object value : dataRow) { + cell = row.createCell((short) colIndex); + if (value instanceof String) cell.setCellValue((String)value); + if (value instanceof Number) cell.setCellValue(((Number)value).doubleValue()); + if (value instanceof GregorianCalendar) { + cell.setCellValue((GregorianCalendar)value); + cell.setCellStyle(dateStyle); + } + colIndex++; + } + rowIndex++; + } + + sheet.autoSizeColumn(0); + sheet.autoSizeColumn(1); + + // create the chart + + // chart data sources + XDDFDataSource xs1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 4, 1, 1)); + XDDFNumericalDataSource ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 4, 0, 0)); + XDDFNumericalDataSource bSz1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 4, 0, 0)); + + XDDFDataSource xs2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(8, 9, 1, 1)); + XDDFNumericalDataSource ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(8, 9, 0, 0)); + XDDFNumericalDataSource bSz2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(8, 9, 0, 0)); + + // chart in drawing + XSSFDrawing drawing = sheet.createDrawingPatriarch(); + XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 3, 0, 15, 20); + XSSFChart chart = drawing.createChart(anchor); + chart.setTitleText("Chart Title"); + chart.setTitleOverlay(false); + chart.getFormattedTitle().getParagraph(0).addDefaultRunProperties().setFontSize(20d); + + // value axis x + XDDFValueAxis valAxisX = chart.createValueAxis(AxisPosition.BOTTOM); + valAxisX.setTitle("Axis Title"); + + // value axis y + XDDFValueAxis valAxisY = chart.createValueAxis(AxisPosition.LEFT); + valAxisY.setTitle("Axis Title"); + + // cross axes + valAxisY.setCrosses(AxisCrosses.AUTO_ZERO); + + // chart data + //XDDFChartData data = chart.createData(ChartTypes.???, valAxisX, valAxisY); + XDDFBubbleChartData data = new XDDFBubbleChartData(chart, chart.getCTChart().getPlotArea().addNewBubbleChart(), valAxisX, valAxisY); + + // series + XDDFBubbleChartData.Series series1 = (XDDFBubbleChartData.Series)data.addSeries(xs1, ys1); + series1.setTitle("Category 1", new CellReference(sheet.getSheetName(), 0, 1, true, true)); + // set bubble sizes + series1.setBubbleSizes(bSz1); + // add data labels + // pos 8 = INT_R , showVal = true, showLegendKey= false, showCatName = true + CTDLbls ctDLbls = setDataLabels(series1, 8, true, false, true); + + XDDFBubbleChartData.Series series2 = (XDDFBubbleChartData.Series)data.addSeries(xs2, ys2); + series2.setTitle("Category 2", new CellReference(sheet.getSheetName(), 6, 1, true, true)); + // set bubble sizes + series2.setBubbleSizes(bSz2); + // add data labels + // pos 8 = INT_R , showVal = true, showLegendKey= false, showCatName = true + ctDLbls = setDataLabels(series2, 8, true, false, true); + + // plot chart + chart.plot(data); + + // legend + XDDFChartLegend legend = chart.getOrAddLegend(); + legend.setPosition(LegendPosition.RIGHT); + + // set series fill color + solidFillSeries(data, 0, PresetColor.BLUE); + solidFillSeries(data, 1, PresetColor.RED); + + // set rounded corners false + setRoundedCorners(chart, false); + + // Write the output to a file + try (UnsynchronizedByteArrayOutputStream outStream = new UnsynchronizedByteArrayOutputStream()) { + wb.write(outStream); + try (XSSFWorkbook wb2 = new XSSFWorkbook(outStream.toInputStream())) { + // see if this fails + } + } + } + } + + private static void solidFillSeries(XDDFChartData data, int index, PresetColor color) { + XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color)); + XDDFChartData.Series series = data.getSeries(index); + XDDFShapeProperties properties = series.getShapeProperties(); + if (properties == null) { + properties = new XDDFShapeProperties(); + } + properties.setFillProperties(fill); + series.setShapeProperties(properties); + } + + private static CTDLbls setDataLabels(XDDFChartData.Series series, int pos, boolean... show) { + /* + INT_BEST_FIT 1 + INT_B 2 + INT_CTR 3 + INT_IN_BASE 4 + INT_IN_END 5 + INT_L 6 + INT_OUT_END 7 + INT_R 8 + INT_T 9 + */ + CTDLbls ctDLbls = null; + if (series instanceof XDDFBarChartData.Series) { + CTBarSer ctBarSer = ((XDDFBarChartData.Series)series).getCTBarSer(); + if (ctBarSer.isSetDLbls()) ctBarSer.unsetDLbls(); + ctDLbls = ctBarSer.addNewDLbls(); + if (!(pos == 3 || pos == 4 || pos == 5 || pos == 7)) pos = 3; // bar chart does not provide other pos + ctDLbls.addNewDLblPos().setVal(STDLblPos.Enum.forInt(pos)); + } else if (series instanceof XDDFLineChartData.Series) { + CTLineSer ctLineSer = ((XDDFLineChartData.Series)series).getCTLineSer(); + if (ctLineSer.isSetDLbls()) ctLineSer.unsetDLbls(); + ctDLbls = ctLineSer.addNewDLbls(); + if (!(pos == 3 || pos == 6 || pos == 8 || pos == 9 || pos == 2)) pos = 3; // line chart does not provide other pos + ctDLbls.addNewDLblPos().setVal(STDLblPos.Enum.forInt(pos)); + } else if (series instanceof XDDFPieChartData.Series) { + CTPieSer ctPieSer = ((XDDFPieChartData.Series)series).getCTPieSer(); + if (ctPieSer.isSetDLbls()) ctPieSer.unsetDLbls(); + ctDLbls = ctPieSer.addNewDLbls(); + if (!(pos == 3 || pos == 1 || pos == 4 || pos == 5)) pos = 3; // pie chart does not provide other pos + ctDLbls.addNewDLblPos().setVal(STDLblPos.Enum.forInt(pos)); + } else if (series instanceof XDDFBubbleChartData.Series) { + CTBubbleSer ctBubbleSer = ((XDDFBubbleChartData.Series)series).getCTBubbleSer(); + if (ctBubbleSer.isSetDLbls()) ctBubbleSer.unsetDLbls(); + ctDLbls = ctBubbleSer.addNewDLbls(); + if (!(pos == 3 || pos == 2 || pos == 6 || pos == 8 || pos == 9)) pos = 3; // bubble chart does not provide other pos + ctDLbls.addNewDLblPos().setVal(STDLblPos.Enum.forInt(pos)); + }// else if ... + + if (ctDLbls != null) { + ctDLbls.addNewShowVal().setVal((show.length>0)?show[0]:false); + ctDLbls.addNewShowLegendKey().setVal((show.length>1)?show[1]:false); + ctDLbls.addNewShowCatName().setVal((show.length>2)?show[2]:false); + ctDLbls.addNewShowSerName().setVal((show.length>3)?show[3]:false); + ctDLbls.addNewShowPercent().setVal((show.length>4)?show[4]:false); + ctDLbls.addNewShowBubbleSize().setVal((show.length>5)?show[5]:false); + ctDLbls.addNewShowLeaderLines().setVal((show.length>6)?show[8]:false); + + return ctDLbls; + } + return null; + } + + private static void setRoundedCorners(XDDFChart chart, boolean setVal) { + if (chart.getCTChartSpace().getRoundedCorners() == null) chart.getCTChartSpace().addNewRoundedCorners(); + chart.getCTChartSpace().getRoundedCorners().setVal(setVal); + } +}