final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values1, valuesDataRange, 1);
values1[6] = 16.0; // if you ever want to change the underlying data
final XDDFNumericalDataSource<? extends Number> valuesData2 = XDDFDataSourcesFactory.fromArray(values2, valuesDataRange2, 2);
- bar.getSeries().get(0).replaceData(categoriesData, valuesData);
- bar.addSeries(categoriesData, valuesData2);
- bar.getSeries().get(0).setTitle(series[0], chart.setSheetTitle(series[0], 0));
- bar.getSeries().get(1).setTitle(series[1], chart.setSheetTitle(series[1], 1));
+
+ XDDFChartData.Series series1 = bar.getSeries().get(0);
+ series1.replaceData(categoriesData, valuesData);
+ series1.setTitle(series[0], chart.setSheetTitle(series[0], 0));
+ XDDFChartData.Series series2 = bar.addSeries(categoriesData, valuesData2);
+ series2.setTitle(series[1], chart.setSheetTitle(series[1], 1));
+
chart.plot(bar);
}
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
- data.addSeries(xs, ys1);
- data.addSeries(xs, ys2);
+ XDDFChartData.Series series1 = data.addSeries(xs, ys1);
+ series1.setTitle("2x", null); // https://stackoverflow.com/questions/21855842
+ XDDFChartData.Series series2 = data.addSeries(xs, ys2);
+ series2.setTitle("3x", null);
chart.plot(data);
// in order to transform a bar chart into a column chart, you just need to change the bar direction
private static void solidFillSeries(XDDFChartData data, int index, PresetColor color) {
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
- XDDFChartData.Series firstSeries = data.getSeries().get(index);
- XDDFShapeProperties properties = firstSeries.getShapeProperties();
+ XDDFChartData.Series series = data.getSeries().get(index);
+ XDDFShapeProperties properties = series.getShapeProperties();
if (properties == null) {
properties = new XDDFShapeProperties();
}
properties.setFillProperties(fill);
- firstSeries.setShapeProperties(properties);
+ series.setShapeProperties(properties);
}
}
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xddf.usermodel.PresetColor;
+import org.apache.poi.xddf.usermodel.XDDFColor;
+import org.apache.poi.xddf.usermodel.XDDFLineProperties;
+import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
+import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
+import org.apache.poi.xddf.usermodel.chart.MarkerStyle;
import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis;
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
+import org.apache.poi.xddf.usermodel.chart.XDDFLineChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
import org.apache.poi.xssf.usermodel.XSSFChart;
XDDFNumericalDataSource<Double> ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
- XDDFChartData data = chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
- data.addSeries(xs, ys1);
- data.addSeries(xs, ys2);
+ XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
+ XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(xs, ys1);
+ series1.setTitle("2x", null); // https://stackoverflow.com/questions/21855842
+ series1.setSmooth(false); // https://stackoverflow.com/questions/29014848
+ series1.setMarkerStyle(MarkerStyle.STAR); // https://stackoverflow.com/questions/39636138
+ XDDFLineChartData.Series series2 = (XDDFLineChartData.Series) data.addSeries(xs, ys2);
+ series2.setTitle("3x", null);
+ series2.setSmooth(true);
+ series2.setMarkerSize((short) 6);
+ series2.setMarkerStyle(MarkerStyle.TRIANGLE); // https://stackoverflow.com/questions/39636138
chart.plot(data);
+ // if your series have missing values like https://stackoverflow.com/questions/29014848
+ // chart.displayBlanksAs(DisplayBlanks.GAP);
+
+ // https://stackoverflow.com/questions/24676460
+ solidLineSeries(data, 0, PresetColor.CHARTREUSE);
+ solidLineSeries(data, 1, PresetColor.TURQUOISE);
+
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx")) {
wb.write(fileOut);
}
}
}
+
+ private static void solidLineSeries(XDDFChartData data, int index, PresetColor color) {
+ XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
+ XDDFLineProperties line = new XDDFLineProperties();
+ line.setFillProperties(fill);
+ XDDFChartData.Series series = data.getSeries().get(index);
+ XDDFShapeProperties properties = series.getShapeProperties();
+ if (properties == null) {
+ properties = new XDDFShapeProperties();
+ }
+ properties.setLineProperties(line);
+ series.setShapeProperties(properties);
+ }
}
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xddf.usermodel.PresetColor;
+import org.apache.poi.xddf.usermodel.XDDFColor;
+import org.apache.poi.xddf.usermodel.XDDFLineProperties;
+import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
+import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
+import org.apache.poi.xddf.usermodel.chart.XDDFScatterChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
import org.apache.poi.xssf.usermodel.XSSFChart;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
- XDDFChartData data = chart.createData(ChartTypes.SCATTER, bottomAxis, leftAxis);
-
- data.addSeries(xs, ys1);
- data.addSeries(xs, ys2);
+ XDDFScatterChartData data = (XDDFScatterChartData) chart.createData(ChartTypes.SCATTER, bottomAxis, leftAxis);
+ XDDFScatterChartData.Series series1 = (XDDFScatterChartData.Series) data.addSeries(xs, ys1);
+ series1.setTitle("2x", null); // https://stackoverflow.com/questions/21855842
+ series1.setSmooth(false); // https://stackoverflow.com/questions/39636138
+ XDDFScatterChartData.Series series2 = (XDDFScatterChartData.Series) data.addSeries(xs, ys2);
+ series2.setTitle("3x", null);
chart.plot(data);
+ solidLineSeries(data, 0, PresetColor.CHARTREUSE);
+ solidLineSeries(data, 1, PresetColor.TURQUOISE);
+
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx")) {
wb.write(fileOut);
}
}
}
+
+ private static void solidLineSeries(XDDFChartData data, int index, PresetColor color) {
+ XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
+ XDDFLineProperties line = new XDDFLineProperties();
+ line.setFillProperties(fill);
+ XDDFChartData.Series series = data.getSeries().get(index);
+ XDDFShapeProperties properties = series.getShapeProperties();
+ if (properties == null) {
+ properties = new XDDFShapeProperties();
+ }
+ properties.setLineProperties(line);
+ series.setShapeProperties(properties);
+ }
}
final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values1, valuesDataRange, 1);
values1[6] = 16.0; // if you ever want to change the underlying data
final XDDFNumericalDataSource<? extends Number> valuesData2 = XDDFDataSourcesFactory.fromArray(values2, valuesDataRange2, 2);
- bar.getSeries().get(0).replaceData(categoriesData, valuesData);
- bar.addSeries(categoriesData, valuesData2);
- bar.getSeries().get(0).setTitle(series[0], chart.setSheetTitle(series[0], 0));
- bar.getSeries().get(1).setTitle(series[1], chart.setSheetTitle(series[1], 1));
+
+ XDDFChartData.Series series1 = bar.getSeries().get(0);
+ series1.replaceData(categoriesData, valuesData);
+ series1.setTitle(series[0], chart.setSheetTitle(series[0], 0));
+ XDDFChartData.Series series2 = bar.addSeries(categoriesData, valuesData2);
+ series2.setTitle(series[1], chart.setSheetTitle(series[1], 1));
+
chart.plot(bar);
}
--- /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.HashMap;
+
+import org.openxmlformats.schemas.drawingml.x2006.chart.STDispBlanksAs;
+
+public enum DisplayBlanks {
+ GAP(STDispBlanksAs.GAP),
+ SPAN(STDispBlanksAs.SPAN),
+ ZERO(STDispBlanksAs.ZERO);
+
+ final STDispBlanksAs.Enum underlying;
+
+ DisplayBlanks(STDispBlanksAs.Enum mode) {
+ this.underlying = mode;
+ }
+
+ private final static HashMap<STDispBlanksAs.Enum, DisplayBlanks> reverse = new HashMap<>();
+ static {
+ for (DisplayBlanks value : values()) {
+ reverse.put(value.underlying, value);
+ }
+ }
+
+ static DisplayBlanks valueOf(STDispBlanksAs.Enum mode) {
+ return reverse.get(mode);
+ }
+}
@Override
protected CTSerTx getSeriesText() {
- return series.getTx();
+ if (series.isSetTx()) {
+ return series.getTx();
+ } else {
+ return series.addNewTx();
+ }
}
@Override
chart.getAutoTitleDeleted().setVal(deleted);
}
+ /**
+ * @since 4.0.1
+ *
+ */
+ public void displayBlanksAs(DisplayBlanks as) {
+ if (as == null){
+ if (chart.isSetDispBlanksAs()) {
+ chart.unsetDispBlanksAs();
+ }
+ } else {
+ if (chart.isSetDispBlanksAs()) {
+ chart.getDispBlanksAs().setVal(as.underlying);
+ } else {
+ chart.addNewDispBlanksAs().setVal(as.underlying);
+ }
+ }
+ }
+
/**
* @since 4.0.1
*/
@Override
protected CTSerTx getSeriesText() {
- return series.getTx();
+ if (series.isSetTx()) {
+ return series.getTx();
+ } else {
+ return series.addNewTx();
+ }
}
@Override
}
}
+ /**
+ * @since 4.0.1
+ */
+ public Boolean getSmooth() {
+ if (series.isSetSmooth()) {
+ return series.getSmooth().getVal();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param smooth
+ * whether or not to smooth lines, if <code>null</code> then reverts to default.
+ * @since 4.0.1
+ */
+ public void setSmooth(Boolean smooth) {
+ if (smooth == null) {
+ if (series.isSetSmooth()) {
+ series.unsetSmooth();
+ }
+ } else {
+ if (series.isSetSmooth()) {
+ series.getSmooth().setVal(smooth);
+ } else {
+ series.addNewSmooth().setVal(smooth);
+ }
+ }
+ }
+
+ /**
+ * @param size
+ * <dl><dt>Minimum inclusive:</dt><dd>2</dd><dt>Maximum inclusive:</dt><dd>72</dd></dl>
+ */
public void setMarkerSize(short size) {
+ if (size < 2 || 72 < size) {
+ throw new IllegalArgumentException("Minimum inclusive: 2; Maximum inclusive: 72");
+ }
CTMarker marker = getMarker();
if (marker.isSetSize()) {
marker.getSize().setVal(size);
@Override
protected CTSerTx getSeriesText() {
- return series.getTx();
+ if (series.isSetTx()) {
+ return series.getTx();
+ } else {
+ return series.addNewTx();
+ }
}
@Override
@Override
protected CTSerTx getSeriesText() {
- return series.getTx();
+ if (series.isSetTx()) {
+ return series.getTx();
+ } else {
+ return series.addNewTx();
+ }
}
@Override
import org.apache.poi.util.Beta;
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
+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;
@Override
protected CTSerTx getSeriesText() {
- return series.getTx();
+ if (series.isSetTx()) {
+ return series.getTx();
+ } else {
+ return series.addNewTx();
+ }
}
/**
}
/**
+ * @param smooth
+ * whether or not to smooth lines, if <code>null</code> then reverts to default.
* @since 4.0.1
*/
- public void setSmooth(boolean smooth) {
- if (series.isSetSmooth()) {
- series.getSmooth().setVal(smooth);
+ public void setSmooth(Boolean smooth) {
+ if (smooth == null) {
+ if (series.isSetSmooth()) {
+ series.unsetSmooth();
+ }
+ } else {
+ if (series.isSetSmooth()) {
+ series.getSmooth().setVal(smooth);
+ } else {
+ series.addNewSmooth().setVal(smooth);
+ }
+ }
+ }
+
+ /**
+ * @param size
+ * <dl><dt>Minimum inclusive:</dt><dd>2</dd><dt>Maximum inclusive:</dt><dd>72</dd></dl>
+ * @since 4.0.1
+ */
+ public void setMarkerSize(short size) {
+ if (size < 2 || 72 < size) {
+ throw new IllegalArgumentException("Minimum inclusive: 2; Maximum inclusive: 72");
+ }
+ CTMarker marker = getMarker();
+ if (marker.isSetSize()) {
+ marker.getSize().setVal(size);
+ } else {
+ marker.addNewSize().setVal(size);
+ }
+ }
+
+ /**
+ * @since 4.0.1
+ */
+ public void setMarkerStyle(MarkerStyle style) {
+ CTMarker marker = getMarker();
+ if (marker.isSetSymbol()) {
+ marker.getSymbol().setVal(style.underlying);
+ } else {
+ marker.addNewSymbol().setVal(style.underlying);
+ }
+ }
+
+ private CTMarker getMarker() {
+ if (series.isSetMarker()) {
+ return series.getMarker();
} else {
- series.addNewSmooth().setVal(smooth);
+ return series.addNewMarker();
}
}