this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTAreaSer getCTAreaSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
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 {
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTAreaSer getCTAreaSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
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 {
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTBarSer getCTBarSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
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 {
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTBarSer getCTBarSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
--- /dev/null
+/* ====================================================================
+ 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<Long, XDDFChartAxis> categories = null;
+ Map<Long, XDDFValueAxis> 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<Long, XDDFChartAxis> categories,
+ Map<Long, XDDFValueAxis> 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<Long, XDDFChartAxis> categories, Map<Long, XDDFValueAxis> 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<? extends Number> 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<CTDPt> getDPtList() {
+ return series.getDPtList();
+ }
+ }
+}
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;
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 {
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTPieSer getCTPieSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
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,
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTLineSer getCTLineSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
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 {
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTLineSer getCTLineSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
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 {
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTPieSer getCTPieSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTPieSer getCTPieSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
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 {
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTRadarSer getCTRadarSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
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 {
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTScatterSer getCTScatterSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
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 {
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTSurfaceSer getCTSurfaceSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
this.series = series;
}
+ /**
+ * @since POI 5.2.3
+ */
+ public CTSurfaceSer getCTSurfaceSer() {
+ return series;
+ }
+
@Override
protected CTSerTx getSeriesText() {
if (series.isSetTx()) {
--- /dev/null
+/* ====================================================================
+ 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<Double> xs1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 4, 1, 1));
+ XDDFNumericalDataSource<Double> ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 4, 0, 0));
+ XDDFNumericalDataSource<Double> bSz1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 4, 0, 0));
+
+ XDDFDataSource<Double> xs2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(8, 9, 1, 1));
+ XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(8, 9, 0, 0));
+ XDDFNumericalDataSource<Double> 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);
+ }
+}