diff options
18 files changed, 779 insertions, 77 deletions
diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java index 1747a77822..3df1d90acf 100644 --- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java @@ -64,13 +64,13 @@ public class ScatterChart { ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM); ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); - ScatterChartSerie firstSerie = data.addSerie(); - firstSerie.setXValues(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1)); - firstSerie.setYValues(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1)); + DataMarker xMarker = new DataMarker(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1)); + DataMarker y1Marker = new DataMarker(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1)); + DataMarker y2Marker = new DataMarker(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1)); - ScatterChartSerie secondSerie = data.addSerie(); - secondSerie.setXValues(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1)); - secondSerie.setYValues(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1)); + + data.addSerie(xMarker, y1Marker); + data.addSerie(xMarker, y2Marker); chart.plot(data, bottomAxis, leftAxis); diff --git a/src/java/org/apache/poi/ss/usermodel/Chart.java b/src/java/org/apache/poi/ss/usermodel/Chart.java index 8c4198ef76..b14d95d10f 100644 --- a/src/java/org/apache/poi/ss/usermodel/Chart.java +++ b/src/java/org/apache/poi/ss/usermodel/Chart.java @@ -22,6 +22,8 @@ import java.util.List; import org.apache.poi.ss.usermodel.charts.ChartData; import org.apache.poi.ss.usermodel.charts.ChartAxis; import org.apache.poi.ss.usermodel.charts.ChartLegend; +import org.apache.poi.ss.usermodel.charts.ManualLayout; +import org.apache.poi.ss.usermodel.charts.ManuallyPositionable; import org.apache.poi.ss.usermodel.charts.ChartDataFactory; import org.apache.poi.ss.usermodel.charts.ChartAxisFactory; @@ -30,7 +32,7 @@ import org.apache.poi.ss.usermodel.charts.ChartAxisFactory; * * @author Roman Kashitsyn */ -public interface Chart { +public interface Chart extends ManuallyPositionable { /** * @return an appropriate ChartDataFactory implementation diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java index 034f4500d2..6542f991bf 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java @@ -101,7 +101,7 @@ public interface ChartAxis { AxisOrientation getOrientation(); /** - * @param axis orientation + * @param orientation axis orientation */ void setOrientation(AxisOrientation orientation); diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java index 0975caf435..b870a773ec 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java @@ -22,7 +22,7 @@ package org.apache.poi.ss.usermodel.charts; * * @author Roman Kashitsyn */ -public interface ChartLegend { +public interface ChartLegend extends ManuallyPositionable { /** * @return legend position @@ -33,5 +33,4 @@ public interface ChartLegend { * @param position new legend position */ void setPosition(LegendPosition position); - } diff --git a/src/java/org/apache/poi/ss/usermodel/charts/LayoutMode.java b/src/java/org/apache/poi/ss/usermodel/charts/LayoutMode.java new file mode 100644 index 0000000000..87769701b0 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/LayoutMode.java @@ -0,0 +1,35 @@ +/* ====================================================================
+ 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.ss.usermodel.charts;
+
+/**
+ * Specifies the possible ways to store a chart element's position.
+ * @author Roman Kashitsyn
+ */
+public enum LayoutMode {
+ /**
+ * Specifies that the Width or Height shall be interpreted as the
+ * Right or Bottom of the chart element.
+ */
+ EDGE,
+ /**
+ * Specifies that the Width or Height shall be interpreted as the
+ * Width or Height of the chart element.
+ */
+ FACTOR
+}
diff --git a/src/java/org/apache/poi/ss/usermodel/charts/LayoutTarget.java b/src/java/org/apache/poi/ss/usermodel/charts/LayoutTarget.java new file mode 100644 index 0000000000..f95c5370fb --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/LayoutTarget.java @@ -0,0 +1,39 @@ +/* ====================================================================
+ 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.ss.usermodel.charts;
+
+/**
+ * Specifies whether to layout the plot area by its inside (not including axis
+ * and axis labels) or outside (including axis and axis labels).
+ *
+ * @author Roman Kashitsyn
+ */
+public enum LayoutTarget {
+ /**
+ * Specifies that the plot area size shall determine the
+ * size of the plot area, not including the tick marks and
+ * axis labels.
+ */
+ INNER,
+ /**
+ * Specifies that the plot area size shall determine the
+ * size of the plot area, the tick marks, and the axis
+ * labels.
+ */
+ OUTER
+}
diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ManualLayout.java b/src/java/org/apache/poi/ss/usermodel/charts/ManualLayout.java new file mode 100644 index 0000000000..993ab3dafd --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/ManualLayout.java @@ -0,0 +1,150 @@ +/* ====================================================================
+ 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.ss.usermodel.charts;
+
+/**
+ * High level representation of chart element manual layout.
+ *
+ * @author Roman Kashitsyn
+ */
+public interface ManualLayout {
+
+ /**
+ * Sets the layout target.
+ * @param target new layout target.
+ */
+ public void setTarget(LayoutTarget target);
+
+ /**
+ * Returns current layout target.
+ * @return current layout target
+ */
+ public LayoutTarget getTarget();
+
+ /**
+ * Sets the x-coordinate layout mode.
+ * @param mode new x-coordinate layout mode.
+ */
+ public void setXMode(LayoutMode mode);
+
+ /**
+ * Returns current x-coordinnate layout mode.
+ * @return current x-coordinate layout mode.
+ */
+ public LayoutMode getXMode();
+
+ /**
+ * Sets the y-coordinate layout mode.
+ * @param mode new y-coordinate layout mode.
+ */
+ public void setYMode(LayoutMode mode);
+
+ /**
+ * Returns current y-coordinate layout mode.
+ * @return current y-coordinate layout mode.
+ */
+ public LayoutMode getYMode();
+
+ /**
+ * Returns the x location of the chart element.
+ * @return the x location (left) of the chart element or 0.0 if
+ * not set.
+ */
+ public double getX();
+
+ /**
+ * Specifies the x location (left) of the chart element as a
+ * fraction of the width of the chart. If Left Mode is Factor,
+ * then the position is relative to the default position for the
+ * chart element.
+ */
+ public void setX(double x);
+
+
+ /**
+ * Returns current y location of the chart element.
+ * @return the y location (top) of the chart element or 0.0 if not
+ * set.
+ */
+ public double getY();
+
+ /**
+ * Specifies the y location (top) of the chart element as a
+ * fraction of the height of the chart. If Top Mode is Factor,
+ * then the position is relative to the default position for the
+ * chart element.
+ */
+ public void setY(double y);
+
+
+ /**
+ * Specifies how to interpret the Width element for this manual
+ * layout.
+ * @param mode new width layout mode of this manual layout.
+ */
+ public void setWidthMode(LayoutMode mode);
+
+
+ /**
+ * Returns current width mode of this manual layout.
+ * @return width mode of this manual layout.
+ */
+ public LayoutMode getWidthMode();
+
+ /**
+ * Specifies how to interpret the Height element for this manual
+ * layout.
+ * @param mode new height mode of this manual layout.
+ */
+ public void setHeightMode(LayoutMode mode);
+
+ /**
+ * Returns current height mode of this
+ * @return height mode of this manual layout.
+ */
+ public LayoutMode getHeightMode();
+
+ /**
+ * Specifies the width (if Width Mode is Factor) or right (if
+ * Width Mode is Edge) of the chart element as a fraction of the
+ * width of the chart.
+ * @param ratio a fraction of the width of the chart.
+ */
+ public void setWidthRatio(double ratio);
+
+ /**
+ * Returns current fraction of the width of the chart.
+ * @return fraction of the width of the chart or 0.0 if not set.
+ */
+ public double getWidthRatio();
+
+ /**
+ * Specifies the height (if Height Mode is Factor) or bottom (if
+ * Height Mode is edge) of the chart element as a fraction of the
+ * height of the chart.
+ * @param ratio a fraction of the height of the chart.
+ */
+ public void setHeightRatio(double ratio);
+
+ /**
+ * Returns current fraction of the height of the chart.
+ * @return fraction of the height of the chart or 0.0 if not set.
+ */
+ public double getHeightRatio();
+
+}
diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ManuallyPositionable.java b/src/java/org/apache/poi/ss/usermodel/charts/ManuallyPositionable.java new file mode 100644 index 0000000000..03a85a4bce --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/ManuallyPositionable.java @@ -0,0 +1,33 @@ +/* ====================================================================
+ 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.ss.usermodel.charts;
+
+/**
+ * Abstraction of chart element that can be positioned with manual
+ * layout.
+ *
+ * @author Roman Kashitsyn
+ */
+public interface ManuallyPositionable {
+
+ /**
+ * Returns manual layout for the chart element.
+ * @return manual layout for the chart element.
+ */
+ public ManualLayout getManualLayout();
+}
diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java index 7f828d7664..09e10048ef 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java @@ -18,15 +18,20 @@ package org.apache.poi.ss.usermodel.charts; import java.util.List; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.DataMarker; + /** * @author Roman Kashitsyn */ public interface ScatterChartData extends ChartData { /** + * @param xMarker data marker to be used for X value range + * @param yMarker data marker to be used for Y value range * @return a new scatter chart serie */ - ScatterChartSerie addSerie(); + ScatterChartSerie addSerie(DataMarker xMarker, DataMarker yMarker); /** * @return list of all series diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSerie.java b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSerie.java index 274113b2d8..16cef9c5fa 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSerie.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSerie.java @@ -18,7 +18,7 @@ package org.apache.poi.ss.usermodel.charts; import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.DataMarker; import org.apache.poi.ss.usermodel.charts.ChartDataFactory; /** @@ -27,15 +27,13 @@ import org.apache.poi.ss.usermodel.charts.ChartDataFactory; public interface ScatterChartSerie { /** - * @param sheet a sheet to take range from - * @param address a column or a row with values + * @param xMarker data marker to use for X values. */ - void setXValues(Sheet sheet, CellRangeAddress address); - + void setXValues(DataMarker xMarker); + /**' - * @param sheet a sheet to take range from - * @param address a column or a row with values + * @param yMarker data marker to use for Y values. */ - void setYValues(Sheet sheet, CellRangeAddress address); + void setYValues(DataMarker yMarker); } diff --git a/src/java/org/apache/poi/ss/util/DataMarker.java b/src/java/org/apache/poi/ss/util/DataMarker.java new file mode 100644 index 0000000000..628a975aaa --- /dev/null +++ b/src/java/org/apache/poi/ss/util/DataMarker.java @@ -0,0 +1,87 @@ +/*
+ * ====================================================================
+ * 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.ss.util;
+
+import org.apache.poi.ss.usermodel.Sheet;
+
+/**
+ * Represents data marker used in charts.
+ * @author Roman Kashitsyn
+ */
+public class DataMarker {
+
+ private Sheet sheet;
+ private CellRangeAddress range;
+
+ /**
+ * @param sheet the sheet where data located.
+ * @param range the range within that sheet.
+ */
+ public DataMarker(Sheet sheet, CellRangeAddress range) {
+ this.sheet = sheet;
+ this.range = range;
+ }
+
+ /**
+ * Returns the sheet marker points to.
+ * @return sheet marker points to.
+ */
+ public Sheet getSheet() {
+ return sheet;
+ }
+
+ /**
+ * Sets sheet marker points to.
+ * @param sheet new sheet for the marker.
+ */
+ public void setSheet(Sheet sheet) {
+ this.sheet = sheet;
+ }
+
+ /**
+ * Returns range of the marker.
+ * @return range of cells marker points to.
+ */
+ public CellRangeAddress getRange() {
+ return range;
+ }
+
+ /**
+ * Sets range of the marker.
+ * @param range new range for the marker.
+ */
+ public void setRange(CellRangeAddress range) {
+ this.range = range;
+ }
+
+ /**
+ * Formats data marker using canonical format, for example
+ * `SheetName!$A$1:$A$5'.
+ * @return formatted data marker.
+ */
+ public String formatAsString() {
+ String sheetName = (sheet == null) ? (null) : (sheet.getSheetName());
+ if (range == null) {
+ return null;
+ } else {
+ return range.formatAsString(sheetName, true);
+ }
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java index 2ecb018e7c..eddf983b28 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java @@ -36,6 +36,7 @@ import org.apache.poi.ss.usermodel.charts.ChartAxisFactory; import org.apache.poi.xssf.usermodel.charts.XSSFChartDataFactory; import org.apache.poi.xssf.usermodel.charts.XSSFChartAxis; import org.apache.poi.xssf.usermodel.charts.XSSFValueAxis; +import org.apache.poi.xssf.usermodel.charts.XSSFManualLayout; import org.apache.poi.xssf.usermodel.charts.XSSFChartLegend; import org.apache.poi.ss.usermodel.charts.ChartData; import org.apache.poi.ss.usermodel.charts.AxisPosition; @@ -49,6 +50,7 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument; import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayout; import org.openxmlformats.schemas.drawingml.x2006.chart.CTManualLayout; import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx; import org.openxmlformats.schemas.drawingml.x2006.chart.CTPrintSettings; import org.openxmlformats.schemas.drawingml.x2006.chart.CTPageMargins; import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget; @@ -90,7 +92,7 @@ public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartA } /** - * Construct a SpreadsheetML chart from a package part + * Construct a SpreadsheetML chart from a package part. * * @param part the package part holding the chart data, * the content type must be <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code> @@ -105,7 +107,8 @@ public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartA } /** - * Construct a new CTChartSpace bean. By default, it's just an empty placeholder for chart objects + * Construct a new CTChartSpace bean. + * By default, it's just an empty placeholder for chart objects. * * @return a new CTChartSpace bean */ @@ -113,16 +116,10 @@ public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartA chartSpace = CTChartSpace.Factory.newInstance(); chart = chartSpace.addNewChart(); CTPlotArea plotArea = chart.addNewPlotArea(); - CTLayout layout = plotArea.addNewLayout(); - CTManualLayout manualLayout = layout.addNewManualLayout(); - manualLayout.addNewLayoutTarget().setVal(STLayoutTarget.INNER); - manualLayout.addNewXMode().setVal(STLayoutMode.EDGE); - manualLayout.addNewYMode().setVal(STLayoutMode.EDGE); - manualLayout.addNewX().setVal(0); - manualLayout.addNewY().setVal(0); - manualLayout.addNewW().setVal(0.65); - manualLayout.addNewH().setVal(0.8); + + plotArea.addNewLayout(); chart.addNewPlotVisOnly().setVal(true); + CTPrintSettings printSettings = chartSpace.addNewPrintSettings(); printSettings.addNewHeaderFooter(); @@ -220,39 +217,14 @@ public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartA } public List<? extends XSSFChartAxis> getAxis() { + if (axis.isEmpty() && hasAxis()) { + parseAxis(); + } return axis; } - /** - * Sets the width ratio of the chart. - * Chart width is ratio multiplied by parent frame width. - * @param ratio a number between 0 and 1. - */ - public void setWidthRatio(double ratio) { - chart.getPlotArea().getLayout().getManualLayout().getW().setVal(ratio); - } - - /** - * @return relative chart width - */ - public double getWidthRatio() { - return chart.getPlotArea().getLayout().getManualLayout().getW().getVal(); - } - - /** - * Sets the height ratio of the chart. - * Chart height is ratio multiplied by parent frame height. - * @param ratio a number between 0 and 1. - */ - public void setHeightRatio(double ratio) { - chart.getPlotArea().getLayout().getManualLayout().getH().setVal(ratio); - } - - /** - * @return relative chart height - */ - public double getHeightRatio() { - return chart.getPlotArea().getLayout().getManualLayout().getH().getVal(); + public XSSFManualLayout getManualLayout() { + return new XSSFManualLayout(this); } /** @@ -307,4 +279,25 @@ public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartA } } + private boolean hasAxis() { + CTPlotArea ctPlotArea = chart.getPlotArea(); + int totalAxisCount = + ctPlotArea.sizeOfValAxArray() + + ctPlotArea.sizeOfCatAxArray() + + ctPlotArea.sizeOfDateAxArray() + + ctPlotArea.sizeOfSerAxArray(); + return totalAxisCount > 0; + } + + private void parseAxis() { + // TODO: add other axis types + parseValueAxis(); + } + + private void parseValueAxis() { + for (CTValAx valAx : chart.getPlotArea().getValAxArray()) { + axis.add(new XSSFValueAxis(this, valAx)); + } + } + } 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 index de4b415b25..1123573491 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartLegend.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartLegend.java @@ -75,6 +75,13 @@ public final class XSSFChartLegend implements ChartLegend { } } + public XSSFManualLayout getManualLayout() { + if (!legend.isSetLayout()) { + legend.addNewLayout(); + } + return new XSSFManualLayout(legend.getLayout()); + } + private STLegendPos.Enum fromLegendPosition(LegendPosition position) { switch (position) { case BOTTOM: return STLegendPos.B; diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFManualLayout.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFManualLayout.java new file mode 100644 index 0000000000..81bf55a06a --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFManualLayout.java @@ -0,0 +1,246 @@ +/* ====================================================================
+ 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.ManualLayout;
+import org.apache.poi.ss.usermodel.charts.LayoutMode;
+import org.apache.poi.ss.usermodel.charts.LayoutTarget;
+import org.apache.poi.xssf.usermodel.XSSFChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayout;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTManualLayout;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayoutMode;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayoutTarget;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutMode;
+import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget;
+
+/**
+ * Represents a SpreadsheetML manual layout.
+ * @author Roman Kashitsyn
+ */
+public final class XSSFManualLayout implements ManualLayout {
+
+ /**
+ * Underlaying CTManualLayout bean.
+ */
+ private CTManualLayout layout;
+
+ private static final LayoutMode defaultLayoutMode = LayoutMode.EDGE;
+ private static final LayoutTarget defaultLayoutTarget = LayoutTarget.INNER;
+
+ /**
+ * Create a new SpreadsheetML manual layout.
+ * @param layout a Spreadsheet ML layout that should be used as base.
+ */
+ public XSSFManualLayout(CTLayout ctLayout) {
+ initLayout(ctLayout);
+ }
+
+ /**
+ * Create a new SpreadsheetML manual layout for chart.
+ * @param chart a chart to create layout for.
+ */
+ public XSSFManualLayout(XSSFChart chart) {
+ CTPlotArea ctPlotArea = chart.getCTChart().getPlotArea();
+ CTLayout ctLayout = ctPlotArea.isSetLayout() ?
+ ctPlotArea.getLayout() : ctPlotArea.addNewLayout();
+
+ initLayout(ctLayout);
+ }
+
+ /**
+ * Return the underlying CTManualLayout bean.
+ *
+ * @return the underlying CTManualLayout bean.
+ */
+ @Internal public CTManualLayout getCTManualLayout(){
+ return layout;
+ }
+
+ public void setWidthRatio(double ratio) {
+ if (!layout.isSetW()) {
+ layout.addNewW();
+ }
+ layout.getW().setVal(ratio);
+ }
+
+ public double getWidthRatio() {
+ if (!layout.isSetW()) {
+ return 0.0;
+ }
+ return layout.getW().getVal();
+ }
+
+ public void setHeightRatio(double ratio) {
+ if (!layout.isSetH()) {
+ layout.addNewH();
+ }
+ layout.getH().setVal(ratio);
+ }
+
+ public double getHeightRatio() {
+ if (!layout.isSetH()) {
+ return 0.0;
+ }
+ return layout.getH().getVal();
+ }
+
+ public LayoutTarget getTarget() {
+ if (!layout.isSetLayoutTarget()) {
+ return defaultLayoutTarget;
+ }
+ return toLayoutTarget(layout.getLayoutTarget());
+ }
+
+ public void setTarget(LayoutTarget target) {
+ if (!layout.isSetLayoutTarget()) {
+ layout.addNewLayoutTarget();
+ }
+ layout.getLayoutTarget().setVal(fromLayoutTarget(target));
+ }
+
+ public LayoutMode getXMode() {
+ if (!layout.isSetXMode()) {
+ return defaultLayoutMode;
+ }
+ return toLayoutMode(layout.getXMode());
+ }
+
+ public void setXMode(LayoutMode mode) {
+ if (!layout.isSetXMode()) {
+ layout.addNewXMode();
+ }
+ layout.getXMode().setVal(fromLayoutMode(mode));
+ }
+
+ public LayoutMode getYMode() {
+ if (!layout.isSetYMode()) {
+ return defaultLayoutMode;
+ }
+ return toLayoutMode(layout.getYMode());
+ }
+
+ public void setYMode(LayoutMode mode) {
+ if (!layout.isSetYMode()) {
+ layout.addNewYMode();
+ }
+ layout.getYMode().setVal(fromLayoutMode(mode));
+ }
+
+ public double getX() {
+ if (!layout.isSetX()) {
+ return 0.0;
+ }
+ return layout.getX().getVal();
+ }
+
+ public void setX(double x) {
+ if (!layout.isSetX()) {
+ layout.addNewX();
+ }
+ layout.getX().setVal(x);
+ }
+
+ public double getY() {
+ if (!layout.isSetY()) {
+ return 0.0;
+ }
+ return layout.getY().getVal();
+ }
+
+ public void setY(double y) {
+ if (!layout.isSetY()) {
+ layout.addNewY();
+ }
+ layout.getY().setVal(y);
+ }
+
+ public LayoutMode getWidthMode() {
+ if (!layout.isSetWMode()) {
+ return defaultLayoutMode;
+ }
+ return toLayoutMode(layout.getWMode());
+ }
+
+ public void setWidthMode(LayoutMode mode) {
+ if (!layout.isSetWMode()) {
+ layout.addNewWMode();
+ }
+ layout.getWMode().setVal(fromLayoutMode(mode));
+ }
+
+ public LayoutMode getHeightMode() {
+ if (!layout.isSetHMode()) {
+ return defaultLayoutMode;
+ }
+ return toLayoutMode(layout.getHMode());
+ }
+
+ public void setHeightMode(LayoutMode mode) {
+ if (!layout.isSetHMode()) {
+ layout.addNewHMode();
+ }
+ layout.getHMode().setVal(fromLayoutMode(mode));
+ }
+
+ private void initLayout(CTLayout ctLayout) {
+ if (ctLayout.isSetManualLayout()) {
+ this.layout = ctLayout.getManualLayout();
+ } else {
+ this.layout = ctLayout.addNewManualLayout();
+ }
+ }
+
+ private STLayoutMode.Enum fromLayoutMode(LayoutMode mode) {
+ switch (mode) {
+ case EDGE: return STLayoutMode.EDGE;
+ case FACTOR: return STLayoutMode.FACTOR;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private LayoutMode toLayoutMode(CTLayoutMode ctLayoutMode) {
+ switch (ctLayoutMode.getVal().intValue()) {
+ case STLayoutMode.INT_EDGE: return LayoutMode.EDGE;
+ case STLayoutMode.INT_FACTOR: return LayoutMode.FACTOR;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private STLayoutTarget.Enum fromLayoutTarget(LayoutTarget target) {
+ switch (target) {
+ case INNER: return STLayoutTarget.INNER;
+ case OUTER: return STLayoutTarget.OUTER;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private LayoutTarget toLayoutTarget(CTLayoutTarget ctLayoutTarget) {
+ switch (ctLayoutTarget.getVal().intValue()) {
+ case STLayoutTarget.INT_INNER: return LayoutTarget.INNER;
+ case STLayoutTarget.INT_OUTER: return LayoutTarget.OUTER;
+ 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 index d3f6b96269..42b2775f22 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFScatterChartData.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFScatterChartData.java @@ -22,7 +22,7 @@ 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.util.DataMarker; import org.apache.poi.ss.usermodel.charts.ScatterChartData; import org.apache.poi.ss.usermodel.charts.ScatterChartSerie; import org.apache.poi.ss.usermodel.charts.ChartDataFactory; @@ -66,10 +66,8 @@ public class XSSFScatterChartData implements ScatterChartData { private int id; private int order; private boolean useCache; - private Sheet xSheet; - private Sheet ySheet; - private CellRangeAddress xAddress; - private CellRangeAddress yAddress; + private DataMarker xMarker; + private DataMarker yMarker; public Serie(int id, int order) { super(); @@ -78,14 +76,12 @@ public class XSSFScatterChartData implements ScatterChartData { this.useCache = false; } - public void setXValues(Sheet sheet, CellRangeAddress address) { - this.xSheet = sheet; - this.xAddress = address; + public void setXValues(DataMarker marker) { + xMarker = marker; } - public void setYValues(Sheet sheet, CellRangeAddress address) { - this.ySheet = sheet; - this.yAddress = address; + public void setYValues(DataMarker marker) { + yMarker = marker; } /** @@ -102,17 +98,19 @@ public class XSSFScatterChartData implements ScatterChartData { CTAxDataSource xVal = scatterSer.addNewXVal(); CTNumRef numRef = xVal.addNewNumRef(); - numRef.setF(xAddress.formatAsString(xSheet.getSheetName(), true)); + numRef.setF(xMarker.formatAsString()); CTNumDataSource yVal = scatterSer.addNewYVal(); numRef = yVal.addNewNumRef(); - numRef.setF(yAddress.formatAsString(ySheet.getSheetName(), true)); + numRef.setF(yMarker.formatAsString()); } } - public XSSFScatterChartData.Serie addSerie() { + public XSSFScatterChartData.Serie addSerie(DataMarker xMarker, DataMarker yMarker) { int numOfSeries = series.size(); Serie newSerie = new Serie(numOfSeries, numOfSeries); + newSerie.setXValues(xMarker); + newSerie.setYValues(yMarker); series.add(newSerie); return newSerie; } 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 index 4ed5df2b97..1646db593c 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFValueAxis.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFValueAxis.java @@ -48,6 +48,11 @@ public class XSSFValueAxis extends XSSFChartAxis implements ValueAxis { createAxis(id, pos); } + public XSSFValueAxis(XSSFChart chart, CTValAx ctValAx) { + super(chart); + this.ctValAx = ctValAx; + } + public long getId() { return ctValAx.getAxId().getVal(); } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFManualLayout.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFManualLayout.java new file mode 100644 index 0000000000..cceceddff9 --- /dev/null +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFManualLayout.java @@ -0,0 +1,104 @@ +/* ====================================================================
+ 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.ss.usermodel.charts.ManualLayout;
+import org.apache.poi.ss.usermodel.charts.LayoutMode;
+import org.apache.poi.ss.usermodel.charts.LayoutTarget;
+import org.apache.poi.xssf.usermodel.*;
+
+public final class TestXSSFManualLayout extends TestCase {
+
+ /*
+ * Accessor methods are not trivial. They use lazy underlying bean
+ * initialization so there can be some errors (NPE, for example).
+ */
+ public void testAccessorMethods() throws Exception {
+ final double newRatio = 1.1;
+ final double newCoordinate = 0.3;
+ final LayoutMode nonDefaultMode = LayoutMode.FACTOR;
+ final LayoutTarget nonDefaultTarget = LayoutTarget.OUTER;
+
+ ManualLayout layout = getEmptyLayout();
+
+ layout.setWidthRatio(newRatio);
+ assertTrue(layout.getWidthRatio() == newRatio);
+
+ layout.setHeightRatio(newRatio);
+ assertTrue(layout.getHeightRatio() == newRatio);
+
+ layout.setX(newCoordinate);
+ assertTrue(layout.getX() == newCoordinate);
+
+ layout.setY(newCoordinate);
+ assertTrue(layout.getY() == newCoordinate);
+
+ layout.setXMode(nonDefaultMode);
+ assertTrue(layout.getXMode() == nonDefaultMode);
+
+ layout.setYMode(nonDefaultMode);
+ assertTrue(layout.getYMode() == nonDefaultMode);
+
+ layout.setWidthMode(nonDefaultMode);
+ assertTrue(layout.getWidthMode() == nonDefaultMode);
+
+ layout.setHeightMode(nonDefaultMode);
+ assertTrue(layout.getHeightMode() == nonDefaultMode);
+
+ layout.setTarget(nonDefaultTarget);
+ assertTrue(layout.getTarget() == nonDefaultTarget);
+
+ }
+
+ /*
+ * Layout must have reasonable default values and must not throw
+ * any exceptions.
+ */
+ public void testDefaultValues() throws Exception {
+ ManualLayout layout = getEmptyLayout();
+
+ assertNotNull(layout.getTarget());
+ assertNotNull(layout.getXMode());
+ assertNotNull(layout.getYMode());
+ assertNotNull(layout.getHeightMode());
+ assertNotNull(layout.getWidthMode());
+ /*
+ * According to interface, 0.0 should be returned for
+ * uninitialized double properties.
+ */
+ assertTrue(layout.getX() == 0.0);
+ assertTrue(layout.getY() == 0.0);
+ assertTrue(layout.getWidthRatio() == 0.0);
+ assertTrue(layout.getHeightRatio() == 0.0);
+ }
+
+ private ManualLayout getEmptyLayout() {
+ 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();
+ return legend.getManualLayout();
+ }
+}
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 index cd39a6917f..852af700fd 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java @@ -21,6 +21,7 @@ import junit.framework.TestCase; import org.apache.poi.xssf.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.DataMarker; import org.apache.poi.ss.usermodel.charts.*; import org.apache.poi.xssf.usermodel.charts.XSSFChartDataFactory; @@ -39,9 +40,9 @@ public final class TestXSSFScatterChartData extends TestCase { 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)); + DataMarker xMarker = new DataMarker(sheet, new CellRangeAddress(0,0,1,10)); + DataMarker yMarker = new DataMarker(sheet, new CellRangeAddress(1,1,1,10)); + ScatterChartSerie serie = scatterChartData.addSerie(xMarker, yMarker); assertEquals(scatterChartData.getSeries().size(), 1); |