From c36b01a601ccd54c94b854bb99d6b67a54d7cd4e Mon Sep 17 00:00:00 2001 From: =?utf8?q?C=C3=A9dric=20Walter?= Date: Fri, 22 Nov 2013 18:26:11 +0000 Subject: [PATCH] Bug 55768: added Line charts support and setting axis tick marks, title git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1544628 13f79535-47bb-0310-9956-ffa450edef68 --- .../xssf/usermodel/examples/LineChart.java | 79 ++++++++++++ .../poi/ss/usermodel/charts/AxisTickMark.java | 30 +++++ .../poi/ss/usermodel/charts/ChartAxis.java | 32 ++++- .../ss/usermodel/charts/ChartDataFactory.java | 9 +- .../poi/ss/usermodel/charts/ChartSerie.java | 57 +++++++++ .../ss/usermodel/charts/LineChartData.java | 41 ++++++ .../ss/usermodel/charts/LineChartSerie.java | 40 ++++++ .../usermodel/charts/ScatterChartSerie.java | 3 +- .../poi/ss/usermodel/charts/TitleType.java | 28 ++++ .../charts/AbstractXSSFChartSerie.java | 79 ++++++++++++ .../usermodel/charts/XSSFCategoryAxis.java | 33 +++-- .../xssf/usermodel/charts/XSSFChartAxis.java | 52 ++++++++ .../charts/XSSFChartDataFactory.java | 7 + .../usermodel/charts/XSSFLineChartData.java | 121 ++++++++++++++++++ .../charts/XSSFScatterChartData.java | 6 +- .../xssf/usermodel/charts/XSSFValueAxis.java | 24 ++++ .../usermodel/charts/TestXSSFChartAxis.java | 35 +++++ .../charts/TestXSSFLineChartData.java | 43 +++++++ 18 files changed, 704 insertions(+), 15 deletions(-) create mode 100644 src/examples/src/org/apache/poi/xssf/usermodel/examples/LineChart.java create mode 100644 src/java/org/apache/poi/ss/usermodel/charts/AxisTickMark.java create mode 100644 src/java/org/apache/poi/ss/usermodel/charts/ChartSerie.java create mode 100644 src/java/org/apache/poi/ss/usermodel/charts/LineChartData.java create mode 100644 src/java/org/apache/poi/ss/usermodel/charts/LineChartSerie.java create mode 100644 src/java/org/apache/poi/ss/usermodel/charts/TitleType.java create mode 100644 src/ooxml/java/org/apache/poi/xssf/usermodel/charts/AbstractXSSFChartSerie.java create mode 100644 src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFLineChartData.java create mode 100644 src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFLineChartData.java diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/LineChart.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/LineChart.java new file mode 100644 index 0000000000..9fc24ac0d7 --- /dev/null +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/LineChart.java @@ -0,0 +1,79 @@ +/* ==================================================================== + 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 org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.usermodel.charts.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.FileOutputStream; + +/** + * Line chart example. + * + * @author Martin Andersson + */ +public class LineChart { + + public static void main(String[] args) throws Exception { + Workbook wb = new XSSFWorkbook(); + Sheet sheet = wb.createSheet("linechart"); + 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.TOP_RIGHT); + + LineChartData data = chart.getChartDataFactory().createLineChartData(); + + // Use a category axis for the bottom axis. + ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM); + ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); + leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); + + ChartDataSource xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1)); + ChartDataSource ys1 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1)); + ChartDataSource ys2 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1)); + + + data.addSerie(xs, ys1); + data.addSerie(xs, ys2); + + chart.plot(data, bottomAxis, leftAxis); + + // Write the output to a file + FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx"); + wb.write(fileOut); + fileOut.close(); + } +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/AxisTickMark.java b/src/java/org/apache/poi/ss/usermodel/charts/AxisTickMark.java new file mode 100644 index 0000000000..5c7d16a4e6 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/AxisTickMark.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 possible axis tick marks. + * + * @author Martin Andersson + */ +public enum AxisTickMark { + NONE, + CROSS, + IN, + OUT +} 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 e4ccdb5db8..f3d9365894 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java @@ -26,7 +26,7 @@ import org.apache.poi.util.Beta; */ @Beta public interface ChartAxis { - + /** * @return axis id */ @@ -123,4 +123,34 @@ public interface ChartAxis { * @param axis that this axis should cross */ void crossAxis(ChartAxis axis); + + /** + * @return visibility of the axis. + */ + boolean isVisible(); + + /** + * @param value visibility of the axis. + */ + void setVisible(boolean value); + + /** + * @return major tick mark. + */ + AxisTickMark getMajorTickMark(); + + /** + * @param tickMark major tick mark type. + */ + void setMajorTickMark(AxisTickMark tickMark); + + /** + * @return minor tick mark. + */ + AxisTickMark getMinorTickMark(); + + /** + * @param tickMark minor tick mark type. + */ + void setMinorTickMark(AxisTickMark tickMark); } diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java index f75e66307d..675322da70 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java @@ -22,14 +22,19 @@ import org.apache.poi.util.Beta; /** * A factory for different charts data types. * - * @author Roman Kashitsyn + * @author Roman Kashitsyn, Martin Andersson */ @Beta public interface ChartDataFactory { - + /** * @return an appropriate ScatterChartData instance */ ScatterChartData createScatterChartData(); + /** + * @return a LineChartData instance + */ + LineChartData createLineChartData(); + } diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartSerie.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartSerie.java new file mode 100644 index 0000000000..47f9914b54 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartSerie.java @@ -0,0 +1,57 @@ +/* ==================================================================== + 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.util.CellReference; + +/** + * Basic settings for all chart series. + * + * @author Martin Andersson + */ +public interface ChartSerie { + + /** + * Sets the title of the series as a string literal. + * + * @param title + */ + void setTitle(String title); + + /** + * Sets the title of the series as a cell reference. + * + * @param titleReference + */ + void setTitle(CellReference titleReference); + + /** + * @return title as string literal. + */ + String getTitleString(); + + /** + * @return title as cell reference. + */ + CellReference getTitleCellReference(); + + /** + * @return title type. + */ + TitleType getTitleType(); +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/LineChartData.java b/src/java/org/apache/poi/ss/usermodel/charts/LineChartData.java new file mode 100644 index 0000000000..dbc99700d3 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/LineChartData.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.util.Beta; + +import java.util.List; + +/** + * @author Martin Andersson + */ +@Beta +public interface LineChartData extends ChartData { + + /** + * @param categories data source for categories. + * @param values data source for values. + * @return a new line chart serie. + */ + LineChartSerie addSerie(ChartDataSource categories, ChartDataSource values); + + /** + * @return list of all series. + */ + List getSeries(); +} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/LineChartSerie.java b/src/java/org/apache/poi/ss/usermodel/charts/LineChartSerie.java new file mode 100644 index 0000000000..9dd9593925 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/LineChartSerie.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; + +import org.apache.poi.util.Beta; + +/** + * Represents a line chart serie. + * + * @author Martin Andersson + */ +@Beta +public interface LineChartSerie extends ChartSerie { + + /** + * @return data source used for category axis data. + */ + ChartDataSource getCategoryAxisData(); + + /** + * @return data source used for value axis. + */ + ChartDataSource getValues(); + +} 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 c968f79698..a5fa424993 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSerie.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSerie.java @@ -23,9 +23,10 @@ import org.apache.poi.util.Beta; * Represents scatter charts serie. * * @author Roman Kashitsyn + * @author Martin Andersson */ @Beta -public interface ScatterChartSerie { +public interface ScatterChartSerie extends ChartSerie { /** * @return data source used for X axis values diff --git a/src/java/org/apache/poi/ss/usermodel/charts/TitleType.java b/src/java/org/apache/poi/ss/usermodel/charts/TitleType.java new file mode 100644 index 0000000000..6d93d61d36 --- /dev/null +++ b/src/java/org/apache/poi/ss/usermodel/charts/TitleType.java @@ -0,0 +1,28 @@ +/* ==================================================================== + 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; + +/** + * Title types for charts. + * + * @author Martin Andersson + */ +public enum TitleType { + STRING, + CELL_REFERENCE +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/AbstractXSSFChartSerie.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/AbstractXSSFChartSerie.java new file mode 100644 index 0000000000..eb2fb2f595 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/AbstractXSSFChartSerie.java @@ -0,0 +1,79 @@ +/* ==================================================================== + 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.ChartSerie; +import org.apache.poi.ss.usermodel.charts.TitleType; +import org.apache.poi.ss.util.CellReference; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; + +/** + * @author Martin Andersson + */ +public abstract class AbstractXSSFChartSerie implements ChartSerie { + + private String titleValue; + private CellReference titleRef; + private TitleType titleType; + + public void setTitle(CellReference titleReference) { + titleType = TitleType.CELL_REFERENCE; + titleRef = titleReference; + } + + public void setTitle(String title) { + titleType = TitleType.STRING; + titleValue = title; + } + + public CellReference getTitleCellReference() { + if (TitleType.CELL_REFERENCE.equals(titleType)) { + return titleRef; + } + throw new IllegalStateException("Title type is not CellReference."); + } + + public String getTitleString() { + if (TitleType.STRING.equals(titleType)) { + return titleValue; + } + throw new IllegalStateException("Title type is not String."); + } + + public TitleType getTitleType() { + return titleType; + } + + protected boolean isTitleSet() { + return titleType != null; + } + + protected CTSerTx getCTSerTx() { + CTSerTx tx = CTSerTx.Factory.newInstance(); + switch (titleType) { + case CELL_REFERENCE: + tx.addNewStrRef().setF(titleRef.formatAsString()); + return tx; + case STRING: + tx.setV(titleValue); + return tx; + default: + throw new IllegalStateException("Unkown title type: " + titleType); + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFCategoryAxis.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFCategoryAxis.java index d8193a5a03..43ac8f6c4f 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFCategoryAxis.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFCategoryAxis.java @@ -17,18 +17,10 @@ package org.apache.poi.xssf.usermodel.charts; -import org.apache.poi.ss.usermodel.charts.AxisCrosses; -import org.apache.poi.ss.usermodel.charts.AxisOrientation; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.ChartAxis; +import org.apache.poi.ss.usermodel.charts.*; import org.apache.poi.util.Beta; import org.apache.poi.xssf.usermodel.XSSFChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTCrosses; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumFmt; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTScaling; -import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; /** * Category axis type. @@ -73,6 +65,21 @@ public class XSSFCategoryAxis extends XSSFChartAxis { return ctCatAx.getCrosses(); } + @Override + protected CTBoolean getDelete() { + return ctCatAx.getDelete(); + } + + @Override + protected CTTickMark getMajorCTTickMark() { + return ctCatAx.getMajorTickMark(); + } + + @Override + protected CTTickMark getMinorCTTickMark() { + return ctCatAx.getMinorTickMark(); + } + public void crossAxis(ChartAxis axis) { ctCatAx.getCrossAx().setVal(axis.getId()); } @@ -85,9 +92,15 @@ public class XSSFCategoryAxis extends XSSFChartAxis { ctCatAx.addNewCrosses(); ctCatAx.addNewCrossAx(); ctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO); + ctCatAx.addNewDelete(); + ctCatAx.addNewMajorTickMark(); + ctCatAx.addNewMinorTickMark(); setPosition(pos); setOrientation(AxisOrientation.MIN_MAX); setCrosses(AxisCrosses.AUTO_ZERO); + setVisible(true); + setMajorTickMark(AxisTickMark.CROSS); + setMinorTickMark(AxisTickMark.NONE); } } 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 index ca188a266a..2e89755fc9 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartAxis.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartAxis.java @@ -21,17 +21,21 @@ 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.ss.usermodel.charts.AxisTickMark; import org.apache.poi.util.Beta; import org.apache.poi.xssf.usermodel.XSSFChart; import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean; 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.CTTickMark; import org.openxmlformats.schemas.drawingml.x2006.chart.STOrientation; import org.openxmlformats.schemas.drawingml.x2006.chart.STAxPos; import org.openxmlformats.schemas.drawingml.x2006.chart.STCrosses; +import org.openxmlformats.schemas.drawingml.x2006.chart.STTickMark; /** * Base class for all axis types. @@ -158,10 +162,37 @@ public abstract class XSSFChartAxis implements ChartAxis { getCTCrosses().setVal(fromAxisCrosses(crosses)); } + public boolean isVisible() { + return !getDelete().getVal(); + } + + public void setVisible(boolean value) { + getDelete().setVal(!value); + } + + public AxisTickMark getMajorTickMark() { + return toAxisTickMark(getMajorCTTickMark()); + } + + public void setMajorTickMark(AxisTickMark tickMark) { + getMajorCTTickMark().setVal(fromAxisTickMark(tickMark)); + } + + public AxisTickMark getMinorTickMark() { + return toAxisTickMark(getMinorCTTickMark()); + } + + public void setMinorTickMark(AxisTickMark tickMark) { + getMinorCTTickMark().setVal(fromAxisTickMark(tickMark)); + } + protected abstract CTAxPos getCTAxPos(); protected abstract CTNumFmt getCTNumFmt(); protected abstract CTScaling getCTScaling(); protected abstract CTCrosses getCTCrosses(); + protected abstract CTBoolean getDelete(); + protected abstract CTTickMark getMajorCTTickMark(); + protected abstract CTTickMark getMinorCTTickMark(); private static STOrientation.Enum fromAxisOrientation(AxisOrientation orientation) { switch (orientation) { @@ -221,4 +252,25 @@ public abstract class XSSFChartAxis implements ChartAxis { default: return AxisPosition.BOTTOM; } } + + private static STTickMark.Enum fromAxisTickMark(AxisTickMark tickMark) { + switch (tickMark) { + case NONE: return STTickMark.NONE; + case IN: return STTickMark.IN; + case OUT: return STTickMark.OUT; + case CROSS: return STTickMark.CROSS; + default: + throw new IllegalArgumentException("Unknown AxisTickMark: " + tickMark); + } + } + + private static AxisTickMark toAxisTickMark(CTTickMark ctTickMark) { + switch (ctTickMark.getVal().intValue()) { + case STTickMark.INT_NONE: return AxisTickMark.NONE; + case STTickMark.INT_IN: return AxisTickMark.IN; + case STTickMark.INT_OUT: return AxisTickMark.OUT; + case STTickMark.INT_CROSS: return AxisTickMark.CROSS; + default: return AxisTickMark.CROSS; + } + } } 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 index 57b826a186..8bde83a258 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartDataFactory.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartDataFactory.java @@ -39,6 +39,13 @@ public class XSSFChartDataFactory implements ChartDataFactory { return new XSSFScatterChartData(); } + /** + * @return new line charts data instance + */ + public XSSFLineChartData createLineChartData() { + return new XSSFLineChartData(); + } + /** * @return factory instance */ diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFLineChartData.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFLineChartData.java new file mode 100644 index 0000000000..7da2b1e383 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFLineChartData.java @@ -0,0 +1,121 @@ +/* ==================================================================== + 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.Chart; +import org.apache.poi.ss.usermodel.charts.ChartAxis; +import org.apache.poi.ss.usermodel.charts.ChartDataSource; +import org.apache.poi.ss.usermodel.charts.LineChartData; +import org.apache.poi.ss.usermodel.charts.LineChartSerie; +import org.apache.poi.util.Beta; +import org.apache.poi.xssf.usermodel.XSSFChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Martin Andersson + */ +@Beta +public class XSSFLineChartData implements LineChartData { + + /** + * List of all data series. + */ + private List series; + + public XSSFLineChartData() { + series = new ArrayList(); + } + + static class Serie extends AbstractXSSFChartSerie implements LineChartSerie { + private int id; + private int order; + private ChartDataSource categories; + private ChartDataSource values; + + protected Serie(int id, int order, + ChartDataSource categories, + ChartDataSource values) { + this.id = id; + this.order = order; + this.categories = categories; + this.values = values; + } + + public ChartDataSource getCategoryAxisData() { + return categories; + } + + public ChartDataSource getValues() { + return values; + } + + protected void addToChart(CTLineChart ctLineChart) { + CTLineSer ctLineSer = ctLineChart.addNewSer(); + ctLineSer.addNewIdx().setVal(id); + ctLineSer.addNewOrder().setVal(order); + + // No marker symbol on the chart line. + ctLineSer.addNewMarker().addNewSymbol().setVal(STMarkerStyle.NONE); + + CTAxDataSource catDS = ctLineSer.addNewCat(); + XSSFChartUtil.buildAxDataSource(catDS, categories); + CTNumDataSource valueDS = ctLineSer.addNewVal(); + XSSFChartUtil.buildNumDataSource(valueDS, values); + + if (isTitleSet()) { + ctLineSer.setTx(getCTSerTx()); + } + } + } + + public LineChartSerie addSerie(ChartDataSource categoryAxisData, ChartDataSource values) { + if (!values.isNumeric()) { + throw new IllegalArgumentException("Value data source must be numeric."); + } + int numOfSeries = series.size(); + Serie newSerie = new Serie(numOfSeries, numOfSeries, categoryAxisData, values); + series.add(newSerie); + return newSerie; + } + + public List getSeries() { + return series; + } + + 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(); + CTLineChart lineChart = plotArea.addNewLineChart(); + lineChart.addNewVaryColors().setVal(false); + + for (Serie s : series) { + s.addToChart(lineChart); + } + + for (ChartAxis ax : axis) { + lineChart.addNewAxId().setVal(ax.getId()); + } + } +} 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 23876272ee..088e6fc2a7 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 @@ -50,7 +50,7 @@ public class XSSFScatterChartData implements ScatterChartData { /** * Package private ScatterChartSerie implementation. */ - static class Serie implements ScatterChartSerie { + static class Serie extends AbstractXSSFChartSerie implements ScatterChartSerie { private int id; private int order; private ChartDataSource xs; @@ -92,6 +92,10 @@ public class XSSFScatterChartData implements ScatterChartData { CTNumDataSource yVal = scatterSer.addNewYVal(); XSSFChartUtil.buildNumDataSource(yVal, ys); + + if (isTitleSet()) { + scatterSer.setTx(getCTSerTx()); + } } } 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 f4dec48732..7fc0718a94 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 @@ -23,14 +23,17 @@ 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.ss.usermodel.charts.AxisTickMark; import org.apache.poi.util.Beta; 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.CTBoolean; 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.CTTickMark; import org.openxmlformats.schemas.drawingml.x2006.chart.STCrossBetween; import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos; @@ -89,6 +92,21 @@ public class XSSFValueAxis extends XSSFChartAxis implements ValueAxis { return ctValAx.getCrosses(); } + @Override + protected CTBoolean getDelete() { + return ctValAx.getDelete(); + } + + @Override + protected CTTickMark getMajorCTTickMark() { + return ctValAx.getMajorTickMark(); + } + + @Override + protected CTTickMark getMinorCTTickMark() { + return ctValAx.getMinorTickMark(); + } + public void crossAxis(ChartAxis axis) { ctValAx.getCrossAx().setVal(axis.getId()); } @@ -102,11 +120,17 @@ public class XSSFValueAxis extends XSSFChartAxis implements ValueAxis { ctValAx.addNewCrosses(); ctValAx.addNewCrossAx(); ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO); + ctValAx.addNewDelete(); + ctValAx.addNewMajorTickMark(); + ctValAx.addNewMinorTickMark(); setPosition(pos); setOrientation(AxisOrientation.MIN_MAX); setCrossBetween(AxisCrossBetween.MIDPOINT_CATEGORY); setCrosses(AxisCrosses.AUTO_ZERO); + setVisible(true); + setMajorTickMark(AxisTickMark.CROSS); + setMinorTickMark(AxisTickMark.NONE); } private static STCrossBetween.Enum fromCrossBetween(AxisCrossBetween crossBetween) { 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 index 98db9440ac..0188c71555 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartAxis.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartAxis.java @@ -76,4 +76,39 @@ public final class TestXSSFChartAxis extends TestCase { assertTrue(Math.abs(axis.getMaximum() - newValue) < EPSILON); } + public void testVisibleAccessMethods() { + axis.setVisible(true); + assertTrue(axis.isVisible()); + + axis.setVisible(false); + assertFalse(axis.isVisible()); + } + + public void testMajorTickMarkAccessMethods() { + axis.setMajorTickMark(AxisTickMark.NONE); + assertEquals(AxisTickMark.NONE, axis.getMajorTickMark()); + + axis.setMajorTickMark(AxisTickMark.IN); + assertEquals(AxisTickMark.IN, axis.getMajorTickMark()); + + axis.setMajorTickMark(AxisTickMark.OUT); + assertEquals(AxisTickMark.OUT, axis.getMajorTickMark()); + + axis.setMajorTickMark(AxisTickMark.CROSS); + assertEquals(AxisTickMark.CROSS, axis.getMajorTickMark()); + } + + public void testMinorTickMarkAccessMethods() { + axis.setMinorTickMark(AxisTickMark.NONE); + assertEquals(AxisTickMark.NONE, axis.getMinorTickMark()); + + axis.setMinorTickMark(AxisTickMark.IN); + assertEquals(AxisTickMark.IN, axis.getMinorTickMark()); + + axis.setMinorTickMark(AxisTickMark.OUT); + assertEquals(AxisTickMark.OUT, axis.getMinorTickMark()); + + axis.setMinorTickMark(AxisTickMark.CROSS); + assertEquals(AxisTickMark.CROSS, axis.getMinorTickMark()); + } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFLineChartData.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFLineChartData.java new file mode 100644 index 0000000000..6e45ec0014 --- /dev/null +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFLineChartData.java @@ -0,0 +1,43 @@ +package org.apache.poi.xssf.usermodel.charts; + +import junit.framework.TestCase; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.usermodel.charts.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.SheetBuilder; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +/** + * @author Martin Andersson + */ +public class TestXSSFLineChartData extends TestCase { + + private static final Object[][] plotData = { + {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + }; + + public void testOneSeriePlot() throws Exception { + Workbook wb = new XSSFWorkbook(); + Sheet sheet = new SheetBuilder(wb, plotData).build(); + Drawing drawing = sheet.createDrawingPatriarch(); + ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30); + Chart chart = drawing.createChart(anchor); + + ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM); + ChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); + + LineChartData lineChartData = + chart.getChartDataFactory().createLineChartData(); + + ChartDataSource xs = DataSources.fromStringCellRange(sheet, CellRangeAddress.valueOf("A1:J1")); + ChartDataSource ys = DataSources.fromNumericCellRange(sheet, CellRangeAddress.valueOf("A2:J2")); + LineChartSerie serie = lineChartData.addSerie(xs, ys); + + assertNotNull(serie); + assertEquals(1, lineChartData.getSeries().size()); + assertTrue(lineChartData.getSeries().contains(serie)); + + chart.plot(lineChartData, bottomAxis, leftAxis); + } +} -- 2.39.5