}.
+ *
+ * Here is the schema (ECMA-376):
+ *
+ * {@code
+ *
+ *
+ *
+ *
+ *
+ *
+ * }
+ *
+ */
+ private void appendChartElement(CTGraphicalObjectData data, String id) {
+ String r_namespaceUri = STRelationshipId.type.getName().getNamespaceURI();
+ String c_namespaceUri = XSSFDrawing.NAMESPACE_C;
+ XmlCursor cursor = data.newCursor();
+ cursor.toNextToken();
+ cursor.beginElement(new QName(c_namespaceUri, "chart", "c"));
+ cursor.insertAttributeWithValue(new QName(r_namespaceUri, "id", "r"), id);
+ cursor.dispose();
+ data.setUri(c_namespaceUri);
+ }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java
index f0b9a9b..21094c4 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java
@@ -90,12 +90,12 @@ public final class XSSFRelation extends POIXMLRelation {
"/xl/worksheets/sheet#.xml",
XSSFSheet.class
);
- public static final XSSFRelation CHARTSHEET = new XSSFRelation(
- "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml",
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet",
- "/xl/chartsheets/sheet#.xml",
- XSSFChartSheet.class
- );
+ public static final XSSFRelation CHARTSHEET = new XSSFRelation(
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet",
+ "/xl/chartsheets/sheet#.xml",
+ XSSFChartSheet.class
+ );
public static final XSSFRelation SHARED_STRINGS = new XSSFRelation(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartAxis.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartAxis.java
new file mode 100644
index 0000000..95467c6
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartAxis.java
@@ -0,0 +1,223 @@
+/* ====================================================================
+ 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.poi.ss.usermodel.charts.ChartAxis;
+import org.apache.poi.ss.usermodel.charts.AxisPosition;
+import org.apache.poi.ss.usermodel.charts.AxisOrientation;
+import org.apache.poi.ss.usermodel.charts.AxisCrosses;
+import org.apache.poi.xssf.usermodel.XSSFChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumFmt;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTCrosses;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTOrientation;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTLogBase;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTScaling;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STOrientation;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STAxPos;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STCrosses;
+
+/**
+ * Base class for all axis types.
+ *
+ * @author Roman Kashitsyn
+ */
+public abstract class XSSFChartAxis implements ChartAxis {
+
+ protected XSSFChart chart;
+
+ private static final double MIN_LOG_BASE = 2.0;
+ private static final double MAX_LOG_BASE = 1000.0;
+
+ protected XSSFChartAxis(XSSFChart chart) {
+ this.chart = chart;
+ }
+
+ public AxisPosition getPosition() {
+ return toAxisPosition(getCTAxPos());
+ }
+
+ public void setPosition(AxisPosition position) {
+ getCTAxPos().setVal(fromAxisPosition(position));
+ }
+
+ public void setNumberFormat(String format) {
+ getCTNumFmt().setFormatCode(format);
+ getCTNumFmt().setSourceLinked(true);
+ }
+
+ public String getNumberFormat() {
+ return getCTNumFmt().getFormatCode();
+ }
+
+ public boolean isSetLogBase() {
+ return getCTScaling().isSetLogBase();
+ }
+
+ public void setLogBase(double logBase) {
+ if (logBase < MIN_LOG_BASE ||
+ MAX_LOG_BASE < logBase) {
+ throw new IllegalArgumentException("Axis log base must be between 2 and 1000 (inclusive), got: " + logBase);
+ }
+ CTScaling scaling = getCTScaling();
+ if (scaling.isSetLogBase()) {
+ scaling.getLogBase().setVal(logBase);
+ } else {
+ scaling.addNewLogBase().setVal(logBase);
+ }
+ }
+
+ public double getLogBase() {
+ CTLogBase logBase = getCTScaling().getLogBase();
+ if (logBase != null) {
+ return logBase.getVal();
+ }
+ return 0.0;
+ }
+
+ public boolean isSetMinimum() {
+ return getCTScaling().isSetMin();
+ }
+
+ public void setMinimum(double min) {
+ CTScaling scaling = getCTScaling();
+ if (scaling.isSetMin()) {
+ scaling.getMin().setVal(min);
+ } else {
+ scaling.addNewMin().setVal(min);
+ }
+ }
+
+ public double getMinimum() {
+ CTScaling scaling = getCTScaling();
+ if (scaling.isSetMin()) {
+ return scaling.getMin().getVal();
+ } else {
+ return 0.0;
+ }
+ }
+
+ public boolean isSetMaximum() {
+ return getCTScaling().isSetMax();
+ }
+
+ public void setMaximum(double max) {
+ CTScaling scaling = getCTScaling();
+ if (scaling.isSetMax()) {
+ scaling.getMax().setVal(max);
+ } else {
+ scaling.addNewMax().setVal(max);
+ }
+ }
+
+ public double getMaximum() {
+ CTScaling scaling = getCTScaling();
+ if (scaling.isSetMax()) {
+ return scaling.getMax().getVal();
+ } else {
+ return 0.0;
+ }
+ }
+
+ public AxisOrientation getOrientation() {
+ return toAxisOrientation(getCTScaling().getOrientation());
+ }
+
+ public void setOrientation(AxisOrientation orientation) {
+ CTScaling scaling = getCTScaling();
+ STOrientation.Enum stOrientation = fromAxisOrientation(orientation);
+ if (scaling.isSetOrientation()) {
+ scaling.getOrientation().setVal(stOrientation);
+ } else {
+ getCTScaling().addNewOrientation().setVal(stOrientation);
+ }
+ }
+
+ public AxisCrosses getCrosses() {
+ return toAxisCrosses(getCTCrosses());
+ }
+
+ public void setCrosses(AxisCrosses crosses) {
+ getCTCrosses().setVal(fromAxisCrosses(crosses));
+ }
+
+ protected abstract CTAxPos getCTAxPos();
+ protected abstract CTNumFmt getCTNumFmt();
+ protected abstract CTScaling getCTScaling();
+ protected abstract CTCrosses getCTCrosses();
+
+ private static STOrientation.Enum fromAxisOrientation(AxisOrientation orientation) {
+ switch (orientation) {
+ case MIN_MAX: return STOrientation.MIN_MAX;
+ case MAX_MIN: return STOrientation.MAX_MIN;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private static AxisOrientation toAxisOrientation(CTOrientation ctOrientation) {
+ switch (ctOrientation.getVal().intValue()) {
+ case STOrientation.INT_MIN_MAX: return AxisOrientation.MIN_MAX;
+ case STOrientation.INT_MAX_MIN: return AxisOrientation.MAX_MIN;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private static STCrosses.Enum fromAxisCrosses(AxisCrosses crosses) {
+ switch (crosses) {
+ case AUTO_ZERO: return STCrosses.AUTO_ZERO;
+ case MIN: return STCrosses.MIN;
+ case MAX: return STCrosses.MAX;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private static AxisCrosses toAxisCrosses(CTCrosses ctCrosses) {
+ switch (ctCrosses.getVal().intValue()) {
+ case STCrosses.INT_AUTO_ZERO: return AxisCrosses.AUTO_ZERO;
+ case STCrosses.INT_MAX: return AxisCrosses.MAX;
+ case STCrosses.INT_MIN: return AxisCrosses.MIN;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private static STAxPos.Enum fromAxisPosition(AxisPosition position) {
+ switch (position) {
+ case BOTTOM: return STAxPos.B;
+ case LEFT: return STAxPos.L;
+ case RIGHT: return STAxPos.R;
+ case TOP: return STAxPos.T;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private static AxisPosition toAxisPosition(CTAxPos ctAxPos) {
+ switch (ctAxPos.getVal().intValue()) {
+ case STAxPos.INT_B: return AxisPosition.BOTTOM;
+ case STAxPos.INT_L: return AxisPosition.LEFT;
+ case STAxPos.INT_R: return AxisPosition.RIGHT;
+ case STAxPos.INT_T: return AxisPosition.TOP;
+ default: return AxisPosition.BOTTOM;
+ }
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartDataFactory.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartDataFactory.java
new file mode 100644
index 0000000..b36f917
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartDataFactory.java
@@ -0,0 +1,50 @@
+/* ====================================================================
+ 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.poi.ss.usermodel.charts.*;
+
+/**
+ * @author Roman Kashitsyn
+ */
+public class XSSFChartDataFactory implements ChartDataFactory {
+
+ private static XSSFChartDataFactory instance;
+
+ private XSSFChartDataFactory() {
+ super();
+ }
+
+ /**
+ * @return new scatter chart data instance
+ */
+ public XSSFScatterChartData createScatterChartData() {
+ return new XSSFScatterChartData();
+ }
+
+ /**
+ * @return factory instance
+ */
+ public static XSSFChartDataFactory getInstance() {
+ if (instance == null) {
+ instance = new XSSFChartDataFactory();
+ }
+ return instance;
+ }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartLegend.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartLegend.java
new file mode 100644
index 0000000..de4b415
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartLegend.java
@@ -0,0 +1,101 @@
+/* ====================================================================
+ 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.poi.util.Internal;
+import org.apache.poi.ss.usermodel.charts.ChartLegend;
+import org.apache.poi.ss.usermodel.charts.LegendPosition;
+import org.apache.poi.xssf.usermodel.XSSFChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTLegend;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTLegendPos;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STLegendPos;
+
+/**
+ * Represents a SpreadsheetML chart legend
+ * @author Roman Kashitsyn
+ */
+public final class XSSFChartLegend implements ChartLegend {
+
+ /**
+ * Underlaying CTLagend bean
+ */
+ private CTLegend legend;
+
+ /**
+ * Create a new SpreadsheetML chart legend
+ */
+ public XSSFChartLegend(XSSFChart chart) {
+ CTChart ctChart = chart.getCTChart();
+ this.legend = (ctChart.isSetLegend()) ?
+ ctChart.getLegend() :
+ ctChart.addNewLegend();
+ }
+
+ /**
+ * Return the underlying CTLegend bean.
+ *
+ * @return the underlying CTLegend bean
+ */
+ @Internal
+ public CTLegend getCTLegend(){
+ return legend;
+ }
+
+ public void setPosition(LegendPosition position) {
+ if (!legend.isSetLegendPos()) {
+ legend.addNewLegendPos();
+ }
+ legend.getLegendPos().setVal(fromLegendPosition(position));
+ }
+
+ /*
+ * According to ECMA-376 default position is RIGHT.
+ */
+ public LegendPosition getPosition() {
+ if (legend.isSetLegendPos()) {
+ return toLegendPosition(legend.getLegendPos());
+ } else {
+ return LegendPosition.RIGHT;
+ }
+ }
+
+ private STLegendPos.Enum fromLegendPosition(LegendPosition position) {
+ switch (position) {
+ case BOTTOM: return STLegendPos.B;
+ case LEFT: return STLegendPos.L;
+ case RIGHT: return STLegendPos.R;
+ case TOP: return STLegendPos.T;
+ case TOP_RIGHT: return STLegendPos.TR;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private LegendPosition toLegendPosition(CTLegendPos ctLegendPos) {
+ switch (ctLegendPos.getVal().intValue()) {
+ case STLegendPos.INT_B: return LegendPosition.BOTTOM;
+ case STLegendPos.INT_L: return LegendPosition.LEFT;
+ case STLegendPos.INT_R: return LegendPosition.RIGHT;
+ case STLegendPos.INT_T: return LegendPosition.TOP;
+ case STLegendPos.INT_TR: return LegendPosition.TOP_RIGHT;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFScatterChartData.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFScatterChartData.java
new file mode 100644
index 0000000..d3f6b96
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFScatterChartData.java
@@ -0,0 +1,147 @@
+/* ====================================================================
+ 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 java.util.List;
+import java.util.ArrayList;
+
+import org.apache.poi.ss.usermodel.Chart;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.usermodel.charts.ScatterChartData;
+import org.apache.poi.ss.usermodel.charts.ScatterChartSerie;
+import org.apache.poi.ss.usermodel.charts.ChartDataFactory;
+import org.apache.poi.ss.usermodel.charts.ChartAxis;
+
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterStyle;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterSer;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumFmt;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STScatterStyle;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STCrosses;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STCrossBetween;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STOrientation;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STAxPos;
+
+import org.apache.poi.xssf.usermodel.XSSFChart;
+
+/**
+ * Represents DrawingML scatter chart.
+ *
+ * @author Roman Kashitsyn
+ */
+public class XSSFScatterChartData implements ScatterChartData {
+
+ /**
+ * List of all data series.
+ */
+ private List series;
+
+ public XSSFScatterChartData() {
+ series = new ArrayList();
+ }
+
+ public static class Serie implements ScatterChartSerie {
+ private int id;
+ private int order;
+ private boolean useCache;
+ private Sheet xSheet;
+ private Sheet ySheet;
+ private CellRangeAddress xAddress;
+ private CellRangeAddress yAddress;
+
+ public Serie(int id, int order) {
+ super();
+ this.id = id;
+ this.order = order;
+ this.useCache = false;
+ }
+
+ public void setXValues(Sheet sheet, CellRangeAddress address) {
+ this.xSheet = sheet;
+ this.xAddress = address;
+ }
+
+ public void setYValues(Sheet sheet, CellRangeAddress address) {
+ this.ySheet = sheet;
+ this.yAddress = address;
+ }
+
+ /**
+ * @param useCache if true, cached results will be added on plot
+ */
+ public void setUseCache(boolean useCache) {
+ this.useCache = useCache;
+ }
+
+ protected void addToChart(CTScatterChart ctScatterChart) {
+ CTScatterSer scatterSer = ctScatterChart.addNewSer();
+ scatterSer.addNewIdx().setVal(this.id);
+ scatterSer.addNewOrder().setVal(this.order);
+
+ CTAxDataSource xVal = scatterSer.addNewXVal();
+ CTNumRef numRef = xVal.addNewNumRef();
+ numRef.setF(xAddress.formatAsString(xSheet.getSheetName(), true));
+
+ CTNumDataSource yVal = scatterSer.addNewYVal();
+ numRef = yVal.addNewNumRef();
+ numRef.setF(yAddress.formatAsString(ySheet.getSheetName(), true));
+ }
+ }
+
+ public XSSFScatterChartData.Serie addSerie() {
+ int numOfSeries = series.size();
+ Serie newSerie = new Serie(numOfSeries, numOfSeries);
+ series.add(newSerie);
+ return newSerie;
+ }
+
+ public void fillChart(Chart chart, ChartAxis... axis) {
+ if (!(chart instanceof XSSFChart)) {
+ throw new IllegalArgumentException("Chart must be instance of XSSFChart");
+ }
+
+ XSSFChart xssfChart = (XSSFChart) chart;
+ CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea();
+ CTScatterChart scatterChart = plotArea.addNewScatterChart();
+ addStyle(scatterChart);
+
+ for (Serie s : series) {
+ s.addToChart(scatterChart);
+ }
+
+ for (ChartAxis ax : axis) {
+ scatterChart.addNewAxId().setVal(ax.getId());
+ }
+ }
+
+ public List extends Serie> getSeries() {
+ return series;
+ }
+
+ private void addStyle(CTScatterChart ctScatterChart) {
+ CTScatterStyle scatterStyle = ctScatterChart.addNewScatterStyle();
+ scatterStyle.setVal(STScatterStyle.LINE_MARKER);
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFValueAxis.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFValueAxis.java
new file mode 100644
index 0000000..4ed5df2
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFValueAxis.java
@@ -0,0 +1,123 @@
+/* ====================================================================
+ 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.poi.ss.usermodel.charts.ChartAxis;
+import org.apache.poi.ss.usermodel.charts.ValueAxis;
+import org.apache.poi.ss.usermodel.charts.AxisPosition;
+import org.apache.poi.ss.usermodel.charts.AxisOrientation;
+import org.apache.poi.ss.usermodel.charts.AxisCrossBetween;
+import org.apache.poi.ss.usermodel.charts.AxisCrosses;
+
+import org.apache.poi.xssf.usermodel.XSSFChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumFmt;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTCrosses;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTScaling;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STAxPos;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STCrossBetween;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos;
+
+/**
+ * Value axis type.
+ *
+ * @author Roman Kashitsyn
+ */
+public class XSSFValueAxis extends XSSFChartAxis implements ValueAxis {
+
+ private CTValAx ctValAx;
+
+ public XSSFValueAxis(XSSFChart chart, long id, AxisPosition pos) {
+ super(chart);
+ createAxis(id, pos);
+ }
+
+ public long getId() {
+ return ctValAx.getAxId().getVal();
+ }
+
+ public void setCrossBetween(AxisCrossBetween crossBetween) {
+ ctValAx.getCrossBetween().setVal(fromCrossBetween(crossBetween));
+ }
+
+ public AxisCrossBetween getCrossBetween() {
+ return toCrossBetween(ctValAx.getCrossBetween().getVal());
+ }
+
+ @Override
+ protected CTAxPos getCTAxPos() {
+ return ctValAx.getAxPos();
+ }
+
+ @Override
+ protected CTNumFmt getCTNumFmt() {
+ if (ctValAx.isSetNumFmt()) {
+ return ctValAx.getNumFmt();
+ }
+ return ctValAx.addNewNumFmt();
+ }
+
+ @Override
+ protected CTScaling getCTScaling() {
+ return ctValAx.getScaling();
+ }
+
+ @Override
+ protected CTCrosses getCTCrosses() {
+ return ctValAx.getCrosses();
+ }
+
+ public void crossAxis(ChartAxis axis) {
+ ctValAx.getCrossAx().setVal(axis.getId());
+ }
+
+ private void createAxis(long id, AxisPosition pos) {
+ ctValAx = chart.getCTChart().getPlotArea().addNewValAx();
+ ctValAx.addNewAxId().setVal(id);
+ ctValAx.addNewAxPos();
+ ctValAx.addNewScaling();
+ ctValAx.addNewCrossBetween();
+ ctValAx.addNewCrosses();
+ ctValAx.addNewCrossAx();
+ ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
+
+ setPosition(pos);
+ setOrientation(AxisOrientation.MIN_MAX);
+ setCrossBetween(AxisCrossBetween.MIDPOINT_CATEGORY);
+ setCrosses(AxisCrosses.AUTO_ZERO);
+ }
+
+ private static STCrossBetween.Enum fromCrossBetween(AxisCrossBetween crossBetween) {
+ switch (crossBetween) {
+ case BETWEEN: return STCrossBetween.BETWEEN;
+ case MIDPOINT_CATEGORY: return STCrossBetween.MID_CAT;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private static AxisCrossBetween toCrossBetween(STCrossBetween.Enum ctCrossBetween) {
+ switch (ctCrossBetween.intValue()) {
+ case STCrossBetween.INT_BETWEEN: return AxisCrossBetween.BETWEEN;
+ case STCrossBetween.INT_MID_CAT: return AxisCrossBetween.MIDPOINT_CATEGORY;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChart.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChart.java
index 3ddd636..00b0e36 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChart.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChart.java
@@ -55,4 +55,20 @@ public final class TestXSSFChart extends TestCase {
chart = s3.createDrawingPatriarch().getCharts().get(0);
assertEquals("Sheet 3 Chart with Title", chart.getTitle().getString());
}
+
+ public void testAddChartsToNewWorkbook() throws Exception {
+ XSSFWorkbook wb = new XSSFWorkbook();
+ XSSFSheet s1 = wb.createSheet();
+ XSSFDrawing d1 = s1.createDrawingPatriarch();
+ XSSFClientAnchor a1 = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30);
+ XSSFChart c1 = d1.createChart(a1);
+
+ assertEquals(1, d1.getCharts().size());
+ assertNotNull(c1.getGraphicFrame());
+ assertNotNull(c1.getOrCreateLegend());
+
+ XSSFClientAnchor a2 = new XSSFClientAnchor(0, 0, 0, 0, 1, 11, 10, 60);
+ XSSFChart c2 = d1.createChart(a2);
+ assertEquals(2, d1.getCharts().size());
+ }
}
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartAxis.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartAxis.java
new file mode 100644
index 0000000..305be51
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartAxis.java
@@ -0,0 +1,80 @@
+/* ====================================================================
+ 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 junit.framework.TestCase;
+
+import org.apache.poi.ss.usermodel.charts.*;
+import org.apache.poi.xssf.usermodel.*;
+import org.apache.poi.xssf.usermodel.charts.*;
+
+public final class TestXSSFChartAxis extends TestCase {
+
+ private static final double EPSILON = 1E-7;
+ private XSSFChartAxis axis;
+
+ public TestXSSFChartAxis() {
+ super();
+ XSSFWorkbook wb = new XSSFWorkbook();
+ XSSFSheet sheet = wb.createSheet();
+ XSSFDrawing drawing = sheet.createDrawingPatriarch();
+ XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30);
+ XSSFChart chart = drawing.createChart(anchor);
+ axis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
+ }
+
+ public void testLogBaseIllegalArgument() throws Exception {
+ IllegalArgumentException iae = null;
+ try {
+ axis.setLogBase(0.0);
+ } catch (IllegalArgumentException e) {
+ iae = e;
+ }
+ assertNotNull(iae);
+
+ iae = null;
+ try {
+ axis.setLogBase(30000.0);
+ } catch (IllegalArgumentException e) {
+ iae = e;
+ }
+ assertNotNull(iae);
+ }
+
+ public void testLogBaseLegalArgument() throws Exception {
+ axis.setLogBase(Math.E);
+ assertTrue(Math.abs(axis.getLogBase() - Math.E) < EPSILON);
+ }
+
+ public void testNumberFormat() throws Exception {
+ final String numberFormat = "General";
+ axis.setNumberFormat(numberFormat);
+ assertEquals(numberFormat, axis.getNumberFormat());
+ }
+
+ public void testMaxAndMinAccessMethods() {
+ final double newValue = 10.0;
+
+ axis.setMinimum(newValue);
+ assertTrue(Math.abs(axis.getMinimum() - newValue) < EPSILON);
+
+ axis.setMaximum(newValue);
+ assertTrue(Math.abs(axis.getMaximum() - newValue) < EPSILON);
+ }
+
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartLegend.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartLegend.java
new file mode 100644
index 0000000..3c7cf52
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartLegend.java
@@ -0,0 +1,40 @@
+/* ====================================================================
+ 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 junit.framework.TestCase;
+
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.usermodel.charts.ChartLegend;
+import org.apache.poi.ss.usermodel.charts.LegendPosition;
+import org.apache.poi.xssf.usermodel.*;
+
+public final class TestXSSFChartLegend extends TestCase {
+
+ public void testLegendPositionAccessMethods() throws Exception {
+ Workbook wb = new XSSFWorkbook();
+ Sheet sheet = wb.createSheet();
+ Drawing drawing = sheet.createDrawingPatriarch();
+ ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30);
+ Chart chart = drawing.createChart(anchor);
+ ChartLegend legend = chart.getOrCreateLegend();
+
+ legend.setPosition(LegendPosition.TOP_RIGHT);
+ assertEquals(LegendPosition.TOP_RIGHT, legend.getPosition());
+ }
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java
new file mode 100644
index 0000000..cd39a69
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java
@@ -0,0 +1,51 @@
+/* ====================================================================
+ 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 junit.framework.TestCase;
+
+import org.apache.poi.xssf.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.usermodel.charts.*;
+import org.apache.poi.xssf.usermodel.charts.XSSFChartDataFactory;
+
+public final class TestXSSFScatterChartData extends TestCase {
+
+ public void testOneSeriePlot() throws Exception {
+ XSSFWorkbook wb = new XSSFWorkbook();
+ XSSFSheet sheet = wb.createSheet();
+ XSSFDrawing drawing = sheet.createDrawingPatriarch();
+ XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30);
+ XSSFChart chart = drawing.createChart(anchor);
+
+ ChartAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
+ ChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
+
+ ScatterChartData scatterChartData =
+ XSSFChartDataFactory.getInstance().createScatterChartData();
+
+ ScatterChartSerie serie = scatterChartData.addSerie();
+ serie.setXValues(sheet, new CellRangeAddress(0,0,1,10));
+ serie.setYValues(sheet, new CellRangeAddress(1,1,1,10));
+
+ assertEquals(scatterChartData.getSeries().size(), 1);
+
+ chart.plot(scatterChartData, bottomAxis, leftAxis);
+ }
+
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFValueAxis.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFValueAxis.java
new file mode 100644
index 0000000..a6f3992
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFValueAxis.java
@@ -0,0 +1,44 @@
+/* ====================================================================
+ 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 junit.framework.TestCase;
+
+import org.apache.poi.ss.usermodel.charts.*;
+import org.apache.poi.xssf.usermodel.*;
+import org.apache.poi.xssf.usermodel.charts.*;
+
+public final class TestXSSFValueAxis extends TestCase {
+
+ public void testAccessMethods() throws Exception {
+ XSSFWorkbook wb = new XSSFWorkbook();
+ XSSFSheet sheet = wb.createSheet();
+ XSSFDrawing drawing = sheet.createDrawingPatriarch();
+ XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30);
+ XSSFChart chart = drawing.createChart(anchor);
+ XSSFValueAxis axis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
+
+ axis.setCrossBetween(AxisCrossBetween.MIDPOINT_CATEGORY);
+ assertEquals(axis.getCrossBetween(), AxisCrossBetween.MIDPOINT_CATEGORY);
+
+ axis.setCrosses(AxisCrosses.AUTO_ZERO);
+ assertEquals(axis.getCrosses(), AxisCrosses.AUTO_ZERO);
+
+ assertEquals(chart.getAxis().size(), 1);
+ }
+}