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 new file mode 100644 index 0000000..a47db1e --- /dev/null +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.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.examples; + +import java.io.FileOutputStream; +import java.util.Date; + +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.*; +import org.apache.poi.ss.usermodel.charts.*; +import org.apache.poi.xssf.usermodel.*; +import org.apache.poi.xssf.usermodel.charts.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +/** + * Illustrates how to create a simple scatter chart. + */ +public class ScatterChart { + + public static void main(String[]args) throws Exception { + Workbook wb = new XSSFWorkbook(); + CreationHelper creationHelper = wb.getCreationHelper(); + Sheet sheet = wb.createSheet("new sheet"); + final int NUM_OF_ROWS = 3; + final int NUM_OF_COLUMNS = 10; + + // Create a row and put some cells in it. Rows are 0 based. + Row row; + Cell cell; + for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) { + row = sheet.createRow((short)rowIndex); + for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) { + cell = row.createCell((short)colIndex); + cell.setCellValue(colIndex * (rowIndex + 1)); + } + } + + Drawing drawing = sheet.createDrawingPatriarch(); + ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15); + + Chart chart = drawing.createChart(anchor); + ChartLegend legend = chart.getOrCreateLegend(); + legend.setPosition(LegendPosition.RIGHT); + + ScatterChartData data = chart.getChartDataFactory().createScatterChartData(); + + 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, NUM_OF_COLUMNS + 1, NUM_OF_COLUMNS + 1)); + firstSerie.setXValues(sheet, new CellRangeAddress(1, 1, NUM_OF_COLUMNS + 1, NUM_OF_COLUMNS + 1)); + + ScatterChartSerie secondSerie = data.addSerie(); + secondSerie.setXValues(sheet, new CellRangeAddress(0, 0, NUM_OF_COLUMNS + 1, NUM_OF_COLUMNS + 1)); + secondSerie.setYValues(sheet, new CellRangeAddress(2, 2, NUM_OF_COLUMNS + 1, NUM_OF_COLUMNS + 1)); + + chart.plot(data, bottomAxis, leftAxis); + + // Write the output to a file + FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx"); + wb.write(fileOut); + fileOut.close(); + } +} diff --git a/src/java/org/apache/poi/ss/usermodel/Chart.java b/src/java/org/apache/poi/ss/usermodel/Chart.java new file mode 100644 index 0000000..8c4198e --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/Chart.java @@ -0,0 +1,66 @@ +/* ==================================================================== + 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; + +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.ChartDataFactory; +import org.apache.poi.ss.usermodel.charts.ChartAxisFactory; + +/** + * High level representation of a chart. + * + * @author Roman Kashitsyn + */ +public interface Chart { + + /** + * @return an appropriate ChartDataFactory implementation + */ + ChartDataFactory getChartDataFactory(); + + /** + * @return an appropriate ChartAxisFactory implementation + */ + ChartAxisFactory getChartAxisFactory(); + + /** + * @return chart legend instance + */ + ChartLegend getOrCreateLegend(); + + /** + * Delete current chart legend. + */ + void deleteLegend(); + + /** + * @return list of all chart axis + */ + List getAxis(); + + /** + * Plots specified data on the chart. + * + * @param data a data to plot + */ + void plot(ChartData data, ChartAxis... axis); +} diff --git a/src/java/org/apache/poi/ss/usermodel/Drawing.java b/src/java/org/apache/poi/ss/usermodel/Drawing.java index 82c420a..aaf5660 100644 --- a/src/java/org/apache/poi/ss/usermodel/Drawing.java +++ b/src/java/org/apache/poi/ss/usermodel/Drawing.java @@ -17,10 +17,51 @@ package org.apache.poi.ss.usermodel; /** + * High level representation of spreadsheet drawing. * @author Yegor Kozlov + * @author Roman Kashitsyn */ public interface Drawing { - Picture createPicture(ClientAnchor anchor, int pictureIndex); + /** + * Creates a picture. + * @param anchor the client anchor describes how this picture is + * attached to the sheet. + * @param pictureIndex the index of the picture in the workbook collection + * of pictures. + * + * @return the newly created picture. + */ + Picture createPicture(ClientAnchor anchor, int pictureIndex); - Comment createCellComment(ClientAnchor anchor); + /** + * Creates a comment. + * @param anchor the client anchor describes how this comment is attached + * to the sheet. + * @return the newly created comment. + */ + Comment createCellComment(ClientAnchor anchor); + + /** + * Creates a chart. + * @param anchor the client anchor describes how this chart is attached to + * the sheet. + * @return the newly created chart + */ + Chart createChart(ClientAnchor anchor); + + /** + * Creates a new client anchor and sets the top-left and bottom-right + * coordinates of the anchor. + * + * @param dx1 the x coordinate in EMU within the first cell. + * @param dy1 the y coordinate in EMU within the first cell. + * @param dx2 the x coordinate in EMU within the second cell. + * @param dy2 the y coordinate in EMU within the second cell. + * @param col1 the column (0 based) of the first cell. + * @param row1 the row (0 based) of the first cell. + * @param col2 the column (0 based) of the second cell. + * @param row2 the row (0 based) of the second cell. + * @return the newly created client anchor + */ + ClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2); } diff --git a/src/java/org/apache/poi/ss/usermodel/charts/AxisCrossBetween.java b/src/java/org/apache/poi/ss/usermodel/charts/AxisCrossBetween.java new file mode 100644 index 0000000..d470cf6 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/AxisCrossBetween.java @@ -0,0 +1,36 @@ +/* ==================================================================== + 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 crossing states of an axis. + * + * @author Roman Kashitsyn + */ +public enum AxisCrossBetween { + /** + * Specifies the value axis shall cross the category axis + * between data markers. + */ + BETWEEN, + /** + * Specifies the value axis shall cross the category axis at + * the midpoint of a category. + */ + MIDPOINT_CATEGORY +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/AxisCrosses.java b/src/java/org/apache/poi/ss/usermodel/charts/AxisCrosses.java new file mode 100644 index 0000000..906198b --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/AxisCrosses.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.ss.usermodel.charts; + +/** + * Specifies the possible crossing points for an axis. + * + * @author Roman Kashitsyn + */ +public enum AxisCrosses { + /** + * The category axis crosses at the zero point of the value axis (if + * possible), or the minimum value (if the minimum is greater than zero) or + * the maximum (if the maximum is less than zero). + */ + AUTO_ZERO, + /** + * The axis crosses at the maximum value. + */ + MIN, + /** + * Axis crosses at the minimum value of the chart. + */ + MAX +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/AxisOrientation.java b/src/java/org/apache/poi/ss/usermodel/charts/AxisOrientation.java new file mode 100644 index 0000000..e8c219b --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/AxisOrientation.java @@ -0,0 +1,36 @@ +/* ==================================================================== + 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 place a picture on a data point, series, wall, or floor. + * + * @author Roman Kashitsyn + */ +public enum AxisOrientation { + /** + * Specifies that the values on the axis shall be reversed + * so they go from maximum to minimum. + */ + MAX_MIN, + /** + * Specifies that the axis values shall be in the usual + * order, minimum to maximum. + */ + MIN_MAX +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/AxisPosition.java b/src/java/org/apache/poi/ss/usermodel/charts/AxisPosition.java new file mode 100644 index 0000000..db189f9 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/AxisPosition.java @@ -0,0 +1,30 @@ +/* ==================================================================== + 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; + +/** + * Enumeration of all possible axis positions. + * + * @author Roman Kashitsyn + */ +public enum AxisPosition { + BOTTOM, + LEFT, + RIGHT, + TOP +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java new file mode 100644 index 0000000..034f450 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.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.ss.usermodel.charts; + +/** + * High level representation of chart axis. + * + * @author Roman Kashitsyn + */ +public interface ChartAxis { + + /** + * @return axis id + */ + long getId(); + + /** + * @return axis position + */ + AxisPosition getPosition(); + + /** + * @param position new axis position + */ + void setPosition(AxisPosition position); + + /** + * @return axis number format + */ + String getNumberFormat(); + + /** + * @param format axis number format + */ + void setNumberFormat(String format); + + /** + * @return true if log base is defined, false otherwise + */ + boolean isSetLogBase(); + + /** + * @param logBase a number between 2 and 1000 (inclusive) + * @throws IllegalArgumentException if log base not within allowed range + */ + void setLogBase(double logBase); + + /** + * @return axis log base or 0.0 if not set + */ + double getLogBase(); + + /** + * @return true if minimum value is defined, false otherwise + */ + boolean isSetMinimum(); + + /** + * @return axis minimum or 0.0 if not set + */ + double getMinimum(); + + /** + * @param min axis minimum + */ + void setMinimum(double min); + + /** + * @return true if maximum value is defined, false otherwise + */ + boolean isSetMaximum(); + + /** + * @return axis maximum or 0.0 if not set + */ + double getMaximum(); + + /** + * @param max axis maximum + */ + void setMaximum(double max); + + /** + * @return axis orientation + */ + AxisOrientation getOrientation(); + + /** + * @param axis orientation + */ + void setOrientation(AxisOrientation orientation); + + /** + * @param crosses axis cross type + */ + void setCrosses(AxisCrosses crosses); + + /** + * @return axis cross type + */ + AxisCrosses getCrosses(); + + /** + * Declare this axis cross another axis. + * @param axis that this axis should cross + */ + void crossAxis(ChartAxis axis); +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartAxisFactory.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartAxisFactory.java new file mode 100644 index 0000000..9c1e09d --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartAxisFactory.java @@ -0,0 +1,34 @@ +/* ==================================================================== + 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; + +import org.apache.poi.ss.usermodel.Chart; + +/** + * A factory for different chart axis. + * + * @author Roman Kashitsyn + */ +public interface ChartAxisFactory { + + /** + * @return new value axis + */ + ValueAxis createValueAxis(AxisPosition pos); + +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartData.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartData.java new file mode 100644 index 0000000..f2acc6f --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartData.java @@ -0,0 +1,36 @@ +/* ==================================================================== + 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; + +import org.apache.poi.ss.usermodel.Chart; + +/** + * A base for all chart data types. + * + * @author Roman Kashitsyn + */ +public interface ChartData { + + /** + * Fills a chart with data specified by implementation. + * + * @param chart a chart to fill in + * @param axis chart axis to use + */ + void fillChart(Chart chart, ChartAxis... axis); +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java new file mode 100644 index 0000000..3914fcd --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java @@ -0,0 +1,32 @@ +/* ==================================================================== + 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; + +/** + * A factory for different chart data types. + * + * @author Roman Kashitsyn + */ +public interface ChartDataFactory { + + /** + * @return an appropriate ScatterChartData instance + */ + ScatterChartData createScatterChartData(); + +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java new file mode 100644 index 0000000..0975caf --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java @@ -0,0 +1,37 @@ +/* ==================================================================== + 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 legend. + * + * @author Roman Kashitsyn + */ +public interface ChartLegend { + + /** + * @return legend position + */ + LegendPosition getPosition(); + + /** + * @param position new legend position + */ + void setPosition(LegendPosition position); + +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/LegendPosition.java b/src/java/org/apache/poi/ss/usermodel/charts/LegendPosition.java new file mode 100644 index 0000000..7536168 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/LegendPosition.java @@ -0,0 +1,31 @@ +/* ==================================================================== + 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; + +/** + * Enumeration of all possible chart legend positions. + * + * @author Roman Kashitsyn + */ +public enum LegendPosition { + BOTTOM, + LEFT, + RIGHT, + TOP, + TOP_RIGHT +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java new file mode 100644 index 0000000..7f828d7 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.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; + +import java.util.List; + +/** + * @author Roman Kashitsyn + */ +public interface ScatterChartData extends ChartData { + /** + * @return a new scatter chart serie + */ + ScatterChartSerie addSerie(); + + /** + * @return list of all series + */ + List getSeries(); +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSerie.java b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSerie.java new file mode 100644 index 0000000..274113b --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSerie.java @@ -0,0 +1,41 @@ +/* ==================================================================== + 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; + +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.usermodel.charts.ChartDataFactory; + +/** + * @author Roman Kashitsyn + */ +public interface ScatterChartSerie { + + /** + * @param sheet a sheet to take range from + * @param address a column or a row with values + */ + void setXValues(Sheet sheet, CellRangeAddress address); + + /**' + * @param sheet a sheet to take range from + * @param address a column or a row with values + */ + void setYValues(Sheet sheet, CellRangeAddress address); + +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ValueAxis.java b/src/java/org/apache/poi/ss/usermodel/charts/ValueAxis.java new file mode 100644 index 0000000..5613257 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/ValueAxis.java @@ -0,0 +1,34 @@ +/* ==================================================================== + 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; + +/** + * @author Roman Kashitsyn + */ +public interface ValueAxis extends ChartAxis { + + /** + * @return cross between type + */ + AxisCrossBetween getCrossBetween(); + + /** + * @param crossBetween cross between type + */ + void setCrossBetween(AxisCrossBetween crossBetween); +} diff --git a/src/java/org/apache/poi/ss/util/CellRangeAddress.java b/src/java/org/apache/poi/ss/util/CellRangeAddress.java index 2c34d5f..4a7ec73 100644 --- a/src/java/org/apache/poi/ss/util/CellRangeAddress.java +++ b/src/java/org/apache/poi/ss/util/CellRangeAddress.java @@ -80,10 +80,24 @@ public class CellRangeAddress extends CellRangeAddressBase { * like single cell references (e.g. 'A1' instead of 'A1:A1'). */ public String formatAsString() { + return formatAsString(null, false); + } + + /** + * @return the text format of this range using specified sheet name. + */ + public String formatAsString(String sheetName, boolean useAbsoluteAddress) { StringBuffer sb = new StringBuffer(); - CellReference cellRefFrom = new CellReference(getFirstRow(), getFirstColumn()); - CellReference cellRefTo = new CellReference(getLastRow(), getLastColumn()); + if (sheetName != null) { + sb.append(sheetName); + sb.append("!"); + } + CellReference cellRefFrom = new CellReference(getFirstRow(), getFirstColumn(), + useAbsoluteAddress, useAbsoluteAddress); + CellReference cellRefTo = new CellReference(getLastRow(), getLastColumn(), + useAbsoluteAddress, useAbsoluteAddress); sb.append(cellRefFrom.formatAsString()); + //for a single-cell reference return A1 instead of A1:A1 if(!cellRefFrom.equals(cellRefTo)){ sb.append(':'); 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 6f2accf..2ecb018 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java @@ -21,11 +21,24 @@ import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.Map; +import java.util.List; +import java.util.ArrayList; + +import javax.xml.namespace.QName; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.util.Internal; +import org.apache.poi.ss.usermodel.Chart; +import org.apache.poi.ss.usermodel.charts.ChartAxis; +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.XSSFChartLegend; +import org.apache.poi.ss.usermodel.charts.ChartData; +import org.apache.poi.ss.usermodel.charts.AxisPosition; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; @@ -33,115 +46,265 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace; import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle; 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.CTPrintSettings; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTPageMargins; +import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget; +import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutMode; import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; import org.w3c.dom.NodeList; import org.w3c.dom.Text; /** * Represents a SpreadsheetML Chart + * @author Nick Burch + * @author Roman Kashitsyn */ -public final class XSSFChart extends POIXMLDocumentPart { - /** - * Root element of the SpreadsheetML Chart part - */ - private CTChartSpace chartSpace; - /** - * The Chart within that - */ - private CTChart chart; - - /** - * Create a new SpreadsheetML chart - */ - protected XSSFChart() { - super(); - createChart(); - } - - /** - * Construct a SpreadsheetML chart from a package part - * - * @param part the package part holding the chart data, - * the content type must be application/vnd.openxmlformats-officedocument.drawingml.chart+xml - * @param rel the package relationship holding this chart, - * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart - */ - protected XSSFChart(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); - - chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream()).getChartSpace(); - chart = chartSpace.getChart(); - } - - /** - * Construct a new CTChartSpace bean. By default, it's just an empty placeholder for chart objects - * - * @return a new CTChartSpace bean - */ - private void createChart() { - chartSpace = CTChartSpace.Factory.newInstance(); - chart = chartSpace.addNewChart(); - } - - /** - * Return the underlying CTChartSpace bean, the root element of the SpreadsheetML Chart part. - * - * @return the underlying CTChartSpace bean - */ - @Internal - public CTChartSpace getCTChartSpace(){ - return chartSpace; - } - - /** - * Return the underlying CTChart bean, within the Chart Space - * - * @return the underlying CTChart bean - */ - @Internal - public CTChart getCTChart(){ - return chart; - } - - @Override - protected void commit() throws IOException { - XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); - - Map map = new HashMap(); - map.put(XSSFDrawing.NAMESPACE_A, "a"); - map.put(STRelationshipId.type.getName().getNamespaceURI(), "r"); - xmlOptions.setSaveSuggestedPrefixes(map); - - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - chartSpace.save(out, xmlOptions); - out.close(); - } - - /** - * Returns the title, or null if none is set - */ - public XSSFRichTextString getTitle() { - if(! chart.isSetTitle()) { - return null; - } - - // TODO Do properly - CTTitle title = chart.getTitle(); - - StringBuffer text = new StringBuffer(); - XmlObject[] t = title - .selectPath("declare namespace a='"+XSSFDrawing.NAMESPACE_A+"' .//a:t"); - for (int m = 0; m < t.length; m++) { - NodeList kids = t[m].getDomNode().getChildNodes(); - for (int n = 0; n < kids.getLength(); n++) { - if (kids.item(n) instanceof Text) { - text.append(kids.item(n).getNodeValue()); - } - } - } - - return new XSSFRichTextString(text.toString()); - } +public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartAxisFactory { + + /** + * Parent graphic frame. + */ + private XSSFGraphicFrame frame; + + /** + * Root element of the SpreadsheetML Chart part + */ + private CTChartSpace chartSpace; + /** + * The Chart within that + */ + private CTChart chart; + + List axis; + + /** + * Create a new SpreadsheetML chart + */ + protected XSSFChart() { + super(); + axis = new ArrayList(); + createChart(); + } + + /** + * Construct a SpreadsheetML chart from a package part + * + * @param part the package part holding the chart data, + * the content type must be application/vnd.openxmlformats-officedocument.drawingml.chart+xml + * @param rel the package relationship holding this chart, + * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart + */ + protected XSSFChart(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + super(part, rel); + + chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream()).getChartSpace(); + chart = chartSpace.getChart(); + } + + /** + * Construct a new CTChartSpace bean. By default, it's just an empty placeholder for chart objects + * + * @return a new CTChartSpace bean + */ + private void createChart() { + 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); + chart.addNewPlotVisOnly().setVal(true); + CTPrintSettings printSettings = chartSpace.addNewPrintSettings(); + printSettings.addNewHeaderFooter(); + + CTPageMargins pageMargins = printSettings.addNewPageMargins(); + pageMargins.setB(0.75); + pageMargins.setL(0.70); + pageMargins.setR(0.70); + pageMargins.setT(0.75); + pageMargins.setHeader(0.30); + pageMargins.setFooter(0.30); + printSettings.addNewPageSetup(); + } + + /** + * Return the underlying CTChartSpace bean, the root element of the SpreadsheetML Chart part. + * + * @return the underlying CTChartSpace bean + */ + @Internal + public CTChartSpace getCTChartSpace(){ + return chartSpace; + } + + /** + * Return the underlying CTChart bean, within the Chart Space + * + * @return the underlying CTChart bean + */ + @Internal + public CTChart getCTChart(){ + return chart; + } + + @Override + protected void commit() throws IOException { + XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); + + /* + Saved chart space must have the following namespaces set: + + */ + xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c")); + Map map = new HashMap(); + map.put(XSSFDrawing.NAMESPACE_A, "a"); + map.put(XSSFDrawing.NAMESPACE_C, "c"); + map.put(STRelationshipId.type.getName().getNamespaceURI(), "r"); + xmlOptions.setSaveSuggestedPrefixes(map); + + PackagePart part = getPackagePart(); + OutputStream out = part.getOutputStream(); + chartSpace.save(out, xmlOptions); + out.close(); + } + + /** + * Returns the parent graphic frame. + * @return the graphic frame this chart belongs to + */ + public XSSFGraphicFrame getGraphicFrame() { + return frame; + } + + /** + * Sets the parent graphic frame. + */ + protected void setGraphicFrame(XSSFGraphicFrame frame) { + this.frame = frame; + } + + public XSSFChartDataFactory getChartDataFactory() { + return XSSFChartDataFactory.getInstance(); + } + + public XSSFChart getChartAxisFactory() { + return this; + } + + public void plot(ChartData data, ChartAxis... axis) { + data.fillChart(this, axis); + } + + public XSSFValueAxis createValueAxis(AxisPosition pos) { + long id = axis.size() + 1; + XSSFValueAxis valueAxis = new XSSFValueAxis(this, id, pos); + if (axis.size() == 1) { + ChartAxis ax = axis.get(0); + ax.crossAxis(valueAxis); + valueAxis.crossAxis(ax); + } + axis.add(valueAxis); + return valueAxis; + } + + public List getAxis() { + 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(); + } + + /** + * @return true if only visible cells will be present on the chart, + * false otherwise + */ + public boolean isPlotOnlyVisibleCells() { + return chart.getPlotVisOnly().getVal(); + } + + /** + * @param plotVisOnly a flag specifying if only visible cells should be + * present on the chart + */ + public void setPlotOnlyVisibleCells(boolean plotVisOnly) { + chart.getPlotVisOnly().setVal(plotVisOnly); + } + + /** + * Returns the title, or null if none is set + */ + public XSSFRichTextString getTitle() { + if(! chart.isSetTitle()) { + return null; + } + + // TODO Do properly + CTTitle title = chart.getTitle(); + + StringBuffer text = new StringBuffer(); + XmlObject[] t = title + .selectPath("declare namespace a='"+XSSFDrawing.NAMESPACE_A+"' .//a:t"); + for (int m = 0; m < t.length; m++) { + NodeList kids = t[m].getDomNode().getChildNodes(); + for (int n = 0; n < kids.getLength(); n++) { + if (kids.item(n) instanceof Text) { + text.append(kids.item(n).getNodeValue()); + } + } + } + + return new XSSFRichTextString(text.toString()); + } + + public XSSFChartLegend getOrCreateLegend() { + return new XSSFChartLegend(this); + } + + public void deleteLegend() { + if (chart.isSetLegend()) { + chart.unsetLegend(); + } + } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java index 956f08f..b0cff7c 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java @@ -44,6 +44,7 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs; +import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrame; import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; /** @@ -57,8 +58,10 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { */ private CTDrawing drawing; private boolean isNew; + private long numOfGraphicFrames = 0L; protected static final String NAMESPACE_A = "http://schemas.openxmlformats.org/drawingml/2006/main"; + protected static final String NAMESPACE_C = "http://schemas.openxmlformats.org/drawingml/2006/chart"; /** * Create a new SpreadsheetML drawing @@ -125,6 +128,11 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { out.close(); } + public XSSFClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, + int col1, int row1, int col2, int row2) { + return new XSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2); + } + /** * Constructs a textbox under the drawing. * @@ -169,6 +177,31 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { return createPicture((XSSFClientAnchor)anchor, pictureIndex); } + /** + * Creates a chart. + * @param anchor the client anchor describes how this chart is attached to + * the sheet. + * @return the newly created chart + * @see org.apache.poi.xssf.usermodel.XSSFDrawing#createChart(ClientAnchor) + */ + public XSSFChart createChart(XSSFClientAnchor anchor) { + int chartNumber = getPackagePart().getPackage(). + getPartsByContentType(XSSFRelation.CHART.getContentType()).size() + 1; + + XSSFChart chart = (XSSFChart) createRelationship( + XSSFRelation.CHART, XSSFFactory.getInstance(), chartNumber); + String chartRelId = chart.getPackageRelationship().getId(); + + XSSFGraphicFrame frame = createGraphicFrame(anchor); + frame.setChart(chart, chartRelId); + + return chart; + } + + public XSSFChart createChart(ClientAnchor anchor) { + return createChart((XSSFClientAnchor)anchor); + } + /** * Add the indexed picture to this drawing relations * @@ -240,13 +273,12 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { return shape; } - /** - * Creates a cell comment. - * - * @param anchor the client anchor describes how this comment is attached - * to the sheet. - * @return the newly created comment. - */ + /** + * Creates a comment. + * @param anchor the client anchor describes how this comment is attached + * to the sheet. + * @return the newly created comment. + */ public XSSFComment createCellComment(ClientAnchor anchor) { XSSFClientAnchor ca = (XSSFClientAnchor)anchor; XSSFSheet sheet = (XSSFSheet)getParent(); @@ -266,6 +298,26 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { shape.setRow(ca.getRow1()); return shape; } + + /** + * Creates a new graphic frame. + * + * @param anchor the client anchor describes how this frame is attached + * to the sheet + * @return the newly created graphic frame + */ + private XSSFGraphicFrame createGraphicFrame(XSSFClientAnchor anchor) { + CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); + CTGraphicalObjectFrame ctGraphicFrame = ctAnchor.addNewGraphicFrame(); + ctGraphicFrame.set(XSSFGraphicFrame.prototype()); + + long frameId = numOfGraphicFrames++; + XSSFGraphicFrame graphicFrame = new XSSFGraphicFrame(this, ctGraphicFrame); + graphicFrame.setAnchor(anchor); + graphicFrame.setId(frameId); + graphicFrame.setName("Diagramm" + frameId); + return graphicFrame; + } /** * Returns all charts in this drawing. diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFGraphicFrame.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFGraphicFrame.java new file mode 100644 index 0000000..09acc94 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFGraphicFrame.java @@ -0,0 +1,187 @@ +/* ==================================================================== + 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; + +import javax.xml.namespace.QName; + +import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.poi.util.Internal; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlCursor; +import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrame; +import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrameNonVisual; +import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject; +import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData; +import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; +import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; +import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; +import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; + +/** + * Represents DrawingML GraphicalObjectFrame. + * + * @author Roman Kashitsyn + */ +public final class XSSFGraphicFrame { + + private static CTGraphicalObjectFrame prototype = null; + + private CTGraphicalObjectFrame graphicFrame; + private XSSFDrawing drawing; + private XSSFClientAnchor anchor; + + /** + * Construct a new XSSFGraphicFrame object. + * + * @param drawing the XSSFDrawing that owns this frame + * @param ctGraphicFrame the XML bean that stores this frame content + */ + protected XSSFGraphicFrame(XSSFDrawing drawing, CTGraphicalObjectFrame ctGraphicFrame) { + this.drawing = drawing; + this.graphicFrame = ctGraphicFrame; + } + + @Internal + public CTGraphicalObjectFrame getCTGraphicalObjectFrame() { + return graphicFrame; + } + + /** + * Initialize default structure of a new graphic frame + */ + protected static CTGraphicalObjectFrame prototype() { + if (prototype == null) { + CTGraphicalObjectFrame graphicFrame = CTGraphicalObjectFrame.Factory.newInstance(); + + CTGraphicalObjectFrameNonVisual nvGraphic = graphicFrame.addNewNvGraphicFramePr(); + CTNonVisualDrawingProps props = nvGraphic.addNewCNvPr(); + props.setId(0); + props.setName("Diagramm 1"); + nvGraphic.addNewCNvGraphicFramePr(); + + CTTransform2D transform = graphicFrame.addNewXfrm(); + CTPositiveSize2D extPoint = transform.addNewExt(); + CTPoint2D offPoint = transform.addNewOff(); + + extPoint.setCx(0); + extPoint.setCy(0); + offPoint.setX(0); + offPoint.setY(0); + + CTGraphicalObject graphic = graphicFrame.addNewGraphic(); + + prototype = graphicFrame; + } + return prototype; + } + + /** + * Sets the frame macro. + */ + public void setMacro(String macro) { + graphicFrame.setMacro(macro); + } + + /** + * Sets the frame name. + */ + public void setName(String name) { + getNonVisualProperties().setName(name); + } + + /** + * Returns the frame name. + * @return name of the frame + */ + public String getName() { + return getNonVisualProperties().getName(); + } + + private CTNonVisualDrawingProps getNonVisualProperties() { + CTGraphicalObjectFrameNonVisual nvGraphic = graphicFrame.getNvGraphicFramePr(); + return nvGraphic.getCNvPr(); + } + + /** + * Attaches frame to an anchor. + */ + protected void setAnchor(XSSFClientAnchor anchor) { + this.anchor = anchor; + } + + /** + * Returns the frame anchor. + * @return the anchor this frame is attached to + */ + public XSSFClientAnchor getAnchor() { + return anchor; + } + + /** + * Assign a DrawingML chart to the graphic frame. + */ + protected void setChart(XSSFChart chart, String relId) { + CTGraphicalObjectData data = graphicFrame.getGraphic().addNewGraphicData(); + appendChartElement(data, relId); + chart.setGraphicFrame(this); + return; + } + + /** + * Gets the frame id. + */ + public long getId() { + return graphicFrame.getNvGraphicFramePr().getCNvPr().getId(); + } + + /** + * Sets the frame id. + */ + protected void setId(long id) { + graphicFrame.getNvGraphicFramePr().getCNvPr().setId(id); + } + + /** + * The low level code to insert {@code } tag into + * {@code}. + * + * 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 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); + } +}