From: Alain BĂ©arez Date: Sun, 26 Nov 2017 14:03:01 +0000 (+0000) Subject: XDDF usermodel for Charts closes #68 on GitHub X-Git-Tag: REL_4_0_0_FINAL~342 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=3b8f806850882b1aa60923526b44950d215a8990;p=poi.git XDDF usermodel for Charts closes #68 on GitHub git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1816383 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/build.xml b/build.xml index a9ac116704..092d07c5f9 100644 --- a/build.xml +++ b/build.xml @@ -2051,7 +2051,7 @@ under the License. - + diff --git a/src/examples/src/org/apache/poi/xslf/usermodel/BarChartDemo.java b/src/examples/src/org/apache/poi/xslf/usermodel/BarChartDemo.java new file mode 100644 index 0000000000..c66b9e00ed --- /dev/null +++ b/src/examples/src/org/apache/poi/xslf/usermodel/BarChartDemo.java @@ -0,0 +1,145 @@ +/* + * ==================================================================== + * 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.xslf.usermodel; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xddf.usermodel.chart.AxisOrientation; +import org.apache.poi.xddf.usermodel.chart.AxisPosition; +import org.apache.poi.xddf.usermodel.chart.BarDirection; +import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory; +import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource; + +/** + * Build a bar chart from a template pptx + */ +public class BarChartDemo { + private static void usage(){ + System.out.println("Usage: BarChartDemo "); + System.out.println(" bar-chart-template.pptx template with a bar chart"); + System.out.println(" bar-chart-data.txt the model to set. First line is chart title, " + + "then go pairs {axis-label value}"); + } + + public static void main(String[] args) throws Exception { + if(args.length < 2) { + usage(); + return; + } + + BufferedReader modelReader = new BufferedReader(new FileReader(args[1])); + XMLSlideShow pptx = null; + try { + String chartTitle = modelReader.readLine(); // first line is chart title + + // Category Axis Data + List listCategories = new ArrayList(3); + + // Values + List listValues = new ArrayList(3); + + // set model + String ln; + while((ln = modelReader.readLine()) != null){ + String[] vals = ln.split("\\s+"); + listCategories.add(vals[0]); + listValues.add(Double.valueOf(vals[1])); + } + String[] categories = listCategories.toArray(new String[listCategories.size()]); + Double[] values = listValues.toArray(new Double[listValues.size()]); + + pptx = new XMLSlideShow(new FileInputStream(args[0])); + XSLFSlide slide = pptx.getSlides().get(0); + setBarData(findChart(slide), chartTitle, categories, values); + + XSLFChart chart = findChart(pptx.createSlide().importContent(slide)); + setColumnData(chart, "Column variant"); + + // save the result + OutputStream out = new FileOutputStream("bar-chart-demo-output.pptx"); + try { + pptx.write(out); + } finally { + out.close(); + } + } finally { + if (pptx != null) { + pptx.close(); + } + modelReader.close(); + } + } + + private static void setBarData(XSLFChart chart, String chartTitle, String[] categories, Double[] values) { + final List series = chart.getChartSeries(); + final XDDFBarChartData bar = (XDDFBarChartData) series.get(0); + + final int numOfPoints = categories.length; + final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0)); + final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1)); + final XDDFDataSource categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange); + final XDDFNumericalDataSource valuesData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange); + + bar.getSeries().get(0).replaceData(categoriesData, valuesData); + bar.getSeries().get(0).setTitle(chartTitle, chart.setSheetTitle(chartTitle)); + chart.plot(bar); + } + + private static void setColumnData(XSLFChart chart, String chartTitle) { + // Series Text + List series = chart.getChartSeries(); + XDDFBarChartData bar = (XDDFBarChartData) series.get(0); + bar.getSeries().get(0).setTitle(chartTitle, chart.setSheetTitle(chartTitle)); + + // in order to transform a bar chart into a column chart, you just need to change the bar direction + bar.setBarDirection(BarDirection.COL); + + // additionally, you can adjust the axes + bar.getCategoryAxis().setOrientation(AxisOrientation.MAX_MIN); + bar.getValueAxes().get(0).setPosition(AxisPosition.TOP); + } + + private static XSLFChart findChart(XSLFSlide slide) { + // find chart in the slide + XSLFChart chart = null; + for(POIXMLDocumentPart part : slide.getRelations()){ + if(part instanceof XSLFChart){ + chart = (XSLFChart) part; + break; + } + } + + if(chart == null) { + throw new IllegalStateException("chart not found in the template"); + } + return chart; + } +} diff --git a/src/examples/src/org/apache/poi/xslf/usermodel/PieChartDemo.java b/src/examples/src/org/apache/poi/xslf/usermodel/PieChartDemo.java index 9ba7461915..45122f7b2f 100644 --- a/src/examples/src/org/apache/poi/xslf/usermodel/PieChartDemo.java +++ b/src/examples/src/org/apache/poi/xslf/usermodel/PieChartDemo.java @@ -19,34 +19,24 @@ package org.apache.poi.xslf.usermodel; -import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumVal; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrVal; - import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xddf.usermodel.chart.XDDFChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory; +import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFPieChartData; /** * Build a pie chart from a template pptx - * - * @author Yegor Kozlov */ public class PieChartDemo { private static void usage(){ @@ -77,74 +67,45 @@ public class PieChartDemo { } } - if (chart == null) throw new IllegalStateException("chart not found in the template"); - - // embedded Excel workbook that holds the chart data - POIXMLDocumentPart xlsPart = chart.getRelations().get(0); - try (XSSFWorkbook wb = new XSSFWorkbook()) { - XSSFSheet sheet = wb.createSheet(); - - CTChart ctChart = chart.getCTChart(); - CTPlotArea plotArea = ctChart.getPlotArea(); - - CTPieChart pieChart = plotArea.getPieChartArray(0); - //Pie Chart Series - CTPieSer ser = pieChart.getSerArray(0); - - // Series Text - CTSerTx tx = ser.getTx(); - tx.getStrRef().getStrCache().getPtArray(0).setV(chartTitle); - sheet.createRow(0).createCell(1).setCellValue(chartTitle); - String titleRef = new CellReference(sheet.getSheetName(), 0, 1, true, true).formatAsString(); - tx.getStrRef().setF(titleRef); - - // Category Axis Data - CTAxDataSource cat = ser.getCat(); - CTStrData strData = cat.getStrRef().getStrCache(); - - // Values - CTNumDataSource val = ser.getVal(); - CTNumData numData = val.getNumRef().getNumCache(); - - strData.setPtArray(null); // unset old axis text - numData.setPtArray(null); // unset old values - - // set model - int idx = 0; - int rownum = 1; - String ln; - while ((ln = modelReader.readLine()) != null) { - String[] vals = ln.split("\\s+"); - CTNumVal numVal = numData.addNewPt(); - numVal.setIdx(idx); - numVal.setV(vals[1]); - - CTStrVal sVal = strData.addNewPt(); - sVal.setIdx(idx); - sVal.setV(vals[0]); - - idx++; - XSSFRow row = sheet.createRow(rownum++); - row.createCell(0).setCellValue(vals[0]); - row.createCell(1).setCellValue(Double.valueOf(vals[1])); - } - numData.getPtCount().setVal(idx); - strData.getPtCount().setVal(idx); - - String numDataRange = new CellRangeAddress(1, rownum - 1, 1, 1).formatAsString(sheet.getSheetName(), true); - val.getNumRef().setF(numDataRange); - String axisDataRange = new CellRangeAddress(1, rownum - 1, 0, 0).formatAsString(sheet.getSheetName(), true); - cat.getStrRef().setF(axisDataRange); - - // updated the embedded workbook with the data - try (OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream()) { - wb.write(xlsOut); - } - - // save the result - try (OutputStream out = new FileOutputStream("pie-chart-demo-output.pptx")) { - pptx.write(out); - } + if(chart == null) { + throw new IllegalStateException("chart not found in the template"); + } + + // Series Text + List series = chart.getChartSeries(); + XDDFPieChartData pie = (XDDFPieChartData) series.get(0); + + // Category Axis Data + List listCategories = new ArrayList(3); + + // Values + List listValues = new ArrayList(3); + + // set model + String ln; + while((ln = modelReader.readLine()) != null){ + String[] vals = ln.split("\\s+"); + listCategories.add(vals[0]); + listValues.add(Double.valueOf(vals[1])); + } + String[] categories = listCategories.toArray(new String[listCategories.size()]); + Double[] values = listValues.toArray(new Double[listValues.size()]); + + final int numOfPoints = categories.length; + final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0)); + final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1)); + final XDDFDataSource categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange); + final XDDFNumericalDataSource valuesData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange); + + XDDFPieChartData.Series firstSeries = (XDDFPieChartData.Series) pie.getSeries().get(0); + firstSeries.replaceData(categoriesData, valuesData); + firstSeries.setTitle(chartTitle, chart.setSheetTitle(chartTitle)); + firstSeries.setExplosion(25); + chart.plot(pie); + + // save the result + try (OutputStream out = new FileOutputStream("pie-chart-demo-output.pptx")) { + pptx.write(out); } } } diff --git a/src/examples/src/org/apache/poi/xslf/usermodel/bar-chart-data.txt b/src/examples/src/org/apache/poi/xslf/usermodel/bar-chart-data.txt new file mode 100644 index 0000000000..7f9c271036 --- /dev/null +++ b/src/examples/src/org/apache/poi/xslf/usermodel/bar-chart-data.txt @@ -0,0 +1,4 @@ +My Bar or Column Chart +First 1.0 +Second 3.0 +Third 4.0 \ No newline at end of file diff --git a/src/examples/src/org/apache/poi/xslf/usermodel/bar-chart-template.pptx b/src/examples/src/org/apache/poi/xslf/usermodel/bar-chart-template.pptx new file mode 100644 index 0000000000..e4d2613046 Binary files /dev/null and b/src/examples/src/org/apache/poi/xslf/usermodel/bar-chart-template.pptx differ 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 index fa14a9d3be..9aff342bce 100644 --- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/LineChart.java +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/LineChart.java @@ -20,22 +20,23 @@ import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.AxisCrosses; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ChartDataSource; -import org.apache.poi.ss.usermodel.charts.ChartLegend; -import org.apache.poi.ss.usermodel.charts.DataSources; -import org.apache.poi.ss.usermodel.charts.LegendPosition; -import org.apache.poi.ss.usermodel.charts.LineChartData; -import org.apache.poi.ss.usermodel.charts.ValueAxis; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xddf.usermodel.chart.AxisCrosses; +import org.apache.poi.xddf.usermodel.chart.AxisPosition; +import org.apache.poi.xddf.usermodel.chart.ChartTypes; +import org.apache.poi.xddf.usermodel.chart.LegendPosition; +import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis; +import org.apache.poi.xddf.usermodel.chart.XDDFChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory; +import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis; +import org.apache.poi.xssf.usermodel.XSSFChart; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; /** @@ -44,8 +45,8 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class LineChart { public static void main(String[] args) throws IOException { - try (Workbook wb = new XSSFWorkbook()) { - Sheet sheet = wb.createSheet("linechart"); + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFSheet sheet = wb.createSheet("linechart"); final int NUM_OF_ROWS = 3; final int NUM_OF_COLUMNS = 10; @@ -60,29 +61,26 @@ public class LineChart { } } - 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(); + XSSFDrawing drawing = sheet.createDrawingPatriarch(); + XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15); + + XSSFChart chart = drawing.createChart(anchor); + XDDFChartLegend legend = chart.getOrAddLegend(); 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); + XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); + XDDFValueAxis leftAxis = chart.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)); - - + + XDDFDataSource xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1)); + XDDFNumericalDataSource ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1)); + XDDFNumericalDataSource ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1)); + + XDDFChartData data = chart.createData(ChartTypes.LINE, bottomAxis, leftAxis); data.addSeries(xs, ys1); data.addSeries(xs, ys2); - - chart.plot(data, bottomAxis, leftAxis); + chart.plot(data); // Write the output to a file try (FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx")) { diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java index ccd23cf9a7..6ad9dbaeaa 100644 --- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java @@ -23,21 +23,22 @@ import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.AxisCrosses; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.ChartDataSource; -import org.apache.poi.ss.usermodel.charts.ChartLegend; -import org.apache.poi.ss.usermodel.charts.DataSources; -import org.apache.poi.ss.usermodel.charts.LegendPosition; -import org.apache.poi.ss.usermodel.charts.ScatterChartData; -import org.apache.poi.ss.usermodel.charts.ValueAxis; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xddf.usermodel.chart.AxisCrosses; +import org.apache.poi.xddf.usermodel.chart.AxisPosition; +import org.apache.poi.xddf.usermodel.chart.ChartTypes; +import org.apache.poi.xddf.usermodel.chart.LegendPosition; +import org.apache.poi.xddf.usermodel.chart.XDDFChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory; +import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis; +import org.apache.poi.xssf.usermodel.XSSFChart; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; /** @@ -46,8 +47,8 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ScatterChart { public static void main(String[] args) throws IOException { - try (Workbook wb = new XSSFWorkbook()) { - Sheet sheet = wb.createSheet("Sheet 1"); + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFSheet sheet = wb.createSheet("Sheet 1"); final int NUM_OF_ROWS = 3; final int NUM_OF_COLUMNS = 10; @@ -61,29 +62,28 @@ public class ScatterChart { 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(); + + XSSFDrawing drawing = sheet.createDrawingPatriarch(); + XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15); + + XSSFChart chart = drawing.createChart(anchor); + XDDFChartLegend legend = chart.getOrAddLegend(); legend.setPosition(LegendPosition.TOP_RIGHT); - - ScatterChartData data = chart.getChartDataFactory().createScatterChartData(); - - ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM); - ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); + + XDDFValueAxis bottomAxis = chart.createValueAxis(AxisPosition.BOTTOM); + XDDFValueAxis leftAxis = chart.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); + + XDDFDataSource xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1)); + XDDFNumericalDataSource ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1)); + XDDFNumericalDataSource ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1)); + + + XDDFChartData data = chart.createData(ChartTypes.SCATTER, bottomAxis, leftAxis); + + data.addSeries(xs, ys1); + data.addSeries(xs, ys2); + chart.plot(data); // Write the output to a file try (FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx")) { diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java index bc210b9cfe..c0aa36f524 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java @@ -45,13 +45,11 @@ import org.apache.poi.hssf.record.ObjRecord; import org.apache.poi.ss.util.CellReference; import org.apache.poi.poifs.filesystem.DirectoryEntry; import org.apache.poi.poifs.filesystem.DirectoryNode; -import org.apache.poi.ss.usermodel.Chart; import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.util.HexDump; import org.apache.poi.util.Internal; -import org.apache.poi.util.NotImplemented; import org.apache.poi.util.StringUtil; /** @@ -523,13 +521,6 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing extends ShapeContainer { */ 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. @@ -62,10 +54,10 @@ public interface Drawing extends ShapeContainer { * @return the newly created client anchor */ ClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2); - + /** - * Adds a new OLE Package Shape - * + * Adds a new OLE Package Shape + * * @param anchor the client anchor describes how this picture is * attached to the sheet. * @param storageId the storageId returned by {@link Workbook#addOlePackage(byte[], String, String, String)} diff --git a/src/java/org/apache/poi/ss/usermodel/charts/AxisCrossBetween.java b/src/java/org/apache/poi/ss/usermodel/charts/AxisCrossBetween.java index d470cf61f1..fa6d46dae9 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/AxisCrossBetween.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/AxisCrossBetween.java @@ -17,11 +17,15 @@ package org.apache.poi.ss.usermodel.charts; +import org.apache.poi.util.Removal; + /** * Specifies the possible crossing states of an axis. * - * @author Roman Kashitsyn + * @deprecated use XDDF AxisCrossBetween */ +@Deprecated +@Removal(version="4.2") public enum AxisCrossBetween { /** * Specifies the value axis shall cross the category axis diff --git a/src/java/org/apache/poi/ss/usermodel/charts/AxisCrosses.java b/src/java/org/apache/poi/ss/usermodel/charts/AxisCrosses.java index 906198bb40..29389de7ed 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/AxisCrosses.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/AxisCrosses.java @@ -17,11 +17,15 @@ package org.apache.poi.ss.usermodel.charts; +import org.apache.poi.util.Removal; + /** * Specifies the possible crossing points for an axis. * - * @author Roman Kashitsyn + * @deprecated use XDDF AxisCrosses instead */ +@Deprecated +@Removal(version="4.2") public enum AxisCrosses { /** * The category axis crosses at the zero point of the value axis (if diff --git a/src/java/org/apache/poi/ss/usermodel/charts/AxisOrientation.java b/src/java/org/apache/poi/ss/usermodel/charts/AxisOrientation.java index e8c219b437..22a408682b 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/AxisOrientation.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/AxisOrientation.java @@ -17,11 +17,15 @@ package org.apache.poi.ss.usermodel.charts; +import org.apache.poi.util.Removal; + /** * Specifies the possible ways to place a picture on a data point, series, wall, or floor. * - * @author Roman Kashitsyn + * @deprecated use XDDF AxisOrientation */ +@Deprecated +@Removal(version="4.2") public enum AxisOrientation { /** * Specifies that the values on the axis shall be reversed diff --git a/src/java/org/apache/poi/ss/usermodel/charts/AxisPosition.java b/src/java/org/apache/poi/ss/usermodel/charts/AxisPosition.java index db189f9983..e774d163eb 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/AxisPosition.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/AxisPosition.java @@ -17,11 +17,15 @@ package org.apache.poi.ss.usermodel.charts; +import org.apache.poi.util.Removal; + /** * Enumeration of all possible axis positions. * - * @author Roman Kashitsyn + * @deprecated use XDDF AxisPosition instead */ +@Deprecated +@Removal(version="4.2") public enum AxisPosition { BOTTOM, LEFT, diff --git a/src/java/org/apache/poi/ss/usermodel/charts/AxisTickMark.java b/src/java/org/apache/poi/ss/usermodel/charts/AxisTickMark.java index d25a00ad8c..80c6e7aaf8 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/AxisTickMark.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/AxisTickMark.java @@ -17,11 +17,15 @@ package org.apache.poi.ss.usermodel.charts; +import org.apache.poi.util.Removal; + /** * Enumeration of possible axis tick marks. * - * @author Martin Andersson + * @deprecated use XDDF AxisTickMark instead */ +@Deprecated +@Removal(version="4.2") public enum AxisTickMark { NONE, CROSS, 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 45cec602f1..4d297541cd 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java @@ -17,14 +17,15 @@ package org.apache.poi.ss.usermodel.charts; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * High level representation of chart axis. * - * @author Roman Kashitsyn + * @deprecated use XDDFChartAxis instead */ -@Beta +@Deprecated +@Removal(version="4.2") public interface ChartAxis { /** @@ -153,7 +154,7 @@ public interface ChartAxis { * @param tickMark minor tick mark type. */ void setMinorTickMark(AxisTickMark tickMark); - + /** * Use this to check before retrieving a number format, as calling {@link #getNumberFormat()} may create a default one if none exists. * @return true if a number format element is defined, false if not diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartAxisFactory.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartAxisFactory.java index 3eb80e28b5..a66416003a 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ChartAxisFactory.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartAxisFactory.java @@ -17,31 +17,31 @@ package org.apache.poi.ss.usermodel.charts; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * A factory for different chart axis. * - * @author Roman Kashitsyn - * @author Martin Andersson + * @deprecated */ -@Beta +@Deprecated +@Removal(version="4.2") public interface ChartAxisFactory { /** - * @param pos + * @param pos * @return new value axis at the end of the list at the specified chart position */ ValueAxis createValueAxis(AxisPosition pos); /** - * @param pos + * @param pos * @return new category axis at the end of the list at the specified chart position */ ChartAxis createCategoryAxis(AxisPosition pos); - + /** - * @param pos + * @param pos * @return new date category axis at the end of the list at the specified chart position */ ChartAxis createDateAxis(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 index 7a4aec5f0b..5048d71d34 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ChartData.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartData.java @@ -18,14 +18,15 @@ package org.apache.poi.ss.usermodel.charts; import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * A base for all charts data types. * - * @author Roman Kashitsyn + * @deprecated use XDDFChartData instead */ -@Beta +@Deprecated +@Removal(version="4.2") public interface ChartData { /** 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 675322da70..3e053e3817 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java @@ -17,14 +17,15 @@ package org.apache.poi.ss.usermodel.charts; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * A factory for different charts data types. * - * @author Roman Kashitsyn, Martin Andersson + * @deprecated */ -@Beta +@Deprecated +@Removal(version="4.2") public interface ChartDataFactory { /** diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartDataSource.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartDataSource.java index d843cac9b8..a451ceb439 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ChartDataSource.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartDataSource.java @@ -18,15 +18,16 @@ */ package org.apache.poi.ss.usermodel.charts; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * Represents data model of the charts. * * @param type of points the data source contents - * @author Roman Kashitsyn + * @deprecated use XDDFDataSource instead */ -@Beta +@Deprecated +@Removal(version="4.2") public interface ChartDataSource { /** diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java index f8ab5c9695..629b9bf146 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java @@ -17,15 +17,15 @@ package org.apache.poi.ss.usermodel.charts; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * High level representation of chart legend. * - * @author Roman Kashitsyn - * @author Martin Andersson + * @deprecated use XDDFChartLegend instead */ -@Beta +@Deprecated +@Removal(version="4.2") public interface ChartLegend extends ManuallyPositionable { /** diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ChartSeries.java b/src/java/org/apache/poi/ss/usermodel/charts/ChartSeries.java index 2ad666a8b8..bfebe94802 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ChartSeries.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ChartSeries.java @@ -18,10 +18,14 @@ package org.apache.poi.ss.usermodel.charts; import org.apache.poi.ss.util.CellReference; +import org.apache.poi.util.Removal; /** * Basic settings for all chart series. + * @deprecated */ +@Deprecated +@Removal(version="4.2") public interface ChartSeries { /** diff --git a/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java b/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java index 5ebb8cf585..b5c5e7849f 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java @@ -19,16 +19,21 @@ package org.apache.poi.ss.usermodel.charts; -import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.CellValue; +import org.apache.poi.ss.usermodel.FormulaEvaluator; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * Class {@code DataSources} is a factory for {@link ChartDataSource} instances. * - * @author Roman Kashitsyn + *@deprecated use XDDFDataSourcesFactory instead */ -@Beta +@Deprecated +@Removal(version="4.2") public class DataSources { private DataSources() { diff --git a/src/java/org/apache/poi/ss/usermodel/charts/LayoutMode.java b/src/java/org/apache/poi/ss/usermodel/charts/LayoutMode.java index 794c774887..22bbd8d2a9 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/LayoutMode.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/LayoutMode.java @@ -17,10 +17,14 @@ package org.apache.poi.ss.usermodel.charts; +import org.apache.poi.util.Removal; + /** * Specifies the possible ways to store a chart element's position. - * @author Roman Kashitsyn + * @use XDDF LayoutMode instead */ +@Deprecated +@Removal(version="4.2") public enum LayoutMode { /** * Specifies that the Width or Height shall be interpreted as the diff --git a/src/java/org/apache/poi/ss/usermodel/charts/LayoutTarget.java b/src/java/org/apache/poi/ss/usermodel/charts/LayoutTarget.java index 2a8b110cb1..73c7754fc4 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/LayoutTarget.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/LayoutTarget.java @@ -17,12 +17,16 @@ package org.apache.poi.ss.usermodel.charts; +import org.apache.poi.util.Removal; + /** * Specifies whether to layout the plot area by its inside (not including axis * and axis labels) or outside (including axis and axis labels). * - * @author Roman Kashitsyn + * @deprecated use XDDF LayoutTarget instead */ +@Deprecated +@Removal(version="4.2") public enum LayoutTarget { /** * Specifies that the plot area size shall determine the diff --git a/src/java/org/apache/poi/ss/usermodel/charts/LegendPosition.java b/src/java/org/apache/poi/ss/usermodel/charts/LegendPosition.java index 7536168a6b..826eff2f93 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/LegendPosition.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/LegendPosition.java @@ -17,11 +17,15 @@ package org.apache.poi.ss.usermodel.charts; +import org.apache.poi.util.Removal; + /** * Enumeration of all possible chart legend positions. * - * @author Roman Kashitsyn + * @deprecated use XDDF LayoutPosition instead */ +@Deprecated +@Removal(version="4.2") public enum LegendPosition { BOTTOM, LEFT, diff --git a/src/java/org/apache/poi/ss/usermodel/charts/LineChartData.java b/src/java/org/apache/poi/ss/usermodel/charts/LineChartData.java index 4fa9f8e6fa..39c4674b7e 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/LineChartData.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/LineChartData.java @@ -19,12 +19,15 @@ package org.apache.poi.ss.usermodel.charts; import java.util.List; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * Data for a Line Chart + * + * @deprecated use XDDFLineChartData instead */ -@Beta +@Deprecated +@Removal(version="4.2") public interface LineChartData extends ChartData { /** diff --git a/src/java/org/apache/poi/ss/usermodel/charts/LineChartSeries.java b/src/java/org/apache/poi/ss/usermodel/charts/LineChartSeries.java index 842c442a5c..8675b77de3 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/LineChartSeries.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/LineChartSeries.java @@ -17,12 +17,15 @@ package org.apache.poi.ss.usermodel.charts; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * Represents a line chart series. + * + * @deprecated use XDDFLineChartData.Series instead */ -@Beta +@Deprecated +@Removal(version="4.2") public interface LineChartSeries extends ChartSeries { /** diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ManualLayout.java b/src/java/org/apache/poi/ss/usermodel/charts/ManualLayout.java index cd78c1c95a..8b63276151 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ManualLayout.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ManualLayout.java @@ -17,14 +17,15 @@ package org.apache.poi.ss.usermodel.charts; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * High level representation of chart element manual layout. * - * @author Roman Kashitsyn + * @deprecated use XDDFManualLayout instead */ -@Beta +@Deprecated +@Removal(version="4.2") public interface ManualLayout { /** @@ -117,7 +118,7 @@ public interface ManualLayout { public void setHeightMode(LayoutMode mode); /** - * Returns current height mode of this + * Returns current height mode of this * @return height mode of this manual layout. */ public LayoutMode getHeightMode(); diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ManuallyPositionable.java b/src/java/org/apache/poi/ss/usermodel/charts/ManuallyPositionable.java index 3fc5ba1fb6..ee4abad22c 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ManuallyPositionable.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ManuallyPositionable.java @@ -17,15 +17,16 @@ package org.apache.poi.ss.usermodel.charts; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * Abstraction of chart element that can be positioned with manual * layout. * - * @author Roman Kashitsyn + * @deprecated */ -@Beta +@Deprecated +@Removal(version="4.2") public interface ManuallyPositionable { /** diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java index 594b5bdfe3..ae178c747d 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java @@ -19,9 +19,15 @@ package org.apache.poi.ss.usermodel.charts; import java.util.List; +import org.apache.poi.util.Removal; + /** * Data for a Scatter Chart + * + * @deprecated use XDDFScatterChartData instead */ +@Deprecated +@Removal(version="4.2") public interface ScatterChartData extends ChartData { /** * @param xs data source to be used for X axis values diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSeries.java b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSeries.java index f200cb6ba2..6967f7ffbf 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSeries.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSeries.java @@ -17,12 +17,15 @@ package org.apache.poi.ss.usermodel.charts; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** * Represents scatter charts series. + * + * @deprecated use XDFFScatterChartData.Series instead */ -@Beta +@Deprecated +@Removal(version="4.2") public interface ScatterChartSeries extends ChartSeries { /** diff --git a/src/java/org/apache/poi/ss/usermodel/charts/TitleType.java b/src/java/org/apache/poi/ss/usermodel/charts/TitleType.java index 07b5beb8a3..475adf06bc 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/TitleType.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/TitleType.java @@ -17,11 +17,15 @@ package org.apache.poi.ss.usermodel.charts; +import org.apache.poi.util.Removal; + /** * Title types for charts. * - * @author Martin Andersson + * @deprecated */ +@Deprecated +@Removal(version="4.2") public enum TitleType { STRING, CELL_REFERENCE diff --git a/src/java/org/apache/poi/ss/usermodel/charts/ValueAxis.java b/src/java/org/apache/poi/ss/usermodel/charts/ValueAxis.java index f6673dae47..d16ff52b06 100644 --- a/src/java/org/apache/poi/ss/usermodel/charts/ValueAxis.java +++ b/src/java/org/apache/poi/ss/usermodel/charts/ValueAxis.java @@ -17,12 +17,13 @@ package org.apache.poi.ss.usermodel.charts; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; /** - * @author Roman Kashitsyn + * @deprecated use XDDFValueAxis instead */ -@Beta +@Deprecated +@Removal(version="4.2") public interface ValueAxis extends ChartAxis { /** diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisCrossBetween.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisCrossBetween.java new file mode 100644 index 0000000000..ec2fc32a44 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisCrossBetween.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.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STCrossBetween; + +public enum AxisCrossBetween { + BETWEEN(STCrossBetween.BETWEEN), + MIDPOINT_CATEGORY(STCrossBetween.MID_CAT); + + final STCrossBetween.Enum underlying; + + AxisCrossBetween(STCrossBetween.Enum crossBetween) { + this.underlying = crossBetween; + } + + private final static HashMap reverse = new HashMap(); + static { + for (AxisCrossBetween value : values()) { + reverse.put(value.underlying, value); + } + } + + static AxisCrossBetween valueOf(STCrossBetween.Enum crossBetween) { + return reverse.get(crossBetween); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisCrosses.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisCrosses.java new file mode 100644 index 0000000000..ff9d32dbb0 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisCrosses.java @@ -0,0 +1,45 @@ +/* ==================================================================== +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STCrosses; + +public enum AxisCrosses { + AUTO_ZERO(STCrosses.AUTO_ZERO), + MAX(STCrosses.MAX), + MIN(STCrosses.MIN); + + final STCrosses.Enum underlying; + + AxisCrosses(STCrosses.Enum crosses) { + this.underlying = crosses; + } + + private final static HashMap reverse = new HashMap(); + static { + for (AxisCrosses value : values()) { + reverse.put(value.underlying, value); + } + } + + static AxisCrosses valueOf(STCrosses.Enum crosses) { + return reverse.get(crosses); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisLabelAlignment.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisLabelAlignment.java new file mode 100644 index 0000000000..dff809cd36 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisLabelAlignment.java @@ -0,0 +1,45 @@ +/* ==================================================================== +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STLblAlgn; + +public enum AxisLabelAlignment { + CENTER(STLblAlgn.CTR), + LEFT(STLblAlgn.L), + RIGHT(STLblAlgn.R); + + final STLblAlgn.Enum underlying; + + AxisLabelAlignment(STLblAlgn.Enum alignment) { + this.underlying = alignment; + } + + private final static HashMap reverse = new HashMap(); + static { + for (AxisLabelAlignment value : values()) { + reverse.put(value.underlying, value); + } + } + + static AxisLabelAlignment valueOf(STLblAlgn.Enum alignment) { + return reverse.get(alignment); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisOrientation.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisOrientation.java new file mode 100644 index 0000000000..ce0ace3fac --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisOrientation.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.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STOrientation; + +public enum AxisOrientation { + MIN_MAX(STOrientation.MIN_MAX), + MAX_MIN(STOrientation.MAX_MIN); + + final STOrientation.Enum underlying; + + AxisOrientation(STOrientation.Enum orientation) { + this.underlying = orientation; + } + + private final static HashMap reverse = new HashMap(); + static { + for (AxisOrientation value : values()) { + reverse.put(value.underlying, value); + } + } + + static AxisOrientation valueOf(STOrientation.Enum orientation) { + return reverse.get(orientation); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisPosition.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisPosition.java new file mode 100644 index 0000000000..de277391ec --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisPosition.java @@ -0,0 +1,46 @@ +/* ==================================================================== +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STAxPos; + +public enum AxisPosition { + BOTTOM(STAxPos.B), + LEFT(STAxPos.L), + RIGHT(STAxPos.R), + TOP(STAxPos.T); + + final STAxPos.Enum underlying; + + AxisPosition(STAxPos.Enum position) { + this.underlying = position; + } + + private final static HashMap reverse = new HashMap(); + static { + for (AxisPosition value : values()) { + reverse.put(value.underlying, value); + } + } + + static AxisPosition valueOf(STAxPos.Enum position) { + return reverse.get(position); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisTickLabelPosition.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisTickLabelPosition.java new file mode 100644 index 0000000000..5e22d2f283 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisTickLabelPosition.java @@ -0,0 +1,46 @@ +/* ==================================================================== +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos; + +public enum AxisTickLabelPosition { + HIGH(STTickLblPos.HIGH), + LOW(STTickLblPos.LOW), + NEXT_TO(STTickLblPos.NEXT_TO), + NONE(STTickLblPos.NONE); + + final STTickLblPos.Enum underlying; + + AxisTickLabelPosition(STTickLblPos.Enum position) { + this.underlying = position; + } + + private final static HashMap reverse = new HashMap(); + static { + for (AxisTickLabelPosition value : values()) { + reverse.put(value.underlying, value); + } + } + + static AxisTickLabelPosition valueOf(STTickLblPos.Enum position) { + return reverse.get(position); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisTickMark.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisTickMark.java new file mode 100644 index 0000000000..f26cf5634c --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/AxisTickMark.java @@ -0,0 +1,46 @@ +/* ==================================================================== +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STTickMark; + +public enum AxisTickMark { + CROSS(STTickMark.CROSS), + IN(STTickMark.IN), + NONE(STTickMark.NONE), + OUT(STTickMark.OUT); + + final STTickMark.Enum underlying; + + AxisTickMark(STTickMark.Enum tickMark) { + this.underlying = tickMark; + } + + private final static HashMap reverse = new HashMap(); + static { + for (AxisTickMark value : values()) { + reverse.put(value.underlying, value); + } + } + + static AxisTickMark valueOf(STTickMark.Enum tickMark) { + return reverse.get(tickMark); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/BarDirection.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/BarDirection.java new file mode 100644 index 0000000000..027196795f --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/BarDirection.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.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STBarDir; + +public enum BarDirection { + BAR(STBarDir.BAR), + COL(STBarDir.COL); + + final STBarDir.Enum underlying; + + BarDirection(STBarDir.Enum direction) { + this.underlying = direction; + } + + private final static HashMap reverse = new HashMap(); + static { + for (BarDirection value : values()) { + reverse.put(value.underlying, value); + } + } + + static BarDirection valueOf(STBarDir.Enum direction) { + return reverse.get(direction); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/BarGrouping.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/BarGrouping.java new file mode 100644 index 0000000000..ce8615eb1d --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/BarGrouping.java @@ -0,0 +1,46 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STBarGrouping; + +public enum BarGrouping { + STANDARD(STBarGrouping.STANDARD), + CLUSTERED(STBarGrouping.CLUSTERED), + STACKED(STBarGrouping.STACKED), + PERCENT_STACKED(STBarGrouping.PERCENT_STACKED); + + final STBarGrouping.Enum underlying; + + BarGrouping(STBarGrouping.Enum grouping) { + this.underlying = grouping; + } + + private final static HashMap reverse = new HashMap(); + static { + for (BarGrouping value : values()) { + reverse.put(value.underlying, value); + } + } + + static BarGrouping valueOf(STBarGrouping.Enum grouping) { + return reverse.get(grouping); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/ChartTypes.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/ChartTypes.java new file mode 100644 index 0000000000..9dbec09aaa --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/ChartTypes.java @@ -0,0 +1,25 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.xddf.usermodel.chart; + +public enum ChartTypes { + BAR, + LINE, + PIE, + RADAR, + SCATTER; +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/Grouping.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/Grouping.java new file mode 100644 index 0000000000..9549c8755d --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/Grouping.java @@ -0,0 +1,45 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STGrouping; + +public enum Grouping { + STANDARD(STGrouping.STANDARD), + STACKED(STGrouping.STACKED), + PERCENT_STACKED(STGrouping.PERCENT_STACKED); + + final STGrouping.Enum underlying; + + Grouping(STGrouping.Enum grouping) { + this.underlying = grouping; + } + + private final static HashMap reverse = new HashMap(); + static { + for (Grouping value : values()) { + reverse.put(value.underlying, value); + } + } + + static Grouping valueOf(STGrouping.Enum grouping) { + return reverse.get(grouping); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/LayoutMode.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/LayoutMode.java new file mode 100644 index 0000000000..398d71b3c8 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/LayoutMode.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.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutMode;; + +public enum LayoutMode { + EDGE(STLayoutMode.EDGE), + FACTOR(STLayoutMode.FACTOR); + + final STLayoutMode.Enum underlying; + + LayoutMode(STLayoutMode.Enum layoutMode) { + this.underlying = layoutMode; + } + + private final static HashMap reverse = new HashMap(); + static { + for (LayoutMode value : values()) { + reverse.put(value.underlying, value); + } + } + + static LayoutMode valueOf(STLayoutMode.Enum layoutMode) { + return reverse.get(layoutMode); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/LayoutTarget.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/LayoutTarget.java new file mode 100644 index 0000000000..b4ba3513c0 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/LayoutTarget.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.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget;; + +public enum LayoutTarget { + INNER(STLayoutTarget.INNER), + OUTER(STLayoutTarget.OUTER); + + final STLayoutTarget.Enum underlying; + + LayoutTarget(STLayoutTarget.Enum layoutTarget) { + this.underlying = layoutTarget; + } + + private final static HashMap reverse = new HashMap(); + static { + for (LayoutTarget value : values()) { + reverse.put(value.underlying, value); + } + } + + static LayoutTarget valueOf(STLayoutTarget.Enum layoutTarget) { + return reverse.get(layoutTarget); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/LegendPosition.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/LegendPosition.java new file mode 100644 index 0000000000..062a880044 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/LegendPosition.java @@ -0,0 +1,47 @@ +/* ==================================================================== +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STLegendPos; + +public enum LegendPosition { + BOTTOM(STLegendPos.B), + LEFT(STLegendPos.L), + RIGHT(STLegendPos.R), + TOP(STLegendPos.T), + TOP_RIGHT(STLegendPos.TR); + + final STLegendPos.Enum underlying; + + LegendPosition(STLegendPos.Enum position) { + this.underlying = position; + } + + private final static HashMap reverse = new HashMap(); + static { + for (LegendPosition value : values()) { + reverse.put(value.underlying, value); + } + } + + static LegendPosition valueOf(STLegendPos.Enum position) { + return reverse.get(position); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/MarkerStyle.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/MarkerStyle.java new file mode 100644 index 0000000000..4613fb460e --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/MarkerStyle.java @@ -0,0 +1,53 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STMarkerStyle; + +public enum MarkerStyle { + CIRCLE(STMarkerStyle.CIRCLE), + DASH(STMarkerStyle.DASH), + DIAMOND(STMarkerStyle.DIAMOND), + DOT(STMarkerStyle.DOT), + NONE(STMarkerStyle.NONE), + PICTURE(STMarkerStyle.PICTURE), + PLUS(STMarkerStyle.PLUS), + SQUARE(STMarkerStyle.SQUARE), + STAR(STMarkerStyle.STAR), + TRIANGLE(STMarkerStyle.TRIANGLE), + X(STMarkerStyle.X); + + final STMarkerStyle.Enum underlying; + + MarkerStyle(STMarkerStyle.Enum style) { + this.underlying = style; + } + + private final static HashMap reverse = new HashMap(); + static { + for (MarkerStyle value : values()) { + reverse.put(value.underlying, value); + } + } + + static MarkerStyle valueOf(STMarkerStyle.Enum style) { + return reverse.get(style); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/RadarStyle.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/RadarStyle.java new file mode 100644 index 0000000000..8cb7491ad5 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/RadarStyle.java @@ -0,0 +1,45 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STRadarStyle; + +public enum RadarStyle { + FILLED(STRadarStyle.FILLED), + MARKER(STRadarStyle.MARKER), + STANDARD(STRadarStyle.STANDARD); + + final STRadarStyle.Enum underlying; + + RadarStyle(STRadarStyle.Enum style) { + this.underlying = style; + } + + private final static HashMap reverse = new HashMap(); + static { + for (RadarStyle value : values()) { + reverse.put(value.underlying, value); + } + } + + static RadarStyle valueOf(STRadarStyle.Enum style) { + return reverse.get(style); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/ScatterStyle.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/ScatterStyle.java new file mode 100644 index 0000000000..139bb7d0e4 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/ScatterStyle.java @@ -0,0 +1,48 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.HashMap; + +import org.openxmlformats.schemas.drawingml.x2006.chart.STScatterStyle; + +public enum ScatterStyle { + LINE(STScatterStyle.LINE), + LINE_MARKER(STScatterStyle.LINE_MARKER), + MARKER(STScatterStyle.MARKER), + NONE(STScatterStyle.NONE), + SMOOTH(STScatterStyle.SMOOTH), + SMOOTH_MARKER(STScatterStyle.SMOOTH_MARKER); + + final STScatterStyle.Enum underlying; + + ScatterStyle(STScatterStyle.Enum style) { + this.underlying = style; + } + + private final static HashMap reverse = new HashMap(); + static { + for (ScatterStyle value : values()) { + reverse.put(value.underlying, value); + } + } + + static ScatterStyle valueOf(STScatterStyle.Enum style) { + return reverse.get(style); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFBarChartData.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFBarChartData.java new file mode 100644 index 0000000000..e89ec321d0 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFBarChartData.java @@ -0,0 +1,146 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.Map; + +import org.apache.poi.util.Beta; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarSer; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; + +@Beta +public class XDDFBarChartData extends XDDFChartData { + private CTBarChart chart; + + public XDDFBarChartData(CTBarChart chart, Map categories, + Map values) { + this.chart = chart; + for (CTBarSer series : chart.getSerList()) { + this.series.add(new Series(series, series.getCat(), series.getVal())); + } + defineAxes(chart.getAxIdArray(), categories, values); + } + + @Override + public void setVaryColors(boolean varyColors) { + if (chart.isSetVaryColors()) { + chart.getVaryColors().setVal(varyColors); + } else { + chart.addNewVaryColors().setVal(varyColors); + } + } + + public BarDirection getBarDirection() { + return BarDirection.valueOf(chart.getBarDir().getVal()); + } + + public void setBarDirection(BarDirection direction) { + chart.getBarDir().setVal(direction.underlying); + } + + public BarGrouping getBarGrouping() { + if (chart.isSetGrouping()) { + return BarGrouping.valueOf(chart.getGrouping().getVal()); + } else { + return BarGrouping.STANDARD; + } + } + + public void setBarGrouping(BarGrouping grouping) { + if (chart.isSetGrouping()) { + chart.getGrouping().setVal(grouping.underlying); + } else { + chart.addNewGrouping().setVal(grouping.underlying); + } + } + + public int getGapWidth() { + if (chart.isSetGapWidth()) { + return chart.getGapWidth().getVal(); + } else { + return 0; + } + } + + public void setGapWidth(int width) { + if (chart.isSetGapWidth()) { + chart.getGapWidth().setVal(width); + } else { + chart.addNewGapWidth().setVal(width); + } + } + + @Override + public XDDFChartData.Series addSeries(XDDFDataSource category, + XDDFNumericalDataSource values) { + final int index = this.series.size(); + final CTBarSer ctSer = this.chart.addNewSer(); + ctSer.addNewCat(); + ctSer.addNewVal(); + ctSer.addNewIdx().setVal(index); + ctSer.addNewOrder().setVal(index); + final Series added = new Series(ctSer, category, values); + this.series.add(added); + return added; + } + + public class Series extends XDDFChartData.Series { + private CTBarSer series; + + protected Series(CTBarSer series, XDDFDataSource category, + XDDFNumericalDataSource values) { + super(category, values); + this.series = series; + } + + protected Series(CTBarSer series, CTAxDataSource category, CTNumDataSource values) { + super(XDDFDataSourcesFactory.fromDataSource(category), XDDFDataSourcesFactory.fromDataSource(values)); + this.series = series; + } + + @Override + protected CTSerTx getSeriesText() { + return series.getTx(); + } + + @Override + public void setShowLeaderLines(boolean showLeaderLines) { + if (!series.isSetDLbls()) { + series.addNewDLbls(); + } + if (series.getDLbls().isSetShowLeaderLines()) { + series.getDLbls().getShowLeaderLines().setVal(showLeaderLines); + } else { + series.getDLbls().addNewShowLeaderLines().setVal(showLeaderLines); + } + } + + @Override + protected CTAxDataSource getAxDS() { + return series.getCat(); + } + + @Override + protected CTNumDataSource getNumDS() { + return series.getVal(); + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFCategoryAxis.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFCategoryAxis.java new file mode 100644 index 0000000000..2744d8b203 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFCategoryAxis.java @@ -0,0 +1,151 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean; +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.CTPlotArea; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTScaling; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTTickMark; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTUnsignedInt; +import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos; +import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; + +@Beta +public class XDDFCategoryAxis extends XDDFChartAxis { + + private CTCatAx ctCatAx; + + public XDDFCategoryAxis(CTPlotArea plotArea, AxisPosition position) { + initializeAxis(plotArea, position); + } + + public XDDFCategoryAxis(CTCatAx ctCatAx) { + this.ctCatAx = ctCatAx; + } + + @Override + @Internal + public CTShapeProperties getMajorGridLines() { + if (!ctCatAx.isSetMajorGridlines()) { + ctCatAx.addNewMajorGridlines(); + } + if (!ctCatAx.getMajorGridlines().isSetSpPr()) { + ctCatAx.getMajorGridlines().addNewSpPr(); + } + return ctCatAx.getMajorGridlines().getSpPr(); + } + + @Override + @Internal + public CTShapeProperties getLine() { + return ctCatAx.getSpPr(); + } + + @Override + public void crossAxis(XDDFChartAxis axis) { + ctCatAx.getCrossAx().setVal(axis.getId()); + } + + @Override + protected CTUnsignedInt getCTAxId() { + return ctCatAx.getAxId(); + } + + @Override + protected CTAxPos getCTAxPos() { + return ctCatAx.getAxPos(); + } + + @Override + public boolean hasNumberFormat() { + return ctCatAx.isSetNumFmt(); + } + + @Override + protected CTNumFmt getCTNumFmt() { + if (ctCatAx.isSetNumFmt()) { + return ctCatAx.getNumFmt(); + } + return ctCatAx.addNewNumFmt(); + } + + @Override + protected CTScaling getCTScaling() { + return ctCatAx.getScaling(); + } + + @Override + protected CTCrosses getCTCrosses() { + CTCrosses crosses = ctCatAx.getCrosses(); + if (crosses == null) { + return ctCatAx.addNewCrosses(); + } else { + return crosses; + } + } + + @Override + protected CTBoolean getDelete() { + return ctCatAx.getDelete(); + } + + @Override + protected CTTickMark getMajorCTTickMark() { + return ctCatAx.getMajorTickMark(); + } + + @Override + protected CTTickMark getMinorCTTickMark() { + return ctCatAx.getMinorTickMark(); + } + + public AxisLabelAlignment getLabelAlignment() { + return AxisLabelAlignment.valueOf(ctCatAx.getLblAlgn().getVal()); + } + + public void setLabelAlignment(AxisLabelAlignment labelAlignment) { + ctCatAx.getLblAlgn().setVal(labelAlignment.underlying); + } + + private void initializeAxis(CTPlotArea plotArea, AxisPosition position) { + final long id = getNextAxId(plotArea); + ctCatAx = plotArea.addNewCatAx(); + ctCatAx.addNewAxId().setVal(id); + ctCatAx.addNewAxPos(); + ctCatAx.addNewScaling(); + ctCatAx.addNewCrosses(); + ctCatAx.addNewCrossAx(); + ctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO); + ctCatAx.addNewDelete(); + ctCatAx.addNewMajorTickMark(); + ctCatAx.addNewMinorTickMark(); + + setPosition(position); + 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/xddf/usermodel/chart/XDDFCategoryDataSource.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFCategoryDataSource.java new file mode 100644 index 0000000000..a65db84097 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFCategoryDataSource.java @@ -0,0 +1,26 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.apache.poi.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; + +@Beta +public interface XDDFCategoryDataSource extends XDDFDataSource { +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChart.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChart.java new file mode 100644 index 0000000000..92f146e2b2 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChart.java @@ -0,0 +1,331 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.apache.poi.xddf.usermodel.chart; + +import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.apache.xmlbeans.XmlException; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTDateAx; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTRadarChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTSurface; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx; +import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument; + +@Beta +public abstract class XDDFChart extends POIXMLDocumentPart { + + protected List axes = new ArrayList<>(); + + /** + * Root element of the Chart part + */ + protected final CTChartSpace chartSpace; + + /** + * Chart element in the chart space + */ + protected final CTChart chart; + + /** + * Construct a chart. + */ + protected XDDFChart() { + super(); + + chartSpace = CTChartSpace.Factory.newInstance(); + chart = chartSpace.addNewChart(); + chart.addNewPlotArea(); + } + + /** + * Construct a DrawingML 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 + * + * @since POI 3.14-Beta1 + */ + protected XDDFChart(PackagePart part) throws IOException, XmlException { + super(part); + + chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream(), DEFAULT_XML_OPTIONS).getChartSpace(); + chart = chartSpace.getChart(); + } + + /** + * Return the underlying CTChartSpace bean, the root element of the 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; + + } + + /** + * Return the underlying CTPlotArea bean, within the Chart + * + * @return the underlying CTPlotArea bean + */ + @Internal + protected CTPlotArea getCTPlotArea() { + return chart.getPlotArea(); + } + + /** + * @return true if only visible cells will be present on the chart, + * false otherwise + */ + public boolean isPlotOnlyVisibleCells() { + if (chart.isSetPlotVisOnly()) { + return chart.getPlotVisOnly().getVal(); + } else { + return false; + } + } + + /** + * @param only a flag specifying if only visible cells should be + * present on the chart + */ + public void setPlotOnlyVisibleCells(boolean only) { + if (!chart.isSetPlotVisOnly()) { + chart.setPlotVisOnly(CTBoolean.Factory.newInstance()); + } + chart.getPlotVisOnly().setVal(only); + } + + public void setFloor(int thickness) { + if (!chart.isSetFloor()) { + chart.setFloor(CTSurface.Factory.newInstance()); + } + chart.getFloor().getThickness().setVal(thickness); + } + + public void setBackWall(int thickness) { + if (!chart.isSetBackWall()) { + chart.setBackWall(CTSurface.Factory.newInstance()); + } + chart.getBackWall().getThickness().setVal(thickness); + } + + public void setSideWall(int thickness) { + if (!chart.isSetSideWall()) { + chart.setSideWall(CTSurface.Factory.newInstance()); + } + chart.getSideWall().getThickness().setVal(thickness); + } + + public void setAutoTitleDeleted(boolean deleted) { + if (!chart.isSetAutoTitleDeleted()) { + chart.setAutoTitleDeleted(CTBoolean.Factory.newInstance()); + } + chart.getAutoTitleDeleted().setVal(deleted); + } + + public XDDFChartLegend getOrAddLegend() { + return new XDDFChartLegend(chart); + } + + public void deleteLegend() { + if (chart.isSetLegend()) { + chart.unsetLegend(); + } + } + + public XDDFManualLayout getOrAddManualLayout() { + return new XDDFManualLayout(chart.getPlotArea()); + } + + public void plot(XDDFChartData data) { + for (XDDFChartData.Series series : data.getSeries()) { + series.plot(); + } + } + + public List getChartSeries() { + List series = new LinkedList<>(); + CTPlotArea plotArea = getCTPlotArea(); + Map categories = getCategoryAxes(); + Map values = getValueAxes(); + + for (int i = 0; i < plotArea.sizeOfBarChartArray(); i++) { + CTBarChart barChart = plotArea.getBarChartArray(i); + series.add(new XDDFBarChartData(barChart, categories, values)); + } + + for (int i = 0; i < plotArea.sizeOfLineChartArray(); i++) { + CTLineChart lineChart = plotArea.getLineChartArray(i); + series.add(new XDDFLineChartData(lineChart, categories, values)); + } + + for (int i = 0; i < plotArea.sizeOfPieChartArray(); i++) { + CTPieChart pieChart = plotArea.getPieChartArray(i); + series.add(new XDDFPieChartData(pieChart)); + } + + for (int i = 0; i < plotArea.sizeOfRadarChartArray(); i++) { + CTRadarChart radarChart = plotArea.getRadarChartArray(i); + series.add(new XDDFRadarChartData(radarChart, categories, values)); + } + + for (int i = 0; i < plotArea.sizeOfScatterChartArray(); i++) { + CTScatterChart scatterChart = plotArea.getScatterChartArray(i); + series.add(new XDDFScatterChartData(scatterChart, categories, values)); + } + + // TODO repeat above code for all kind of charts + return series; + } + + private Map getCategoryAxes() { + CTPlotArea plotArea = getCTPlotArea(); + int sizeOfArray = plotArea.sizeOfCatAxArray(); + Map axes = new HashMap(sizeOfArray); + for (int i = 0; i < sizeOfArray; i++) { + CTCatAx category = plotArea.getCatAxArray(i); + axes.put(category.getAxId().getVal(), new XDDFCategoryAxis(category)); + } + return axes; + } + + private Map getValueAxes() { + CTPlotArea plotArea = getCTPlotArea(); + int sizeOfArray = plotArea.sizeOfValAxArray(); + Map axes = new HashMap<>(sizeOfArray); + for (int i = 0; i < sizeOfArray; i++) { + CTValAx values = plotArea.getValAxArray(i); + axes.put(values.getAxId().getVal(), new XDDFValueAxis(values)); + } + return axes; + } + + public XDDFValueAxis createValueAxis(AxisPosition pos) { + XDDFValueAxis valueAxis = new XDDFValueAxis(chart.getPlotArea(), pos); + if (axes.size() == 1) { + XDDFChartAxis axis = axes.get(0); + axis.crossAxis(valueAxis); + valueAxis.crossAxis(axis); + } + axes.add(valueAxis); + return valueAxis; + } + + public XDDFCategoryAxis createCategoryAxis(AxisPosition pos) { + XDDFCategoryAxis categoryAxis = new XDDFCategoryAxis(chart.getPlotArea(), pos); + if (axes.size() == 1) { + XDDFChartAxis axis = axes.get(0); + axis.crossAxis(categoryAxis); + categoryAxis.crossAxis(axis); + } + axes.add(categoryAxis); + return categoryAxis; + } + + public XDDFDateAxis createDateAxis(AxisPosition pos) { + XDDFDateAxis dateAxis = new XDDFDateAxis(chart.getPlotArea(), pos); + if (axes.size() == 1) { + XDDFChartAxis axis = axes.get(0); + axis.crossAxis(dateAxis); + dateAxis.crossAxis(axis); + } + axes.add(dateAxis); + return dateAxis; + } + + public XDDFChartData createData(ChartTypes type, XDDFChartAxis category, XDDFValueAxis values) { + Map categories = Collections.singletonMap(category.getId(), category); + Map mapValues = Collections.singletonMap(values.getId(), values); + final CTPlotArea plotArea = getCTPlotArea(); + switch (type) { + case BAR: + return new XDDFBarChartData(plotArea.addNewBarChart(), categories, mapValues); + case LINE: + return new XDDFLineChartData(plotArea.addNewLineChart(), categories, mapValues); + case PIE: + return new XDDFPieChartData(plotArea.addNewPieChart()); + case RADAR: + return new XDDFRadarChartData(plotArea.addNewRadarChart(), categories, mapValues); + case SCATTER: + return new XDDFScatterChartData(plotArea.addNewScatterChart(), categories, mapValues); + default: + return null; + } + } + + public List getAxes() { + if (axes.isEmpty() && hasAxes()) { + parseAxes(); + } + return axes; + } + + private boolean hasAxes() { + CTPlotArea ctPlotArea = chart.getPlotArea(); + int totalAxisCount = ctPlotArea.sizeOfValAxArray() + ctPlotArea.sizeOfCatAxArray() + ctPlotArea.sizeOfDateAxArray() + ctPlotArea.sizeOfSerAxArray(); + return totalAxisCount > 0; + } + + private void parseAxes() { + // TODO: add other axis types + for (CTCatAx catAx : chart.getPlotArea().getCatAxArray()) { + axes.add(new XDDFCategoryAxis(catAx)); + } + for (CTDateAx dateAx : chart.getPlotArea().getDateAxArray()) { + axes.add(new XDDFDateAxis(dateAx)); + } + for (CTValAx valAx : chart.getPlotArea().getValAxArray()) { + axes.add(new XDDFValueAxis(valAx)); + } + } + +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartAxis.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartAxis.java new file mode 100644 index 0000000000..3279d2b3c2 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartAxis.java @@ -0,0 +1,302 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTCrosses; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTLogBase; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumFmt; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTScaling; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTTickMark; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTUnsignedInt; +import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; + +/** + * Base class for all axis types. + */ +@Beta +public abstract class XDDFChartAxis { + protected abstract CTUnsignedInt getCTAxId(); + + 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(); + + @Internal + public abstract CTShapeProperties getMajorGridLines(); + + @Internal + public abstract CTShapeProperties getLine(); + + /** + * @return axis id + */ + public long getId() { + return getCTAxId().getVal(); + } + + /** + * @return axis position + */ + public AxisPosition getPosition() { + return AxisPosition.valueOf(getCTAxPos().getVal()); + } + + /** + * @param position + * new axis position + */ + public void setPosition(AxisPosition position) { + getCTAxPos().setVal(position.underlying); + } + + /** + * Use this to check before retrieving a number format, as calling {@link #getNumberFormat()} may create a default + * one if none exists. + * + * @return true if a number format element is defined, false if not + */ + public abstract boolean hasNumberFormat(); + + /** + * @param format + * axis number format + */ + public void setNumberFormat(String format) { + getCTNumFmt().setFormatCode(format); + getCTNumFmt().setSourceLinked(true); + } + + /** + * @return axis number format + */ + public String getNumberFormat() { + return getCTNumFmt().getFormatCode(); + } + + /** + * @return true if log base is defined, false otherwise + */ + public boolean isSetLogBase() { + return getCTScaling().isSetLogBase(); + } + + private static final double MIN_LOG_BASE = 2.0; + private static final double MAX_LOG_BASE = 1000.0; + + /** + * @param logBase + * a number between 2 and 1000 (inclusive) + * @throws IllegalArgumentException + * if log base not within allowed range + */ + 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); + } + } + + /** + * @return axis log base or 0.0 if not set + */ + public double getLogBase() { + CTLogBase logBase = getCTScaling().getLogBase(); + if (logBase != null) { + return logBase.getVal(); + } + return 0.0; + } + + /** + * @return true if minimum value is defined, false otherwise + */ + public boolean isSetMinimum() { + return getCTScaling().isSetMin(); + } + + /** + * @param min + * axis minimum + */ + public void setMinimum(double min) { + CTScaling scaling = getCTScaling(); + if (scaling.isSetMin()) { + scaling.getMin().setVal(min); + } else { + scaling.addNewMin().setVal(min); + } + } + + /** + * @return axis minimum or 0.0 if not set + */ + public double getMinimum() { + CTScaling scaling = getCTScaling(); + if (scaling.isSetMin()) { + return scaling.getMin().getVal(); + } else { + return 0.0; + } + } + + /** + * @return true if maximum value is defined, false otherwise + */ + public boolean isSetMaximum() { + return getCTScaling().isSetMax(); + } + + /** + * @param max + * axis maximum + */ + public void setMaximum(double max) { + CTScaling scaling = getCTScaling(); + if (scaling.isSetMax()) { + scaling.getMax().setVal(max); + } else { + scaling.addNewMax().setVal(max); + } + } + + /** + * @return axis maximum or 0.0 if not set + */ + public double getMaximum() { + CTScaling scaling = getCTScaling(); + if (scaling.isSetMax()) { + return scaling.getMax().getVal(); + } else { + return 0.0; + } + } + + /** + * @return axis orientation + */ + public AxisOrientation getOrientation() { + return AxisOrientation.valueOf(getCTScaling().getOrientation().getVal()); + } + + /** + * @param orientation + * axis orientation + */ + public void setOrientation(AxisOrientation orientation) { + CTScaling scaling = getCTScaling(); + if (scaling.isSetOrientation()) { + scaling.getOrientation().setVal(orientation.underlying); + } else { + scaling.addNewOrientation().setVal(orientation.underlying); + } + } + + /** + * @return axis cross type + */ + public AxisCrosses getCrosses() { + return AxisCrosses.valueOf(getCTCrosses().getVal()); + } + + /** + * @param crosses + * axis cross type + */ + public void setCrosses(AxisCrosses crosses) { + getCTCrosses().setVal(crosses.underlying); + } + + /** + * Declare this axis cross another axis. + * + * @param axis + * that this axis should cross + */ + public abstract void crossAxis(XDDFChartAxis axis); + + /** + * @return visibility of the axis. + */ + public boolean isVisible() { + return !getDelete().getVal(); + } + + /** + * @param value + * visibility of the axis. + */ + public void setVisible(boolean value) { + getDelete().setVal(!value); + } + + /** + * @return major tick mark. + */ + public AxisTickMark getMajorTickMark() { + return AxisTickMark.valueOf(getMajorCTTickMark().getVal()); + } + + /** + * @param tickMark + * major tick mark type. + */ + public void setMajorTickMark(AxisTickMark tickMark) { + getMajorCTTickMark().setVal(tickMark.underlying); + } + + /** + * @return minor tick mark. + */ + public AxisTickMark getMinorTickMark() { + return AxisTickMark.valueOf(getMinorCTTickMark().getVal()); + } + + /** + * @param tickMark + * minor tick mark type. + */ + public void setMinorTickMark(AxisTickMark tickMark) { + getMinorCTTickMark().setVal(tickMark.underlying); + } + + protected long getNextAxId(CTPlotArea plotArea) { + long totalAxisCount = plotArea.sizeOfValAxArray() + plotArea.sizeOfCatAxArray() + plotArea.sizeOfDateAxArray() + + plotArea.sizeOfSerAxArray(); + return totalAxisCount; + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartData.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartData.java new file mode 100644 index 0000000000..66f4c9b555 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartData.java @@ -0,0 +1,291 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.poi.ss.util.CellReference; +import org.apache.poi.util.Beta; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumVal; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrRef; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrVal; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTUnsignedInt; + +/** + * Base of all XDDF Chart Data + */ +@Beta +public abstract class XDDFChartData { + protected List series; + private XDDFCategoryAxis categoryAxis; + private List valueAxes; + + protected XDDFChartData() { + this.series = new ArrayList(); + } + + protected void defineAxes(CTUnsignedInt[] axes, Map categories, + Map values) { + List list = new ArrayList(axes.length); + for (CTUnsignedInt axe : axes) { + Long axisId = axe.getVal(); + XDDFChartAxis category = categories.get(axisId); + if (category == null) { + XDDFValueAxis axis = values.get(axisId); + if (axis != null) { + list.add(axis); + } + } else if (category instanceof XDDFCategoryAxis) { + this.categoryAxis = (XDDFCategoryAxis) category; + } + } + this.valueAxes = Collections.unmodifiableList(list); + } + + public XDDFCategoryAxis getCategoryAxis() { + return categoryAxis; + } + + public List getValueAxes() { + return valueAxes; + } + + public List getSeries() { + return series; + } + + public abstract void setVaryColors(boolean varyColors); + + public abstract XDDFChartData.Series addSeries(XDDFDataSource category, + XDDFNumericalDataSource values); + + public abstract class Series { + protected abstract CTSerTx getSeriesText(); + + public abstract void setShowLeaderLines(boolean showLeaderLines); + + protected XDDFDataSource categoryData; + protected XDDFNumericalDataSource valuesData; + + protected abstract CTAxDataSource getAxDS(); + + protected abstract CTNumDataSource getNumDS(); + + protected Series(XDDFDataSource category, XDDFNumericalDataSource values) { + replaceData(category, values); + } + + public void replaceData(XDDFDataSource category, XDDFNumericalDataSource values) { + if (category == null || values == null) { + throw new IllegalStateException("Category and values must be defined before filling chart data."); + } + int numOfPoints = category.getPointCount(); + if (numOfPoints != values.getPointCount()) { + throw new IllegalStateException("Category and values must have the same point count."); + } + this.categoryData = category; + this.valuesData = values; + } + + public void setTitle(String title, CellReference titleRef) { + if (titleRef == null) { + getSeriesText().setV(title); + } else { + CTStrRef ref; + if (getSeriesText().isSetStrRef()) { + ref = getSeriesText().getStrRef(); + } else { + ref = getSeriesText().addNewStrRef(); + } + CTStrData cache; + if (ref.isSetStrCache()) { + cache = ref.getStrCache(); + } else { + cache = ref.addNewStrCache(); + } + cache.getPtArray(0).setV(title); + ref.setF(titleRef.formatAsString()); + } + } + + public XDDFDataSource getCategoryData() { + return categoryData; + } + + public XDDFNumericalDataSource getValuesData() { + return valuesData; + } + + public void plot() { + int numOfPoints = categoryData.getPointCount(); + if (categoryData.isNumeric()) { + CTNumData cache = retrieveNumCache(getAxDS(), categoryData); + fillNumCache(cache, numOfPoints, (XDDFNumericalDataSource) categoryData); + } else { + CTStrData cache = retrieveStrCache(getAxDS(), categoryData); + fillStringCache(cache, numOfPoints, categoryData); + } + CTNumData cache = retrieveNumCache(getNumDS(), valuesData); + fillNumCache(cache, numOfPoints, valuesData); + } + + private CTNumData retrieveNumCache(final CTAxDataSource axDataSource, XDDFDataSource data) { + CTNumData numCache; + if (data.isReference()) { + CTNumRef numRef; + if (axDataSource.isSetNumRef()) { + numRef = axDataSource.getNumRef(); + } else { + numRef = axDataSource.addNewNumRef(); + } + if (numRef.isSetNumCache()) { + numCache = numRef.getNumCache(); + } else { + numCache = numRef.addNewNumCache(); + } + numRef.setF(data.getDataRangeReference()); + if (axDataSource.isSetNumLit()) { + axDataSource.unsetNumLit(); + } + } else { + if (axDataSource.isSetNumLit()) { + numCache = axDataSource.getNumLit(); + } else { + numCache = axDataSource.addNewNumLit(); + } + if (axDataSource.isSetNumRef()) { + axDataSource.unsetNumRef(); + } + } + return numCache; + } + + private CTStrData retrieveStrCache(final CTAxDataSource axDataSource, XDDFDataSource data) { + CTStrData strCache; + if (data.isReference()) { + CTStrRef strRef; + if (axDataSource.isSetStrRef()) { + strRef = axDataSource.getStrRef(); + } else { + strRef = axDataSource.addNewStrRef(); + } + if (strRef.isSetStrCache()) { + strCache = strRef.getStrCache(); + } else { + strCache = strRef.addNewStrCache(); + } + strRef.setF(data.getDataRangeReference()); + if (axDataSource.isSetStrLit()) { + axDataSource.unsetStrLit(); + } + } else { + if (axDataSource.isSetStrLit()) { + strCache = axDataSource.getStrLit(); + } else { + strCache = axDataSource.addNewStrLit(); + } + if (axDataSource.isSetStrRef()) { + axDataSource.unsetStrRef(); + } + } + return strCache; + } + + private CTNumData retrieveNumCache(final CTNumDataSource numDataSource, XDDFDataSource data) { + CTNumData numCache; + if (data.isReference()) { + CTNumRef numRef; + if (numDataSource.isSetNumRef()) { + numRef = numDataSource.getNumRef(); + } else { + numRef = numDataSource.addNewNumRef(); + } + if (numRef.isSetNumCache()) { + numCache = numRef.getNumCache(); + } else { + numCache = numRef.addNewNumCache(); + } + numRef.setF(data.getDataRangeReference()); + if (numDataSource.isSetNumLit()) { + numDataSource.unsetNumLit(); + } + } else { + if (numDataSource.isSetNumLit()) { + numCache = numDataSource.getNumLit(); + } else { + numCache = numDataSource.addNewNumLit(); + } + if (numDataSource.isSetNumRef()) { + numDataSource.unsetNumRef(); + } + } + return numCache; + } + + private void fillStringCache(CTStrData cache, int numOfPoints, XDDFDataSource data) { + cache.setPtArray(null); // unset old values + if (cache.isSetPtCount()) { + cache.getPtCount().setVal(numOfPoints); + } else { + cache.addNewPtCount().setVal(numOfPoints); + } + for (int i = 0; i < numOfPoints; ++i) { + String value = data.getPointAt(i).toString(); + if (value != null) { + CTStrVal ctStrVal = cache.addNewPt(); + ctStrVal.setIdx(i); + ctStrVal.setV(value); + } + } + } + + private void fillNumCache(CTNumData cache, int numOfPoints, XDDFNumericalDataSource data) { + String formatCode = data.getFormatCode(); + if (formatCode == null) { + if (cache.isSetFormatCode()) { + cache.unsetFormatCode(); + } + } else { + cache.setFormatCode(formatCode); + } + cache.setPtArray(null); // unset old values + if (cache.isSetPtCount()) { + cache.getPtCount().setVal(numOfPoints); + } else { + cache.addNewPtCount().setVal(numOfPoints); + } + for (int i = 0; i < numOfPoints; ++i) { + Object value = data.getPointAt(i); + if (value != null) { + CTNumVal ctNumVal = cache.addNewPt(); + ctNumVal.setIdx(i); + ctNumVal.setV(value.toString()); + } + } + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartExtensionList.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartExtensionList.java new file mode 100644 index 0000000000..9e593edfbb --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartExtensionList.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.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTExtensionList; + +@Beta +public class XDDFChartExtensionList { + private CTExtensionList list; + + public XDDFChartExtensionList() { + this(CTExtensionList.Factory.newInstance()); + } + + @Internal + protected XDDFChartExtensionList(CTExtensionList list) { + this.list = list; + } + + @Internal + public CTExtensionList getXmlObject() { + return list; + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartLegend.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartLegend.java new file mode 100644 index 0000000000..75db5ebbd4 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChartLegend.java @@ -0,0 +1,184 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.apache.poi.xddf.usermodel.text.XDDFTextBody; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTLegend; +import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; + +/** + * Represents a DrawingML chart legend + */ +@Beta +public final class XDDFChartLegend { + + /** + * Underlying CTLegend bean + */ + private CTLegend legend; + + /** + * Create a new DrawingML chart legend + */ + public XDDFChartLegend(CTChart ctChart) { + this.legend = (ctChart.isSetLegend()) ? ctChart.getLegend() : ctChart.addNewLegend(); + + setDefaults(); + } + + /** + * Set sensible default styling. + */ + private void setDefaults() { + if (!legend.isSetOverlay()) { + legend.addNewOverlay(); + } + legend.getOverlay().setVal(false); + } + + /** + * Return the underlying CTLegend bean. + * + * @return the underlying CTLegend bean + */ + @Internal + protected CTLegend getXmlObject() { + return legend; + } + + @Internal // will later replace with XDDFShapeProperties + public CTShapeProperties getShapeProperties() { + if (legend.isSetSpPr()) { + return legend.getSpPr(); + } else { + return null; + } + } + + @Internal // will later replace with XDDFShapeProperties + public void setShapeProperties(CTShapeProperties properties) { + if (properties == null) { + legend.unsetSpPr(); + } else { + legend.setSpPr(properties); + } + } + + public XDDFTextBody getTextBody() { + if (legend.isSetTxPr()) { + return new XDDFTextBody(legend.getTxPr()); + } else { + return null; + } + } + + public void setTextBody(XDDFTextBody body) { + if (body == null) { + legend.unsetTxPr(); + } else { + legend.setTxPr(body.getXmlObject()); + } + } + + public XDDFLegendEntry addEntry() { + return new XDDFLegendEntry(legend.addNewLegendEntry()); + } + + public XDDFLegendEntry getEntry(int index) { + return new XDDFLegendEntry(legend.getLegendEntryArray(index)); + } + + public List getEntries() { + return legend + .getLegendEntryList() + .stream() + .map(entry -> new XDDFLegendEntry(entry)) + .collect(Collectors.toList()); + } + + public void setExtensionList(XDDFChartExtensionList list) { + if (list == null) { + legend.unsetExtLst(); + } else { + legend.setExtLst(list.getXmlObject()); + } + } + + public XDDFChartExtensionList getExtensionList() { + if (legend.isSetExtLst()) { + return new XDDFChartExtensionList(legend.getExtLst()); + } else { + return null; + } + } + + public void setLayout(XDDFLayout layout) { + if (layout == null) { + legend.unsetLayout(); + } else { + legend.setLayout(layout.getXmlObject()); + } + } + + public XDDFLayout getLayout() { + if (legend.isSetLayout()) { + return new XDDFLayout(legend.getLayout()); + } else { + return null; + } + } + + public void setPosition(LegendPosition position) { + if (!legend.isSetLegendPos()) { + legend.addNewLegendPos(); + } + legend.getLegendPos().setVal(position.underlying); + } + + /* + * According to ECMA-376 default position is RIGHT. + */ + public LegendPosition getPosition() { + if (legend.isSetLegendPos()) { + return LegendPosition.valueOf(legend.getLegendPos().getVal()); + } else { + return LegendPosition.RIGHT; + } + } + + public XDDFManualLayout getOrAddManualLayout() { + if (!legend.isSetLayout()) { + legend.addNewLayout(); + } + return new XDDFManualLayout(legend.getLayout()); + } + + public boolean isOverlay() { + return legend.getOverlay().getVal(); + } + + public void setOverlay(boolean value) { + legend.getOverlay().setVal(value); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFDataSource.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFDataSource.java new file mode 100644 index 0000000000..f6c19a1d1d --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFDataSource.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.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; + +@Beta +public interface XDDFDataSource { + int getPointCount(); + + T getPointAt(int index); + + boolean isReference(); + + boolean isNumeric(); + + String getDataRangeReference(); +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFDataSourcesFactory.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFDataSourcesFactory.java new file mode 100644 index 0000000000..a740d92f4f --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFDataSourcesFactory.java @@ -0,0 +1,299 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.apache.poi.xddf.usermodel.chart; + +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.CellValue; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.util.Beta; +import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData; + +/** + * Class {@code XDDFDataSourcesFactory} is a factory for {@link XDDFDataSource} instances. + */ +@Beta +public class XDDFDataSourcesFactory { + + private XDDFDataSourcesFactory() { + } + + public static XDDFCategoryDataSource fromDataSource(final CTAxDataSource categoryDS) { + return new XDDFCategoryDataSource() { + private CTStrData category = (CTStrData) categoryDS.getStrRef().getStrCache().copy(); + + @Override + public boolean isNumeric() { + return false; + } + + @Override + public boolean isReference() { + return true; + } + + @Override + public int getPointCount() { + return (int) category.getPtCount().getVal(); + } + + @Override + public String getPointAt(int index) { + return category.getPtArray(index).getV(); + } + + @Override + public String getDataRangeReference() { + return categoryDS.getStrRef().getF(); + } + }; + } + + public static XDDFNumericalDataSource fromDataSource(final CTNumDataSource valuesDS) { + return new XDDFNumericalDataSource() { + private CTNumData values = (CTNumData) valuesDS.getNumRef().getNumCache().copy(); + private String formatCode = values.isSetFormatCode() ? values.getFormatCode() : null; + + @Override + public String getFormatCode() { + return formatCode; + } + + @Override + public void setFormatCode(String formatCode) { + this.formatCode = formatCode; + } + + @Override + public boolean isNumeric() { + return true; + } + + @Override + public boolean isReference() { + return true; + } + + @Override + public int getPointCount() { + return (int) values.getPtCount().getVal(); + } + + @Override + public Double getPointAt(int index) { + return Double.valueOf(values.getPtArray(index).getV()); + } + + @Override + public String getDataRangeReference() { + return valuesDS.getNumRef().getF(); + } + }; + } + + public static XDDFNumericalDataSource fromArray(T[] elements, String dataRange) { + return new NumericalArrayDataSource(elements, dataRange); + } + + public static XDDFCategoryDataSource fromArray(String[] elements, String dataRange) { + return new StringArrayDataSource(elements, dataRange); + } + + public static XDDFNumericalDataSource fromNumericCellRange(XSSFSheet sheet, + CellRangeAddress cellRangeAddress) { + return new NumericalCellRangeDataSource(sheet, cellRangeAddress); + } + + public static XDDFCategoryDataSource fromStringCellRange(XSSFSheet sheet, CellRangeAddress cellRangeAddress) { + return new StringCellRangeDataSource(sheet, cellRangeAddress); + } + + private abstract static class AbstractArrayDataSource implements XDDFDataSource { + private final T[] elements; + private final String dataRange; + + public AbstractArrayDataSource(T[] elements, String dataRange) { + this.elements = elements.clone(); + this.dataRange = dataRange; + } + + @Override + public int getPointCount() { + return elements.length; + } + + @Override + public T getPointAt(int index) { + return elements[index]; + } + + @Override + public boolean isReference() { + return dataRange != null; + } + + @Override + public boolean isNumeric() { + Class arrayComponentType = elements.getClass().getComponentType(); + return (Number.class.isAssignableFrom(arrayComponentType)); + } + + @Override + public String getDataRangeReference() { + if (dataRange == null) { + throw new UnsupportedOperationException("Literal data source can not be expressed by reference."); + } else { + return dataRange; + } + } + } + + private static class NumericalArrayDataSource extends AbstractArrayDataSource + implements XDDFNumericalDataSource { + private String formatCode; + + public NumericalArrayDataSource(T[] elements, String dataRange) { + super(elements, dataRange); + } + + @Override + public String getFormatCode() { + return formatCode; + } + + @Override + public void setFormatCode(String formatCode) { + this.formatCode = formatCode; + } + } + + private static class StringArrayDataSource extends AbstractArrayDataSource + implements XDDFCategoryDataSource { + public StringArrayDataSource(String[] elements, String dataRange) { + super(elements, dataRange); + } + } + + private abstract static class AbstractCellRangeDataSource implements XDDFDataSource { + private final XSSFSheet sheet; + private final CellRangeAddress cellRangeAddress; + private final int numOfCells; + private XSSFFormulaEvaluator evaluator; + + protected AbstractCellRangeDataSource(XSSFSheet sheet, CellRangeAddress cellRangeAddress) { + this.sheet = sheet; + // Make copy since CellRangeAddress is mutable. + this.cellRangeAddress = cellRangeAddress.copy(); + this.numOfCells = this.cellRangeAddress.getNumberOfCells(); + this.evaluator = sheet.getWorkbook().getCreationHelper().createFormulaEvaluator(); + } + + @Override + public int getPointCount() { + return numOfCells; + } + + @Override + public boolean isReference() { + return true; + } + + @Override + public String getDataRangeReference() { + return cellRangeAddress.formatAsString(sheet.getSheetName(), true); + } + + protected CellValue getCellValueAt(int index) { + if (index < 0 || index >= numOfCells) { + throw new IndexOutOfBoundsException( + "Index must be between 0 and " + (numOfCells - 1) + " (inclusive), given: " + index); + } + int firstRow = cellRangeAddress.getFirstRow(); + int firstCol = cellRangeAddress.getFirstColumn(); + int lastCol = cellRangeAddress.getLastColumn(); + int width = lastCol - firstCol + 1; + int rowIndex = firstRow + index / width; + int cellIndex = firstCol + index % width; + XSSFRow row = sheet.getRow(rowIndex); + return (row == null) ? null : evaluator.evaluate(row.getCell(cellIndex)); + } + } + + private static class NumericalCellRangeDataSource extends AbstractCellRangeDataSource + implements XDDFNumericalDataSource { + protected NumericalCellRangeDataSource(XSSFSheet sheet, CellRangeAddress cellRangeAddress) { + super(sheet, cellRangeAddress); + } + + private String formatCode; + + @Override + public String getFormatCode() { + return formatCode; + } + + @Override + public void setFormatCode(String formatCode) { + this.formatCode = formatCode; + } + + @Override + public Double getPointAt(int index) { + CellValue cellValue = getCellValueAt(index); + if (cellValue != null && cellValue.getCellTypeEnum() == CellType.NUMERIC) { + return Double.valueOf(cellValue.getNumberValue()); + } else { + return null; + } + } + + @Override + public boolean isNumeric() { + return true; + } + } + + private static class StringCellRangeDataSource extends AbstractCellRangeDataSource + implements XDDFCategoryDataSource { + protected StringCellRangeDataSource(XSSFSheet sheet, CellRangeAddress cellRangeAddress) { + super(sheet, cellRangeAddress); + } + + @Override + public String getPointAt(int index) { + CellValue cellValue = getCellValueAt(index); + if (cellValue != null && cellValue.getCellTypeEnum() == CellType.STRING) { + return cellValue.getStringValue(); + } else { + return null; + } + } + + @Override + public boolean isNumeric() { + return false; + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFDateAxis.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFDateAxis.java new file mode 100644 index 0000000000..bc72a2162e --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFDateAxis.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.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTCrosses; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTDateAx; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumFmt; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTScaling; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTTickMark; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTUnsignedInt; +import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos; +import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; + +/** + * Date axis type. Currently only implements the same values as {@link XDDFCategoryAxis}, since the two are nearly + * identical. + */ +@Beta +public class XDDFDateAxis extends XDDFChartAxis { + + private CTDateAx ctDateAx; + + public XDDFDateAxis(CTPlotArea plotArea, AxisPosition position) { + initializeAxis(plotArea, position); + } + + public XDDFDateAxis(CTDateAx ctDateAx) { + this.ctDateAx = ctDateAx; + } + + @Override + @Internal + public CTShapeProperties getMajorGridLines() { + if (!ctDateAx.isSetMajorGridlines()) { + ctDateAx.addNewMajorGridlines(); + } + if (!ctDateAx.getMajorGridlines().isSetSpPr()) { + ctDateAx.getMajorGridlines().addNewSpPr(); + } + return ctDateAx.getMajorGridlines().getSpPr(); + } + + @Override + @Internal + public CTShapeProperties getLine() { + return ctDateAx.getSpPr(); + } + + @Override + public void crossAxis(XDDFChartAxis axis) { + ctDateAx.getCrossAx().setVal(axis.getId()); + } + + @Override + protected CTUnsignedInt getCTAxId() { + return ctDateAx.getAxId(); + } + + @Override + protected CTAxPos getCTAxPos() { + return ctDateAx.getAxPos(); + } + + @Override + public boolean hasNumberFormat() { + return ctDateAx.isSetNumFmt(); + } + + @Override + protected CTNumFmt getCTNumFmt() { + if (ctDateAx.isSetNumFmt()) { + return ctDateAx.getNumFmt(); + } + return ctDateAx.addNewNumFmt(); + } + + @Override + protected CTScaling getCTScaling() { + return ctDateAx.getScaling(); + } + + @Override + protected CTCrosses getCTCrosses() { + CTCrosses crosses = ctDateAx.getCrosses(); + if (crosses == null) { + return ctDateAx.addNewCrosses(); + } else { + return crosses; + } + } + + @Override + protected CTBoolean getDelete() { + return ctDateAx.getDelete(); + } + + @Override + protected CTTickMark getMajorCTTickMark() { + return ctDateAx.getMajorTickMark(); + } + + @Override + protected CTTickMark getMinorCTTickMark() { + return ctDateAx.getMinorTickMark(); + } + + private void initializeAxis(CTPlotArea plotArea, AxisPosition position) { + final long id = getNextAxId(plotArea); + ctDateAx = plotArea.addNewDateAx(); + ctDateAx.addNewAxId().setVal(id); + ctDateAx.addNewAxPos(); + ctDateAx.addNewScaling(); + ctDateAx.addNewCrosses(); + ctDateAx.addNewCrossAx(); + ctDateAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO); + ctDateAx.addNewDelete(); + ctDateAx.addNewMajorTickMark(); + ctDateAx.addNewMinorTickMark(); + + setPosition(position); + 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/xddf/usermodel/chart/XDDFLayout.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFLayout.java new file mode 100644 index 0000000000..b3bacdd649 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFLayout.java @@ -0,0 +1,73 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayout; + +@Beta +public class XDDFLayout { + private CTLayout layout; + + public XDDFLayout() { + this(CTLayout.Factory.newInstance()); + } + + @Internal + protected XDDFLayout(CTLayout layout) { + this.layout = layout; + } + + @Internal + protected CTLayout getXmlObject() { + return layout; + } + + public void setExtensionList(XDDFChartExtensionList list) { + if (list == null) { + layout.unsetExtLst(); + } else { + layout.setExtLst(list.getXmlObject()); + } + } + + public XDDFChartExtensionList getExtensionList() { + if (layout.isSetExtLst()) { + return new XDDFChartExtensionList(layout.getExtLst()); + } else { + return null; + } + } + + public void setManualLayout(XDDFManualLayout manual) { + if (manual == null) { + layout.unsetManualLayout(); + } else { + layout.setManualLayout(manual.getXmlObject()); + } + } + + public XDDFManualLayout getManualLayout() { + if (layout.isSetManualLayout()) { + return new XDDFManualLayout(layout); + } else { + return null; + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFLegendEntry.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFLegendEntry.java new file mode 100644 index 0000000000..da8fa22c85 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFLegendEntry.java @@ -0,0 +1,98 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.apache.poi.xddf.usermodel.text.XDDFTextBody; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTLegendEntry; + +@Beta +public class XDDFLegendEntry { + private CTLegendEntry entry; + + @Internal + protected XDDFLegendEntry(CTLegendEntry entry) { + this.entry = entry; + } + + @Internal + protected CTLegendEntry getXmlObject() { + return entry; + } + + public XDDFTextBody getTextBody() { + if (entry.isSetTxPr()) { + return new XDDFTextBody(entry.getTxPr()); + } else { + return null; + } + } + + public void setTextBody(XDDFTextBody body) { + if (body == null) { + entry.unsetTxPr(); + } else { + entry.setTxPr(body.getXmlObject()); + } + } + + public boolean getDelete() { + if (entry.isSetDelete()) { + return entry.getDelete().getVal(); + } else { + return false; + } + } + + public void setDelete(Boolean delete) { + if (delete == null) { + entry.unsetDelete(); + } else { + if (entry.isSetDelete()) { + entry.getDelete().setVal(delete); + } else { + entry.addNewDelete().setVal(delete); + } + } + } + + public long getIndex() { + return entry.getIdx().getVal(); + } + + public void setIndex(long index) { + entry.getIdx().setVal(index); + } + + public void setExtensionList(XDDFChartExtensionList list) { + if (list == null) { + entry.unsetExtLst(); + } else { + entry.setExtLst(list.getXmlObject()); + } + } + + public XDDFChartExtensionList getExtensionList() { + if (entry.isSetExtLst()) { + return new XDDFChartExtensionList(entry.getExtLst()); + } else { + return null; + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFLineChartData.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFLineChartData.java new file mode 100644 index 0000000000..ff4c648b61 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFLineChartData.java @@ -0,0 +1,141 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.Map; + +import org.apache.poi.util.Beta; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineSer; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTMarker; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; + +@Beta +public class XDDFLineChartData extends XDDFChartData { + private CTLineChart chart; + + public XDDFLineChartData(CTLineChart chart, Map categories, + Map values) { + this.chart = chart; + for (CTLineSer series : chart.getSerList()) { + this.series.add(new Series(series, series.getCat(), series.getVal())); + } + defineAxes(chart.getAxIdArray(), categories, values); + } + + @Override + public void setVaryColors(boolean varyColors) { + if (chart.isSetVaryColors()) { + chart.getVaryColors().setVal(varyColors); + } else { + chart.addNewVaryColors().setVal(varyColors); + } + } + + public Grouping getGrouping() { + return Grouping.valueOf(chart.getGrouping().getVal()); + } + + public void setGrouping(Grouping grouping) { + chart.getGrouping().setVal(grouping.underlying); + } + + @Override + public XDDFChartData.Series addSeries(XDDFDataSource category, + XDDFNumericalDataSource values) { + final int index = this.series.size(); + final CTLineSer ctSer = this.chart.addNewSer(); + ctSer.addNewCat(); + ctSer.addNewVal(); + ctSer.addNewIdx().setVal(index); + ctSer.addNewOrder().setVal(index); + final Series added = new Series(ctSer, category, values); + this.series.add(added); + return added; + } + + public class Series extends XDDFChartData.Series { + private CTLineSer series; + + protected Series(CTLineSer series, XDDFDataSource category, + XDDFNumericalDataSource values) { + super(category, values); + this.series = series; + } + + protected Series(CTLineSer series, CTAxDataSource category, CTNumDataSource values) { + super(XDDFDataSourcesFactory.fromDataSource(category), XDDFDataSourcesFactory.fromDataSource(values)); + this.series = series; + } + + @Override + protected CTSerTx getSeriesText() { + return series.getTx(); + } + + @Override + public void setShowLeaderLines(boolean showLeaderLines) { + if (!series.isSetDLbls()) { + series.addNewDLbls(); + } + if (series.getDLbls().isSetShowLeaderLines()) { + series.getDLbls().getShowLeaderLines().setVal(showLeaderLines); + } else { + series.getDLbls().addNewShowLeaderLines().setVal(showLeaderLines); + } + } + + public void setMarkerSize(short size) { + CTMarker marker = getMarker(); + if (marker.isSetSize()) { + marker.getSize().setVal(size); + } else { + marker.addNewSize().setVal(size); + } + } + + public void setMarkerStyle(MarkerStyle style) { + CTMarker marker = getMarker(); + if (marker.isSetSymbol()) { + marker.getSymbol().setVal(style.underlying); + } else { + marker.addNewSymbol().setVal(style.underlying); + } + } + + private CTMarker getMarker() { + if (series.isSetMarker()) { + return series.getMarker(); + } else { + return series.addNewMarker(); + } + } + + @Override + protected CTAxDataSource getAxDS() { + return series.getCat(); + } + + @Override + protected CTNumDataSource getNumDS() { + return series.getVal(); + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFManualLayout.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFManualLayout.java new file mode 100644 index 0000000000..766fb95507 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFManualLayout.java @@ -0,0 +1,221 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayout; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTManualLayout; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; + +/** + * Represents a DrawingML manual layout. + */ +@Beta +public final class XDDFManualLayout { + + /** + * Underlaying CTManualLayout bean. + */ + private CTManualLayout layout; + + private static final LayoutMode defaultLayoutMode = LayoutMode.EDGE; + private static final LayoutTarget defaultLayoutTarget = LayoutTarget.INNER; + + /** + * Create a new DrawingML manual layout. + * + * @param ctLayout + * a DrawingML layout that should be used as base. + */ + public XDDFManualLayout(CTLayout ctLayout) { + initializeLayout(ctLayout); + } + + /** + * Create a new DrawingML manual layout for chart. + * + * @param ctPlotArea + * a chart's plot area to create layout for. + */ + public XDDFManualLayout(CTPlotArea ctPlotArea) { + CTLayout ctLayout = ctPlotArea.isSetLayout() ? ctPlotArea.getLayout() : ctPlotArea.addNewLayout(); + + initializeLayout(ctLayout); + } + + /** + * Return the underlying CTManualLayout bean. + * + * @return the underlying CTManualLayout bean. + */ + @Internal + protected CTManualLayout getXmlObject() { + return layout; + } + + public void setExtensionList(XDDFChartExtensionList list) { + if (list == null) { + layout.unsetExtLst(); + } else { + layout.setExtLst(list.getXmlObject()); + } + } + + public XDDFChartExtensionList getExtensionList() { + if (layout.isSetExtLst()) { + return new XDDFChartExtensionList(layout.getExtLst()); + } else { + return null; + } + } + + public void setWidthRatio(double ratio) { + if (!layout.isSetW()) { + layout.addNewW(); + } + layout.getW().setVal(ratio); + } + + public double getWidthRatio() { + if (!layout.isSetW()) { + return 0.0; + } + return layout.getW().getVal(); + } + + public void setHeightRatio(double ratio) { + if (!layout.isSetH()) { + layout.addNewH(); + } + layout.getH().setVal(ratio); + } + + public double getHeightRatio() { + if (!layout.isSetH()) { + return 0.0; + } + return layout.getH().getVal(); + } + + public LayoutTarget getTarget() { + if (!layout.isSetLayoutTarget()) { + return defaultLayoutTarget; + } + return LayoutTarget.valueOf(layout.getLayoutTarget().getVal()); + } + + public void setTarget(LayoutTarget target) { + if (!layout.isSetLayoutTarget()) { + layout.addNewLayoutTarget(); + } + layout.getLayoutTarget().setVal(target.underlying); + } + + public LayoutMode getXMode() { + if (!layout.isSetXMode()) { + return defaultLayoutMode; + } + return LayoutMode.valueOf(layout.getXMode().getVal()); + } + + public void setXMode(LayoutMode mode) { + if (!layout.isSetXMode()) { + layout.addNewXMode(); + } + layout.getXMode().setVal(mode.underlying); + } + + public LayoutMode getYMode() { + if (!layout.isSetYMode()) { + return defaultLayoutMode; + } + return LayoutMode.valueOf(layout.getYMode().getVal()); + } + + public void setYMode(LayoutMode mode) { + if (!layout.isSetYMode()) { + layout.addNewYMode(); + } + layout.getYMode().setVal(mode.underlying); + } + + public double getX() { + if (!layout.isSetX()) { + return 0.0; + } + return layout.getX().getVal(); + } + + public void setX(double x) { + if (!layout.isSetX()) { + layout.addNewX(); + } + layout.getX().setVal(x); + } + + public double getY() { + if (!layout.isSetY()) { + return 0.0; + } + return layout.getY().getVal(); + } + + public void setY(double y) { + if (!layout.isSetY()) { + layout.addNewY(); + } + layout.getY().setVal(y); + } + + public LayoutMode getWidthMode() { + if (!layout.isSetWMode()) { + return defaultLayoutMode; + } + return LayoutMode.valueOf(layout.getWMode().getVal()); + } + + public void setWidthMode(LayoutMode mode) { + if (!layout.isSetWMode()) { + layout.addNewWMode(); + } + layout.getWMode().setVal(mode.underlying); + } + + public LayoutMode getHeightMode() { + if (!layout.isSetHMode()) { + return defaultLayoutMode; + } + return LayoutMode.valueOf(layout.getHMode().getVal()); + } + + public void setHeightMode(LayoutMode mode) { + if (!layout.isSetHMode()) { + layout.addNewHMode(); + } + layout.getHMode().setVal(mode.underlying); + } + + private void initializeLayout(CTLayout ctLayout) { + if (ctLayout.isSetManualLayout()) { + this.layout = ctLayout.getManualLayout(); + } else { + this.layout = ctLayout.addNewManualLayout(); + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFNumericalDataSource.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFNumericalDataSource.java new file mode 100644 index 0000000000..bb6d0825a8 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFNumericalDataSource.java @@ -0,0 +1,29 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.apache.poi.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; + +@Beta +public interface XDDFNumericalDataSource extends XDDFDataSource { + String getFormatCode(); + + void setFormatCode(String formatCode); +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFPieChartData.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFPieChartData.java new file mode 100644 index 0000000000..5c773c272d --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFPieChartData.java @@ -0,0 +1,118 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; + +@Beta +public class XDDFPieChartData extends XDDFChartData { + private CTPieChart chart; + + public XDDFPieChartData(CTPieChart chart) { + this.chart = chart; + for (CTPieSer series : chart.getSerList()) { + this.series.add(new Series(series, series.getCat(), series.getVal())); + } + } + + @Override + public void setVaryColors(boolean varyColors) { + if (chart.isSetVaryColors()) { + chart.getVaryColors().setVal(varyColors); + } else { + chart.addNewVaryColors().setVal(varyColors); + } + } + + @Override + public XDDFChartData.Series addSeries(XDDFDataSource category, + XDDFNumericalDataSource values) { + final int index = this.series.size(); + final CTPieSer ctSer = this.chart.addNewSer(); + ctSer.addNewCat(); + ctSer.addNewVal(); + ctSer.addNewIdx().setVal(index); + ctSer.addNewOrder().setVal(index); + final Series added = new Series(ctSer, category, values); + this.series.add(added); + return added; + } + + public class Series extends XDDFChartData.Series { + private CTPieSer series; + + protected Series(CTPieSer series, XDDFDataSource category, + XDDFNumericalDataSource values) { + super(category, values); + this.series = series; + } + + protected Series(CTPieSer series, CTAxDataSource category, CTNumDataSource values) { + super(XDDFDataSourcesFactory.fromDataSource(category), XDDFDataSourcesFactory.fromDataSource(values)); + this.series = series; + } + + @Override + protected CTSerTx getSeriesText() { + return series.getTx(); + } + + @Override + public void setShowLeaderLines(boolean showLeaderLines) { + if (!series.isSetDLbls()) { + series.addNewDLbls(); + } + if (series.getDLbls().isSetShowLeaderLines()) { + series.getDLbls().getShowLeaderLines().setVal(showLeaderLines); + } else { + series.getDLbls().addNewShowLeaderLines().setVal(showLeaderLines); + } + } + + public long getExplosion() { + if (series.isSetExplosion()) { + return series.getExplosion().getVal(); + } else { + return 0; + } + } + + public void setExplosion(long explosion) { + if (series.isSetExplosion()) { + series.getExplosion().setVal(explosion); + } else { + series.addNewExplosion().setVal(explosion); + } + } + + @Override + protected CTAxDataSource getAxDS() { + return series.getCat(); + } + + @Override + protected CTNumDataSource getNumDS() { + return series.getVal(); + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFRadarChartData.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFRadarChartData.java new file mode 100644 index 0000000000..15891ce58b --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFRadarChartData.java @@ -0,0 +1,119 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import java.util.Map; + +import org.apache.poi.util.Beta; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTRadarChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTRadarSer; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTRadarStyle; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; + +@Beta +public class XDDFRadarChartData extends XDDFChartData { + private CTRadarChart chart; + + public XDDFRadarChartData(CTRadarChart chart, Map categories, + Map values) { + this.chart = chart; + for (CTRadarSer series : chart.getSerList()) { + this.series.add(new Series(series, series.getCat(), series.getVal())); + } + defineAxes(chart.getAxIdArray(), categories, values); + } + + @Override + public void setVaryColors(boolean varyColors) { + if (chart.isSetVaryColors()) { + chart.getVaryColors().setVal(varyColors); + } else { + chart.addNewVaryColors().setVal(varyColors); + } + } + + public RadarStyle getStyle() { + return RadarStyle.valueOf(chart.getRadarStyle().getVal()); + } + + public void setStyle(RadarStyle style) { + CTRadarStyle radarStyle = chart.getRadarStyle(); + if (radarStyle == null) { + radarStyle = chart.addNewRadarStyle(); + } + radarStyle.setVal(style.underlying); + } + + @Override + public XDDFChartData.Series addSeries(XDDFDataSource category, + XDDFNumericalDataSource values) { + final int index = this.series.size(); + final CTRadarSer ctSer = this.chart.addNewSer(); + ctSer.addNewCat(); + ctSer.addNewVal(); + ctSer.addNewIdx().setVal(index); + ctSer.addNewOrder().setVal(index); + final Series added = new Series(ctSer, category, values); + this.series.add(added); + return added; + } + + public class Series extends XDDFChartData.Series { + private CTRadarSer series; + + protected Series(CTRadarSer series, XDDFDataSource category, + XDDFNumericalDataSource values) { + super(category, values); + this.series = series; + } + + protected Series(CTRadarSer series, CTAxDataSource category, CTNumDataSource values) { + super(XDDFDataSourcesFactory.fromDataSource(category), XDDFDataSourcesFactory.fromDataSource(values)); + this.series = series; + } + + @Override + protected CTSerTx getSeriesText() { + return series.getTx(); + } + + @Override + public void setShowLeaderLines(boolean showLeaderLines) { + if (!series.isSetDLbls()) { + series.addNewDLbls(); + } + if (series.getDLbls().isSetShowLeaderLines()) { + series.getDLbls().getShowLeaderLines().setVal(showLeaderLines); + } else { + series.getDLbls().addNewShowLeaderLines().setVal(showLeaderLines); + } + } + + @Override + protected CTAxDataSource getAxDS() { + return series.getCat(); + } + + @Override + protected CTNumDataSource getNumDS() { + return series.getVal(); + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFScatterChartData.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFScatterChartData.java new file mode 100644 index 0000000000..f025273a24 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFScatterChartData.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.xddf.usermodel.chart; + +import java.util.Map; + +import org.apache.poi.util.Beta; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterSer; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterStyle; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; + +@Beta +public class XDDFScatterChartData extends XDDFChartData { + private CTScatterChart chart; + + public XDDFScatterChartData(CTScatterChart chart, Map categories, + Map values) { + this.chart = chart; + for (CTScatterSer series : chart.getSerList()) { + this.series.add(new Series(series, series.getXVal(), series.getYVal())); + } + defineAxes(chart.getAxIdArray(), categories, values); + } + + @Override + public void setVaryColors(boolean varyColors) { + if (chart.isSetVaryColors()) { + chart.getVaryColors().setVal(varyColors); + } else { + chart.addNewVaryColors().setVal(varyColors); + } + } + + public ScatterStyle getStyle() { + CTScatterStyle scatterStyle = chart.getScatterStyle(); + if (scatterStyle == null) { + scatterStyle = chart.addNewScatterStyle(); + scatterStyle.setVal(ScatterStyle.LINE_MARKER.underlying); + } + return ScatterStyle.valueOf(scatterStyle.getVal()); + } + + public void setStyle(ScatterStyle style) { + CTScatterStyle scatterStyle = chart.getScatterStyle(); + if (scatterStyle == null) { + scatterStyle = chart.addNewScatterStyle(); + } + scatterStyle.setVal(style.underlying); + } + + @Override + public XDDFChartData.Series addSeries(XDDFDataSource category, + XDDFNumericalDataSource values) { + final int index = this.series.size(); + final CTScatterSer ctSer = this.chart.addNewSer(); + ctSer.addNewXVal(); + ctSer.addNewYVal(); + ctSer.addNewIdx().setVal(index); + ctSer.addNewOrder().setVal(index); + final Series added = new Series(ctSer, category, values); + this.series.add(added); + return added; + } + + public class Series extends XDDFChartData.Series { + private CTScatterSer series; + + protected Series(CTScatterSer series, XDDFDataSource category, XDDFNumericalDataSource values) { + super(category, values); + this.series = series; + } + + protected Series(CTScatterSer series, CTAxDataSource category, CTNumDataSource values) { + super(XDDFDataSourcesFactory.fromDataSource(category), XDDFDataSourcesFactory.fromDataSource(values)); + this.series = series; + } + + @Override + protected CTSerTx getSeriesText() { + return series.getTx(); + } + + @Override + public void setShowLeaderLines(boolean showLeaderLines) { + if (!series.isSetDLbls()) { + series.addNewDLbls(); + } + if (series.getDLbls().isSetShowLeaderLines()) { + series.getDLbls().getShowLeaderLines().setVal(showLeaderLines); + } else { + series.getDLbls().addNewShowLeaderLines().setVal(showLeaderLines); + } + } + + @Override + protected CTAxDataSource getAxDS() { + return series.getXVal(); + } + + @Override + protected CTNumDataSource getNumDS() { + return series.getYVal(); + } + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFValueAxis.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFValueAxis.java new file mode 100644 index 0000000000..08fe0dea15 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFValueAxis.java @@ -0,0 +1,153 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xddf.usermodel.chart; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTCrosses; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumFmt; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTScaling; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTTickMark; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTUnsignedInt; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx; +import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos; +import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; + +@Beta +public class XDDFValueAxis extends XDDFChartAxis { + + private CTValAx ctValAx; + + public XDDFValueAxis(CTPlotArea plotArea, AxisPosition position) { + initializeAxis(plotArea, position); + } + + public XDDFValueAxis(CTValAx ctValAx) { + this.ctValAx = ctValAx; + } + + @Override + @Internal + public CTShapeProperties getMajorGridLines() { + if (!ctValAx.isSetMajorGridlines()) { + ctValAx.addNewMajorGridlines(); + } + if (!ctValAx.getMajorGridlines().isSetSpPr()) { + ctValAx.getMajorGridlines().addNewSpPr(); + } + return ctValAx.getMajorGridlines().getSpPr(); + } + + @Override + @Internal + public CTShapeProperties getLine() { + return ctValAx.getSpPr(); + } + + @Override + public void crossAxis(XDDFChartAxis axis) { + ctValAx.getCrossAx().setVal(axis.getId()); + } + + @Override + protected CTUnsignedInt getCTAxId() { + return ctValAx.getAxId(); + } + + @Override + protected CTAxPos getCTAxPos() { + return ctValAx.getAxPos(); + } + + @Override + public boolean hasNumberFormat() { + return ctValAx.isSetNumFmt(); + } + + @Override + protected CTNumFmt getCTNumFmt() { + if (ctValAx.isSetNumFmt()) { + return ctValAx.getNumFmt(); + } + return ctValAx.addNewNumFmt(); + } + + @Override + protected CTScaling getCTScaling() { + return ctValAx.getScaling(); + } + + @Override + protected CTCrosses getCTCrosses() { + CTCrosses crosses = ctValAx.getCrosses(); + if (crosses == null) { + return ctValAx.addNewCrosses(); + } else { + return crosses; + } + } + + @Override + protected CTBoolean getDelete() { + return ctValAx.getDelete(); + } + + @Override + protected CTTickMark getMajorCTTickMark() { + return ctValAx.getMajorTickMark(); + } + + @Override + protected CTTickMark getMinorCTTickMark() { + return ctValAx.getMinorTickMark(); + } + + public AxisCrossBetween getCrossBetween() { + return AxisCrossBetween.valueOf(ctValAx.getCrossBetween().getVal()); + } + + public void setCrossBetween(AxisCrossBetween crossBetween) { + ctValAx.getCrossBetween().setVal(crossBetween.underlying); + } + + private void initializeAxis(CTPlotArea plotArea, AxisPosition position) { + final long id = getNextAxId(plotArea); + ctValAx = plotArea.addNewValAx(); + ctValAx.addNewAxId().setVal(id); + ctValAx.addNewAxPos(); + ctValAx.addNewScaling(); + ctValAx.addNewCrossBetween(); + ctValAx.addNewCrosses(); + ctValAx.addNewCrossAx(); + ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO); + ctValAx.addNewDelete(); + ctValAx.addNewMajorTickMark(); + ctValAx.addNewMinorTickMark(); + + setPosition(position); + setOrientation(AxisOrientation.MIN_MAX); + setCrossBetween(AxisCrossBetween.MIDPOINT_CATEGORY); + setCrosses(AxisCrosses.AUTO_ZERO); + setVisible(true); + setMajorTickMark(AxisTickMark.CROSS); + setMinorTickMark(AxisTickMark.NONE); + } +} diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.java new file mode 100644 index 0000000000..fdd0e500c0 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/text/XDDFTextBody.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.xddf.usermodel.text; + +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; + +@Beta +public class XDDFTextBody { + private CTTextBody body; + + public XDDFTextBody() { + this(CTTextBody.Factory.newInstance()); + } + + @Internal + public XDDFTextBody(CTTextBody body) { + this.body = body; + } + + @Internal + public CTTextBody getXmlObject() { + return body; + } +} diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java index 683ceb5ce5..1f66768cde 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java @@ -38,6 +38,7 @@ import org.apache.poi.POIXMLException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.sl.usermodel.MasterSheet; import org.apache.poi.sl.usermodel.PictureData.PictureType; import org.apache.poi.sl.usermodel.Resources; @@ -80,6 +81,7 @@ implements SlideShow { private List _slides; private List _masters; private List _pictures; + private List _charts; private XSLFTableStyles _tableStyles; private XSLFNotesMaster _notesMaster; private XSLFCommentAuthors _commentAuthors; @@ -93,7 +95,7 @@ implements SlideShow { try { if(getCorePart().getContentType().equals(XSLFRelation.THEME_MANAGER.getContentType())) { - rebase(getPackage()); + rebase(getPackage()); } //build a tree of POIXMLDocumentParts, this presentation being the root @@ -130,10 +132,16 @@ implements SlideShow { Map masterMap = new HashMap<>(); Map shIdMap = new HashMap<>(); + Map chartMap = new HashMap<>(); for (RelationPart rp : getRelationParts()) { POIXMLDocumentPart p = rp.getDocumentPart(); if (p instanceof XSLFSlide) { shIdMap.put(rp.getRelationship().getId(), (XSLFSlide) p); + for (POIXMLDocumentPart c : p.getRelations()) { + if (c instanceof XSLFChart) { + chartMap.put(c.getPackagePart().getPartName().getName(), (XSLFChart) c); + } + } } else if (p instanceof XSLFSlideMaster) { masterMap.put(getRelationId(p), (XSLFSlideMaster) p); } else if (p instanceof XSLFTableStyles){ @@ -145,6 +153,11 @@ implements SlideShow { } } + _charts = new ArrayList<>(chartMap.size()); + for(XSLFChart chart : chartMap.values()) { + _charts.add(chart); + } + _masters = new ArrayList<>(masterMap.size()); for (CTSlideMasterIdListEntry masterId : _presentation.getSldMasterIdLst().getSldMasterIdList()) { XSLFSlideMaster master = masterMap.get(masterId.getId2()); @@ -208,6 +221,7 @@ implements SlideShow { public XSLFSlide createSlide(XSLFSlideLayout layout) { int slideNumber = 256, cnt = 1; CTSlideIdList slideList; + XSLFRelation relationType = XSLFRelation.SLIDE; if (!_presentation.isSetSldIdLst()) { slideList = _presentation.addNewSldIdLst(); } else { @@ -217,35 +231,11 @@ implements SlideShow { cnt++; } - // Bug 55791: We also need to check that the resulting file name is not already taken - // this can happen when removing/adding slides - while(true) { - String slideName = XSLFRelation.SLIDE.getFileName(cnt); - boolean found = false; - for (POIXMLDocumentPart relation : getRelations()) { - if (relation.getPackagePart() != null && - slideName.equals(relation.getPackagePart().getPartName().getName())) { - // name is taken => try next one - found = true; - break; - } - } - - if(!found && - getPackage().getPartsByName(Pattern.compile(Pattern.quote(slideName))).size() > 0) { - // name is taken => try next one - found = true; - } - - if (!found) { - break; - } - cnt++; - } + cnt = findNextAvailableFileNameIndex(relationType, cnt); } - RelationPart rp = createRelationship( - XSLFRelation.SLIDE, XSLFFactory.getInstance(), cnt, false); + RelationPart rp = createRelationship + (relationType, XSLFFactory.getInstance(), cnt, false); XSLFSlide slide = rp.getDocumentPart(); CTSlideIdListEntry slideId = slideList.addNewSldId(); @@ -260,6 +250,35 @@ implements SlideShow { return slide; } + private int findNextAvailableFileNameIndex(XSLFRelation relationType, int idx) { + // Bug 55791: We also need to check that the resulting file name is not already taken + // this can happen when removing/adding slides, notes or charts + while(true) { + String fileName = relationType.getFileName(idx); + boolean found = false; + for (POIXMLDocumentPart relation : getRelations()) { + if (relation.getPackagePart() != null && + fileName.equals(relation.getPackagePart().getPartName().getName())) { + // name is taken => try next one + found = true; + break; + } + } + + if(!found && + getPackage().getPartsByName(Pattern.compile(Pattern.quote(fileName))).size() > 0) { + // name is taken => try next one + found = true; + } + + if (!found) { + break; + } + idx++; + } + return idx; + } + /** * Create a blank slide using the default (first) master. */ @@ -275,10 +294,27 @@ implements SlideShow { } layout = sl[0]; } - + return createSlide(layout); } + /** + * Create a blank chart on the given slide. + */ + public XSLFChart createChart(XSLFSlide slide) { + int chartIdx = findNextAvailableFileNameIndex(XSLFRelation.CHART, _charts.size() + 1); + XSLFChart chart = (XSLFChart) createRelationship(XSLFRelation.CHART, XSLFFactory.getInstance(), chartIdx, true).getDocumentPart(); + slide.addRelation(null, XSLFRelation.CHART, chart); + createWorkbookRelationship(chart, chartIdx); + _charts.add(chart); + return chart; + } + + protected PackageRelationship createWorkbookRelationship(XSLFChart chart, int chartIdx) { + POIXMLDocumentPart worksheet = createRelationship(XSLFChart.WORKBOOK_RELATIONSHIP, XSLFFactory.getInstance(), chartIdx, true).getDocumentPart(); + return chart.addRelation(null, XSLFChart.WORKBOOK_RELATIONSHIP, worksheet).getRelationship(); + } + /** * Return notes slide for the specified slide or create new if it does not exist yet. */ @@ -301,39 +337,16 @@ implements SlideShow { createNotesMaster(); } - Integer slideIndex = XSLFRelation.SLIDE.getFileNameIndex(slide); + int slideIndex = XSLFRelation.SLIDE.getFileNameIndex(slide); - // Bug 55791: We also need to check that the resulting file name is not already taken - // this can happen when removing/adding slides - while(true) { - String slideName = XSLFRelation.NOTES.getFileName(slideIndex); - boolean found = false; - for (POIXMLDocumentPart relation : getRelations()) { - if (relation.getPackagePart() != null && - slideName.equals(relation.getPackagePart().getPartName().getName())) { - // name is taken => try next one - found = true; - break; - } - } - - if(!found && - getPackage().getPartsByName(Pattern.compile(Pattern.quote(slideName))).size() > 0) { - // name is taken => try next one - found = true; - } - - if (!found) { - break; - } - slideIndex++; - } + XSLFRelation relationType = XSLFRelation.NOTES; + slideIndex = findNextAvailableFileNameIndex(relationType, slideIndex); // add notes slide to presentation XSLFNotes notesSlide = (XSLFNotes) createRelationship - (XSLFRelation.NOTES, XSLFFactory.getInstance(), slideIndex); + (relationType, XSLFFactory.getInstance(), slideIndex); // link slide and notes slide with each other - slide.addRelation(null, XSLFRelation.NOTES, notesSlide); + slide.addRelation(null, relationType, notesSlide); notesSlide.addRelation(null, XSLFRelation.NOTES_MASTER, _notesMaster); notesSlide.addRelation(null, XSLFRelation.SLIDE, slide); @@ -404,6 +417,13 @@ implements SlideShow { return _slides; } + /** + * Return all the charts in the slideshow + */ + public List getCharts() { + return _charts; + } + /** * Returns the list of comment authors, if there is one. * Will only be present if at least one slide has comments on it. @@ -444,7 +464,17 @@ implements SlideShow { public XSLFSlide removeSlide(int index){ XSLFSlide slide = _slides.remove(index); removeRelation(slide); - _presentation.getSldIdLst().removeSldId(index); + _presentation.getSldIdLst().removeSldId(index); + for (POIXMLDocumentPart p : slide.getRelations()) { + if (p instanceof XSLFChart) { + XSLFChart chart = (XSLFChart) p; + slide.removeChartRelation(chart); + _charts.remove(chart); + } else if (p instanceof XSLFSlideLayout) { + XSLFSlideLayout layout = (XSLFSlideLayout) p; + slide.removeLayoutRelation(layout); + } + } return slide; } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java index 942c13bea4..30e594df8f 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java @@ -26,15 +26,28 @@ import java.io.OutputStream; import javax.xml.namespace.QName; +import org.apache.poi.POIXMLDocument; import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.POIXMLException; +import org.apache.poi.POIXMLRelation; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException; import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellReference; import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; +import org.apache.poi.xddf.usermodel.chart.XDDFChart; +import org.apache.poi.xddf.usermodel.chart.XDDFChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace; -import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; /** * Represents a Chart in a .pptx presentation @@ -42,63 +55,173 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument; * */ @Beta -public final class XSLFChart extends POIXMLDocumentPart { +public final class XSLFChart extends XDDFChart { + protected static final POIXMLRelation WORKBOOK_RELATIONSHIP = new POIXMLRelation( + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + POIXMLDocument.PACK_OBJECT_REL_TYPE, + "/ppt/embeddings/Microsoft_Excel_Worksheet#.xlsx", + XSSFWorkbook.class + ){}; - /** - * Root element of the Chart part - */ - private CTChartSpace chartSpace; /** - * The Chart within that - */ - private CTChart chart; + * Underlying workbook + */ + private XSSFWorkbook workbook; + + + /** + * Construct a PresentationML chart. + */ + protected XSLFChart() { + super(); + } /** - * Construct a chart from a package part. + * Construct a PresentationML 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 - * + * * @since POI 3.14-Beta1 */ protected XSLFChart(PackagePart part) throws IOException, XmlException { super(part); + } - chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream(), DEFAULT_XML_OPTIONS).getChartSpace(); - chart = chartSpace.getChart(); + public XSLFTextShape getTitle() { + if (!chart.isSetTitle()) { + chart.addNewTitle(); + } + final CTTitle title = chart.getTitle(); + if (title.getTx() != null && title.getTx().isSetRich()) { + return new XSLFTextShape(title, null) { + @Override + protected CTTextBody getTextBody(boolean create) { + return title.getTx().getRich(); + } + }; + } else { + return new XSLFTextShape(title, null) { + @Override + protected CTTextBody getTextBody(boolean create) { + return title.getTxPr(); + } + }; + } } - /** - * Return the underlying CTChartSpace bean, the root element of the 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); - xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c")); - - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - chartSpace.save(out, xmlOptions); - out.close(); - } + public CellReference setSheetTitle(String title) { + XSSFSheet sheet = getSheet(); + sheet.createRow(0).createCell(1).setCellValue(title); + return new CellReference(sheet.getSheetName(), 0, 1, true, true); + } + + public String formatRange(CellRangeAddress range) { + return range.formatAsString(getSheet().getSheetName(), true); + } + private XSSFSheet getSheet() { + XSSFSheet sheet = null; + try { + sheet = getWorkbook().getSheetAt(0); + } catch (InvalidFormatException ife) { + } catch (IOException ioe) { + } + return sheet; + } + private PackagePart getWorksheetPart() throws InvalidFormatException { + for (RelationPart part : getRelationParts()) { + if (WORKBOOK_RELATIONSHIP.getRelation().equals(part.getRelationship().getRelationshipType())) { + return getTargetPart(part.getRelationship()); + } + } + return null; + } + + protected XSSFWorkbook getWorkbook() throws IOException, InvalidFormatException { + if (workbook == null) { + try { + PackagePart worksheetPart = getWorksheetPart(); + if (worksheetPart == null) { + workbook = new XSSFWorkbook(); + workbook.createSheet(); + } else { + workbook = new XSSFWorkbook(worksheetPart.getInputStream()); + } + } catch (NotOfficeXmlFileException e) { + workbook = new XSSFWorkbook(); + workbook.createSheet(); + } + } + return workbook; + } + + private XMLSlideShow getSlideShow() { + POIXMLDocumentPart p = getParent(); + while(p != null) { + if(p instanceof XMLSlideShow){ + return (XMLSlideShow)p; + } + p = p.getParent(); + } + throw new IllegalStateException("SlideShow was not found"); + } + + private PackagePart createWorksheetPart() throws InvalidFormatException { + Integer chartIdx = XSLFRelation.CHART.getFileNameIndex(this); + return getTargetPart(getSlideShow().createWorkbookRelationship(this, chartIdx)); + } + + protected void saveWorkbook(XSSFWorkbook workbook) throws IOException, InvalidFormatException { + PackagePart worksheetPart = getWorksheetPart(); + if (worksheetPart == null) { + worksheetPart = createWorksheetPart(); + } + try (OutputStream xlsOut = worksheetPart.getOutputStream()) { + workbook.write(xlsOut); + } + } + + private void fillSheet(XSSFSheet sheet, XDDFDataSource categoryData, XDDFNumericalDataSource valuesData) { + int numOfPoints = categoryData.getPointCount(); + for (int i = 0; i < numOfPoints; i++) { + XSSFRow row = sheet.createRow(i + 1); // first row is for title + row.createCell(0).setCellValue(categoryData.getPointAt(i).toString()); + row.createCell(1).setCellValue(valuesData.getPointAt(i).doubleValue()); + } + } + + @Override + public void plot(XDDFChartData data) { + super.plot(data); + XSSFSheet sheet = getSheet(); + for(XDDFChartData.Series series : data.getSeries()) { + fillSheet(sheet, series.getCategoryData(), series.getValuesData()); + } + } + + public void importContent(XSLFChart other) { + this.chart.set(other.chart); + } + + @Override + protected void commit() throws IOException { + XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); + xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c")); + + if (workbook != null) { + try { + saveWorkbook(workbook); + } catch (InvalidFormatException e) { + throw new POIXMLException(e); + } + } + + PackagePart part = getPackagePart(); + try (OutputStream out = part.getOutputStream()) { + chartSpace.save(out, xmlOptions); + } + } } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java index 89aae95a2f..f08e1d1de4 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java @@ -20,6 +20,7 @@ package org.apache.poi.xslf.usermodel; import java.awt.geom.Rectangle2D; +import java.io.IOException; import javax.xml.namespace.QName; @@ -102,6 +103,7 @@ public class XSLFGraphicFrame extends XSLFShape implements GraphicalFrame { private static POILogger LOG = POILogFactory.getLogger(XSLFSheet.class); - + private XSLFDrawing _drawing; private List _shapes; private CTGroupShape _spTree; @@ -69,13 +69,13 @@ implements XSLFShapeContainer, Sheet { public XSLFSheet() { super(); } - + /** * @since POI 3.14-Beta1 */ public XSLFSheet(PackagePart part) { super(part); - } + } /** * @return the XMLSlideShow this sheet belongs to @@ -155,7 +155,7 @@ implements XSLFShapeContainer, Sheet { initDrawingAndShapes(); return _shapes; } - + /** * Helper method for initializing drawing and shapes in one go. * If they are initialized separately, there's a risk that shapes @@ -255,7 +255,7 @@ implements XSLFShapeContainer, Sheet { return sh; } - + /** * Returns an iterator over the shapes in this sheet * @@ -272,7 +272,7 @@ implements XSLFShapeContainer, Sheet { "Adding a shape from a different container is not supported -" + " create it from scratch witht XSLFSheet.create* methods"); } - + /** * Removes the specified shape from this sheet, if it is present * (optional operation). If this sheet does not contain the element, @@ -356,28 +356,35 @@ implements XSLFShapeContainer, Sheet { * @return modified 'this' */ public XSLFSheet importContent(XSLFSheet src){ - _shapes = null; - _spTree = null; - _drawing = null; _spTree = null; - _placeholders = null; - // fix-me: wth would this ever happen to work ... - - // first copy the source xml - getSpTree().set(src.getSpTree()); + getSpTree().set(src.getSpTree().copy()); + + wipeAndReinitialize(src, 0); - // recursively update each shape + return this; + } + + private void wipeAndReinitialize(XSLFSheet src, int offset) { + // explicitly initialize drawing and shapes from _spTree + _shapes = null; + _drawing = null; + initDrawingAndShapes(); + + // placeholders will be implicitly initialized when requested + _placeholders = null; + + // update each shape according to its own additional copy rules List tgtShapes = getShapes(); List srcShapes = src.getShapes(); - for(int i = 0; i < tgtShapes.size(); i++){ + for(int i = 0; i < srcShapes.size(); i++){ XSLFShape s1 = srcShapes.get(i); - XSLFShape s2 = tgtShapes.get(i); + XSLFShape s2 = tgtShapes.get(offset + i); s2.copy(s1); } - return this; + } /** @@ -387,39 +394,26 @@ implements XSLFShapeContainer, Sheet { * @return modified this. */ public XSLFSheet appendContent(XSLFSheet src){ - CTGroupShape spTree = getSpTree(); int numShapes = getShapes().size(); - + CTGroupShape spTree = getSpTree(); CTGroupShape srcTree = src.getSpTree(); + for(XmlObject ch : srcTree.selectPath("*")){ if(ch instanceof CTShape){ // simple shape - spTree.addNewSp().set(ch); + spTree.addNewSp().set(ch.copy()); } else if (ch instanceof CTGroupShape){ - spTree.addNewGrpSp().set(ch); + spTree.addNewGrpSp().set(ch.copy()); } else if (ch instanceof CTConnector){ - spTree.addNewCxnSp().set(ch); + spTree.addNewCxnSp().set(ch.copy()); } else if (ch instanceof CTPicture){ - spTree.addNewPic().set(ch); + spTree.addNewPic().set(ch.copy()); } else if (ch instanceof CTGraphicalObjectFrame){ - spTree.addNewGraphicFrame().set(ch); + spTree.addNewGraphicFrame().set(ch.copy()); } } - _shapes = null; - _spTree = null; - _drawing = null; - _spTree = null; - _placeholders = null; - - // recursively update each shape - List tgtShapes = getShapes(); - List srcShapes = src.getShapes(); - for(int i = 0; i < srcShapes.size(); i++){ - XSLFShape s1 = srcShapes.get(i); - XSLFShape s2 = tgtShapes.get(numShapes + i); + wipeAndReinitialize(src, numShapes); - s2.copy(s1); - } return this; } @@ -430,7 +424,7 @@ implements XSLFShapeContainer, Sheet { * method and return the corresponding package part. */ XSLFTheme getTheme(){ - return null; + return null; } protected XSLFTextShape getTextShapeByType(Placeholder type){ @@ -574,7 +568,7 @@ implements XSLFShapeContainer, Sheet { PackagePart pic = pictureData.getPackagePart(); RelationPart rp = addRelation(blipId, XSLFRelation.IMAGES, new XSLFPictureData(pic)); - + return rp.getRelationship().getId(); } @@ -584,13 +578,13 @@ implements XSLFShapeContainer, Sheet { PackagePart importPart(PackageRelationship srcRel, PackagePart srcPafrt) { PackagePart destPP = getPackagePart(); PackagePartName srcPPName = srcPafrt.getPartName(); - + OPCPackage pkg = destPP.getPackage(); if(pkg.containPart(srcPPName)){ // already exists return pkg.getPart(srcPPName); - } - + } + destPP.addRelationship(srcPPName, TargetMode.INTERNAL, srcRel.getRelationshipType()); PackagePart part = pkg.createPart(srcPPName, srcPafrt.getContentType()); @@ -605,7 +599,7 @@ implements XSLFShapeContainer, Sheet { } return part; } - + /** * Helper method for sheet and group shapes * @@ -614,4 +608,4 @@ implements XSLFShapeContainer, Sheet { void removePictureRelation(XSLFPictureShape pictureShape) { removeRelation(pictureShape.getBlipId()); } -} \ No newline at end of file +} diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java index 53b645a868..7c3d1f66cf 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java @@ -49,10 +49,10 @@ import org.xml.sax.SAXException; @Beta public final class XSLFSlide extends XSLFSheet implements Slide { - private final CTSlide _slide; - private XSLFSlideLayout _layout; - private XSLFComments _comments; - private XSLFNotes _notes; + private final CTSlide _slide; + private XSLFSlideLayout _layout; + private XSLFComments _comments; + private XSLFNotes _notes; /** * Create a new slide @@ -67,7 +67,7 @@ implements Slide { * * @param part the package part holding the slide data, * the content type must be application/vnd.openxmlformats-officedocument.slide+xml - * + * * @since POI 3.14-Beta1 */ XSLFSlide(PackagePart part) throws IOException, XmlException { @@ -79,11 +79,11 @@ implements Slide { } catch (SAXException e) { throw new IOException(e); } - + SldDocument doc = SldDocument.Factory.parse(_doc, DEFAULT_XML_OPTIONS); _slide = doc.getSld(); } - + private static CTSlide prototype(){ CTSlide ctSlide = CTSlide.Factory.newInstance(); CTCommonSlideData cSld = ctSlide.addNewCSld(); @@ -115,13 +115,21 @@ implements Slide { } @Override - public CTSlide getXmlObject() { - return _slide; - } + public CTSlide getXmlObject() { + return _slide; + } @Override protected String getRootElementName(){ - return "sld"; + return "sld"; + } + + protected void removeChartRelation(XSLFChart chart) { + removeRelation(chart); + } + + protected void removeLayoutRelation(XSLFSlideLayout layout) { + removeRelation(layout, false); } @Override @@ -131,9 +139,9 @@ implements Slide { public XSLFSlideLayout getSlideLayout(){ if(_layout == null){ - for (POIXMLDocumentPart p : getRelations()) { + for (POIXMLDocumentPart p : getRelations()) { if (p instanceof XSLFSlideLayout){ - _layout = (XSLFSlideLayout)p; + _layout = (XSLFSlideLayout)p; } } } @@ -148,36 +156,36 @@ implements Slide { } public XSLFComments getComments() { - if(_comments == null) { - for (POIXMLDocumentPart p : getRelations()) { - if (p instanceof XSLFComments) { - _comments = (XSLFComments)p; - } - } - } - if(_comments == null) { - // This slide lacks comments - // Not all have them, sorry... - return null; - } - return _comments; + if(_comments == null) { + for (POIXMLDocumentPart p : getRelations()) { + if (p instanceof XSLFComments) { + _comments = (XSLFComments)p; + } + } + } + if(_comments == null) { + // This slide lacks comments + // Not all have them, sorry... + return null; + } + return _comments; } @Override public XSLFNotes getNotes() { - if(_notes == null) { - for (POIXMLDocumentPart p : getRelations()) { - if (p instanceof XSLFNotes){ - _notes = (XSLFNotes)p; - } - } - } - if(_notes == null) { - // This slide lacks notes - // Not all have them, sorry... - return null; - } - return _notes; + if(_notes == null) { + for (POIXMLDocumentPart p : getRelations()) { + if (p instanceof XSLFNotes){ + _notes = (XSLFNotes)p; + } + } + } + if(_notes == null) { + // This slide lacks notes + // Not all have them, sorry... + return null; + } + return _notes; } @Override @@ -185,10 +193,10 @@ implements Slide { XSLFTextShape txt = getTextShapeByType(Placeholder.TITLE); return txt == null ? null : txt.getText(); } - + @Override public XSLFTheme getTheme(){ - return getSlideLayout().getSlideMaster().getTheme(); + return getSlideLayout().getSlideMaster().getTheme(); } /** @@ -241,7 +249,7 @@ implements Slide { if (bgOther == null) { return this; } - + CTBackground bgThis = _slide.getCSld().getBg(); // remove existing background if (bgThis != null) { @@ -251,14 +259,14 @@ implements Slide { } _slide.getCSld().unsetBg(); } - + bgThis = (CTBackground)_slide.getCSld().addNewBg().set(bgOther); - + if(bgOther.isSetBgPr() && bgOther.getBgPr().isSetBlipFill()){ String idOther = bgOther.getBgPr().getBlipFill().getBlip().getEmbed(); String idThis = importBlip(idOther, src.getPackagePart()); bgThis.getBgPr().getBlipFill().getBlip().setEmbed(idThis); - + } return this; @@ -294,7 +302,7 @@ implements Slide { assert(notes instanceof XSLFNotes); // TODO Auto-generated method stub } - + @Override public int getSlideNumber() { int idx = getSlideShow().getSlides().indexOf(this); diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java index 3a645f7676..dbaf370e30 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java @@ -19,7 +19,6 @@ package org.apache.poi.xssf.streaming; import java.util.Iterator; -import org.apache.poi.ss.usermodel.Chart; import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.Comment; import org.apache.poi.ss.usermodel.Drawing; @@ -53,11 +52,6 @@ public class SXSSFDrawing implements Drawing { return _drawing.createCellComment(anchor); } - @Override - public Chart createChart(ClientAnchor anchor) { - return _drawing.createChart(anchor); - } - @Override public ClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2) { return _drawing.createAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2); 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 55f71479f7..a0a728da58 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java @@ -26,15 +26,13 @@ import java.util.List; import javax.xml.namespace.QName; -import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.charts.AxisPosition; import org.apache.poi.ss.usermodel.charts.ChartAxis; import org.apache.poi.ss.usermodel.charts.ChartAxisFactory; import org.apache.poi.ss.usermodel.charts.ChartData; -import org.apache.poi.util.Internal; import org.apache.poi.util.Removal; +import org.apache.poi.xddf.usermodel.chart.XDDFChart; import org.apache.poi.xssf.usermodel.charts.XSSFCategoryAxis; import org.apache.poi.xssf.usermodel.charts.XSSFChartAxis; import org.apache.poi.xssf.usermodel.charts.XSSFChartDataFactory; @@ -46,7 +44,6 @@ import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; import org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace; import org.openxmlformats.schemas.drawingml.x2006.chart.CTDateAx; import org.openxmlformats.schemas.drawingml.x2006.chart.CTPageMargins; @@ -56,7 +53,6 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrRef; import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle; import org.openxmlformats.schemas.drawingml.x2006.chart.CTTx; import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx; -import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument; import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField; @@ -68,139 +64,119 @@ import org.w3c.dom.Text; /** * Represents a SpreadsheetML Chart */ -public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartAxisFactory { +public final class XSSFChart extends XDDFChart 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 = new ArrayList<>(); - - /** - * Create a new SpreadsheetML chart - */ - protected XSSFChart() { - super(); - createChart(); - } + /** + * Parent graphic frame. + */ + private XSSFGraphicFrame frame; - /** - * 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 - * - * @since POI 3.14-Beta1 - */ - protected XSSFChart(PackagePart part) throws IOException, XmlException { - super(part); + @Deprecated + @Removal(version="4.2") + List axis = new ArrayList<>(); - chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream(), DEFAULT_XML_OPTIONS).getChartSpace(); - chart = chartSpace.getChart(); - } - - /** - * Construct a new CTChartSpace bean. - * By default, it's just an empty placeholder for chart objects. - */ - private void createChart() { - chartSpace = CTChartSpace.Factory.newInstance(); - chart = chartSpace.addNewChart(); - CTPlotArea plotArea = chart.addNewPlotArea(); - - plotArea.addNewLayout(); - 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(); - } + /** + * Create a new SpreadsheetML chart + */ + protected XSSFChart() { + super(); + createChart(); + } - /** - * Return the underlying CTChartSpace bean, the root element of the SpreadsheetML Chart part. - * - * @return the underlying CTChartSpace bean - */ - @Internal - public CTChartSpace getCTChartSpace(){ - return chartSpace; - } + /** + * 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 + * + * @since POI 3.14-Beta1 + */ + protected XSSFChart(PackagePart part) throws IOException, XmlException { + super(part); + } - /** - * Return the underlying CTChart bean, within the Chart Space - * - * @return the underlying CTChart bean - */ - @Internal - public CTChart getCTChart(){ - return chart; - } + /** + * Construct a new CTChartSpace bean. By default, it's just an empty placeholder for chart objects. + */ + private void createChart() { + CTPlotArea plotArea = getCTPlotArea(); + + plotArea.addNewLayout(); + 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(); + } - @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")); - - PackagePart part = getPackagePart(); - OutputStream out = part.getOutputStream(); - chartSpace.save(out, xmlOptions); - out.close(); - } + @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")); + + PackagePart part = getPackagePart(); + try (OutputStream out = part.getOutputStream()) { + chartSpace.save(out, xmlOptions); + } + } - /** - * Returns the parent graphic frame. - * @return the graphic frame this chart belongs to - */ - public XSSFGraphicFrame getGraphicFrame() { - return frame; - } + /** + * 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; - } + /** + * Sets the parent graphic frame. + */ + protected void setGraphicFrame(XSSFGraphicFrame frame) { + this.frame = frame; + } + @Override + @Deprecated + @Removal(version="4.2") public XSSFChartDataFactory getChartDataFactory() { return XSSFChartDataFactory.getInstance(); } + @Override + @Deprecated + @Removal(version="4.2") public XSSFChart getChartAxisFactory() { return this; } + @Override + @Deprecated + @Removal(version="4.2") public void plot(ChartData data, ChartAxis... chartAxis) { data.fillChart(this, chartAxis); } - public XSSFValueAxis createValueAxis(AxisPosition pos) { + @Override + @Deprecated + @Removal(version="4.2") + public XSSFValueAxis createValueAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { long id = axis.size() + 1; XSSFValueAxis valueAxis = new XSSFValueAxis(this, id, pos); if (axis.size() == 1) { @@ -212,7 +188,10 @@ public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartA return valueAxis; } - public XSSFCategoryAxis createCategoryAxis(AxisPosition pos) { + @Override + @Deprecated + @Removal(version="4.2") + public XSSFCategoryAxis createCategoryAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { long id = axis.size() + 1; XSSFCategoryAxis categoryAxis = new XSSFCategoryAxis(this, id, pos); if (axis.size() == 1) { @@ -224,45 +203,41 @@ public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartA return categoryAxis; } - public XSSFDateAxis createDateAxis(AxisPosition pos) { - long id = axis.size() + 1; - XSSFDateAxis dateAxis = new XSSFDateAxis(this, id, pos); - if (axis.size() == 1) { - ChartAxis ax = axis.get(0); - ax.crossAxis(dateAxis); - dateAxis.crossAxis(ax); - } - axis.add(dateAxis); - return dateAxis; + @Override + @Deprecated + @Removal(version="4.2") + public XSSFDateAxis createDateAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) { + long id = axis.size() + 1; + XSSFDateAxis dateAxis = new XSSFDateAxis(this, id, pos); + if (axis.size() == 1) { + ChartAxis ax = axis.get(0); + ax.crossAxis(dateAxis); + dateAxis.crossAxis(ax); + } + axis.add(dateAxis); + return dateAxis; } - + + /** + * @deprecated use {@link getAxes} instead + */ + @Override + @Deprecated + @Removal(version="4.2") public List getAxis() { if (axis.isEmpty() && hasAxis()) { parseAxis(); } return axis; } - + + @Override + @Deprecated + @Removal(version="4.2") public XSSFManualLayout getManualLayout() { return new XSSFManualLayout(this); } - /** - * @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 static text, or null if none is set. * Note that a title formula may be set instead. @@ -274,14 +249,14 @@ public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartA public XSSFRichTextString getTitle() { return getTitleText(); } - + /** * Returns the title static text, or null if none is set. * Note that a title formula may be set instead. * Empty text result is for backward compatibility, and could mean the title text is empty or there is a formula instead. * Check for a formula first, falling back on text for cleaner logic. - * @return static title text if set, - * null if there is no title, + * @return static title text if set, + * null if there is no title, * empty string if the title text is empty or the title uses a formula instead */ public XSSFRichTextString getTitleText() { @@ -295,8 +270,8 @@ public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartA StringBuilder text = new StringBuilder(64); 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 (XmlObject element : t) { + NodeList kids = element.getDomNode().getChildNodes(); final int count = kids.getLength(); for (int n = 0; n < count; n++) { Node kid = kids.item(n); @@ -315,161 +290,169 @@ public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartA * @deprecated POI 3.16, use {@link #setTitleText(String)} instead. */ @Deprecated - @Removal(version="4.0") - public void setTitle(String newTitle) { - - } - + @Removal(version = "4.0") + public void setTitle(String newTitle) { + + } + /** * Sets the title text as a static string. - * @param newTitle to use + * + * @param newTitle + * to use */ - public void setTitleText(String newTitle) { - CTTitle ctTitle; - if (chart.isSetTitle()) { - ctTitle = chart.getTitle(); - } else { - ctTitle = chart.addNewTitle(); - } + public void setTitleText(String newTitle) { + CTTitle ctTitle; + if (chart.isSetTitle()) { + ctTitle = chart.getTitle(); + } else { + ctTitle = chart.addNewTitle(); + } - CTTx tx; - if (ctTitle.isSetTx()) { - tx = ctTitle.getTx(); - } else { - tx = ctTitle.addNewTx(); - } + CTTx tx; + if (ctTitle.isSetTx()) { + tx = ctTitle.getTx(); + } else { + tx = ctTitle.addNewTx(); + } - if (tx.isSetStrRef()) { - tx.unsetStrRef(); - } + if (tx.isSetStrRef()) { + tx.unsetStrRef(); + } - CTTextBody rich; - if (tx.isSetRich()) { - rich = tx.getRich(); - } else { - rich = tx.addNewRich(); - rich.addNewBodyPr(); // body properties must exist (but can be empty) - } + CTTextBody rich; + if (tx.isSetRich()) { + rich = tx.getRich(); + } else { + rich = tx.addNewRich(); + rich.addNewBodyPr(); // body properties must exist (but can be + // empty) + } - CTTextParagraph para; - if (rich.sizeOfPArray() > 0) { - para = rich.getPArray(0); - } else { - para = rich.addNewP(); - } + CTTextParagraph para; + if (rich.sizeOfPArray() > 0) { + para = rich.getPArray(0); + } else { + para = rich.addNewP(); + } - if (para.sizeOfRArray() > 0) { - CTRegularTextRun run = para.getRArray(0); - run.setT(newTitle); - } else if (para.sizeOfFldArray() > 0) { - CTTextField fld = para.getFldArray(0); - fld.setT(newTitle); - } else { - CTRegularTextRun run = para.addNewR(); - run.setT(newTitle); - } - } - - /** - * Get the chart title formula expression if there is one - * @return formula expression or null - */ - public String getTitleFormula() { - if(! chart.isSetTitle()) { - return null; - } - - CTTitle title = chart.getTitle(); - - if (! title.isSetTx()) { - return null; - } - - CTTx tx = title.getTx(); - - if (! tx.isSetStrRef()) { - return null; - } - - return tx.getStrRef().getF(); - } - - /** - * Set the formula expression to use for the chart title - * @param formula - */ - public void setTitleFormula(String formula) { - CTTitle ctTitle; - if (chart.isSetTitle()) { - ctTitle = chart.getTitle(); - } else { - ctTitle = chart.addNewTitle(); - } - - CTTx tx; - if (ctTitle.isSetTx()) { - tx = ctTitle.getTx(); - } else { - tx = ctTitle.addNewTx(); - } - - if (tx.isSetRich()) { - tx.unsetRich(); - } - - CTStrRef strRef; - if (tx.isSetStrRef()) { - strRef = tx.getStrRef(); - } else { - strRef = tx.addNewStrRef(); - } - - strRef.setF(formula); - } + if (para.sizeOfRArray() > 0) { + CTRegularTextRun run = para.getRArray(0); + run.setT(newTitle); + } else if (para.sizeOfFldArray() > 0) { + CTTextField fld = para.getFldArray(0); + fld.setT(newTitle); + } else { + CTRegularTextRun run = para.addNewR(); + run.setT(newTitle); + } + } + + /** + * Get the chart title formula expression if there is one + * + * @return formula expression or null + */ + public String getTitleFormula() { + if (!chart.isSetTitle()) { + return null; + } + + CTTitle title = chart.getTitle(); + + if (!title.isSetTx()) { + return null; + } + + CTTx tx = title.getTx(); + + if (!tx.isSetStrRef()) { + return null; + } + return tx.getStrRef().getF(); + } + + /** + * Set the formula expression to use for the chart title + * + * @param formula + */ + public void setTitleFormula(String formula) { + CTTitle ctTitle; + if (chart.isSetTitle()) { + ctTitle = chart.getTitle(); + } else { + ctTitle = chart.addNewTitle(); + } + + CTTx tx; + if (ctTitle.isSetTx()) { + tx = ctTitle.getTx(); + } else { + tx = ctTitle.addNewTx(); + } + + if (tx.isSetRich()) { + tx.unsetRich(); + } + + CTStrRef strRef; + if (tx.isSetStrRef()) { + strRef = tx.getStrRef(); + } else { + strRef = tx.addNewStrRef(); + } + + strRef.setF(formula); + } + + @Override + @Deprecated + @Removal(version="4.2") public XSSFChartLegend getOrCreateLegend() { return new XSSFChartLegend(this); } - public void deleteLegend() { - if (chart.isSetLegend()) { - chart.unsetLegend(); - } - } - + @Deprecated + @Removal(version="4.2") private boolean hasAxis() { - CTPlotArea ctPlotArea = chart.getPlotArea(); - int totalAxisCount = - ctPlotArea.sizeOfValAxArray() + - ctPlotArea.sizeOfCatAxArray() + - ctPlotArea.sizeOfDateAxArray() + - ctPlotArea.sizeOfSerAxArray(); - return totalAxisCount > 0; + CTPlotArea ctPlotArea = chart.getPlotArea(); + int totalAxisCount = ctPlotArea.sizeOfValAxArray() + ctPlotArea.sizeOfCatAxArray() + ctPlotArea.sizeOfDateAxArray() + ctPlotArea.sizeOfSerAxArray(); + return totalAxisCount > 0; } - private void parseAxis() { - // TODO: add other axis types - parseCategoryAxis(); - parseDateAxis(); - parseValueAxis(); - } + @Deprecated + @Removal(version="4.2") + private void parseAxis() { + // TODO: add other axis types + parseCategoryAxis(); + parseDateAxis(); + parseValueAxis(); + } - private void parseCategoryAxis() { - for (CTCatAx catAx : chart.getPlotArea().getCatAxArray()) { - axis.add(new XSSFCategoryAxis(this, catAx)); - } - } + @Deprecated + @Removal(version="4.2") + private void parseCategoryAxis() { + for (CTCatAx catAx : chart.getPlotArea().getCatAxArray()) { + axis.add(new XSSFCategoryAxis(this, catAx)); + } + } - private void parseDateAxis() { - for (CTDateAx dateAx : chart.getPlotArea().getDateAxArray()) { - axis.add(new XSSFDateAxis(this, dateAx)); - } - } - - private void parseValueAxis() { - for (CTValAx valAx : chart.getPlotArea().getValAxArray()) { - axis.add(new XSSFValueAxis(this, valAx)); - } - } + @Deprecated + @Removal(version="4.2") + private void parseDateAxis() { + for (CTDateAx dateAx : chart.getPlotArea().getDateAxArray()) { + axis.add(new XSSFDateAxis(this, dateAx)); + } + } + + @Deprecated + @Removal(version="4.2") + private void parseValueAxis() { + for (CTValAx valAx : chart.getPlotArea().getValAxArray()) { + axis.add(new XSSFValueAxis(this, valAx)); + } + } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java index 5c88adb316..0bcc8ec168 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java @@ -239,7 +239,12 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing series; public XSSFLineChartData() { - series = new ArrayList<>(); + series = new ArrayList(); } static class Series extends AbstractXSSFChartSeries implements LineChartSeries { @@ -64,10 +68,12 @@ public class XSSFLineChartData implements LineChartData { this.values = values; } + @Override public ChartDataSource getCategoryAxisData() { return categories; } + @Override public ChartDataSource getValues() { return values; } @@ -91,6 +97,7 @@ public class XSSFLineChartData implements LineChartData { } } + @Override public LineChartSeries addSeries(ChartDataSource categoryAxisData, ChartDataSource values) { if (!values.isNumeric()) { throw new IllegalArgumentException("Value data source must be numeric."); @@ -101,10 +108,12 @@ public class XSSFLineChartData implements LineChartData { return newSeries; } + @Override public List getSeries() { return series; } + @Override public void fillChart(Chart chart, ChartAxis... axis) { if (!(chart instanceof XSSFChart)) { throw new IllegalArgumentException("Chart must be instance of XSSFChart"); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFManualLayout.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFManualLayout.java index 76eaa45f9d..1f5b66b43c 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFManualLayout.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFManualLayout.java @@ -17,25 +17,27 @@ package org.apache.poi.xssf.usermodel.charts; -import org.apache.poi.util.Beta; -import org.apache.poi.util.Internal; -import org.apache.poi.ss.usermodel.charts.ManualLayout; import org.apache.poi.ss.usermodel.charts.LayoutMode; import org.apache.poi.ss.usermodel.charts.LayoutTarget; +import org.apache.poi.ss.usermodel.charts.ManualLayout; +import org.apache.poi.util.Internal; +import org.apache.poi.util.Removal; +import org.apache.poi.xddf.usermodel.chart.XDDFManualLayout; import org.apache.poi.xssf.usermodel.XSSFChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget; import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayout; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTManualLayout; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayoutMode; import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayoutTarget; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTManualLayout; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutMode; +import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget; /** * Represents a SpreadsheetML manual layout. - * @author Roman Kashitsyn + * @deprecated use {@link XDDFManualLayout instead} */ -@Beta +@Deprecated +@Removal(version="4.2") public final class XSSFManualLayout implements ManualLayout { /** @@ -75,126 +77,144 @@ public final class XSSFManualLayout implements ManualLayout { return layout; } - public void setWidthRatio(double ratio) { + @Override + public void setWidthRatio(double ratio) { if (!layout.isSetW()) { layout.addNewW(); } layout.getW().setVal(ratio); } - public double getWidthRatio() { + @Override + public double getWidthRatio() { if (!layout.isSetW()) { return 0.0; } return layout.getW().getVal(); } - public void setHeightRatio(double ratio) { + @Override + public void setHeightRatio(double ratio) { if (!layout.isSetH()) { layout.addNewH(); } layout.getH().setVal(ratio); } - public double getHeightRatio() { + @Override + public double getHeightRatio() { if (!layout.isSetH()) { return 0.0; } return layout.getH().getVal(); } - public LayoutTarget getTarget() { + @Override + public LayoutTarget getTarget() { if (!layout.isSetLayoutTarget()) { return defaultLayoutTarget; } return toLayoutTarget(layout.getLayoutTarget()); } - public void setTarget(LayoutTarget target) { + @Override + public void setTarget(LayoutTarget target) { if (!layout.isSetLayoutTarget()) { layout.addNewLayoutTarget(); } layout.getLayoutTarget().setVal(fromLayoutTarget(target)); } - public LayoutMode getXMode() { + @Override + public LayoutMode getXMode() { if (!layout.isSetXMode()) { return defaultLayoutMode; } return toLayoutMode(layout.getXMode()); } - public void setXMode(LayoutMode mode) { + @Override + public void setXMode(LayoutMode mode) { if (!layout.isSetXMode()) { layout.addNewXMode(); } layout.getXMode().setVal(fromLayoutMode(mode)); } - public LayoutMode getYMode() { + @Override + public LayoutMode getYMode() { if (!layout.isSetYMode()) { return defaultLayoutMode; } return toLayoutMode(layout.getYMode()); } - public void setYMode(LayoutMode mode) { + @Override + public void setYMode(LayoutMode mode) { if (!layout.isSetYMode()) { layout.addNewYMode(); } layout.getYMode().setVal(fromLayoutMode(mode)); } - public double getX() { + @Override + public double getX() { if (!layout.isSetX()) { return 0.0; } return layout.getX().getVal(); } - public void setX(double x) { + @Override + public void setX(double x) { if (!layout.isSetX()) { layout.addNewX(); } layout.getX().setVal(x); } - public double getY() { + @Override + public double getY() { if (!layout.isSetY()) { return 0.0; } return layout.getY().getVal(); } - public void setY(double y) { + @Override + public void setY(double y) { if (!layout.isSetY()) { layout.addNewY(); } layout.getY().setVal(y); } - public LayoutMode getWidthMode() { + @Override + public LayoutMode getWidthMode() { if (!layout.isSetWMode()) { return defaultLayoutMode; } return toLayoutMode(layout.getWMode()); } - public void setWidthMode(LayoutMode mode) { + @Override + public void setWidthMode(LayoutMode mode) { if (!layout.isSetWMode()) { layout.addNewWMode(); } layout.getWMode().setVal(fromLayoutMode(mode)); } - public LayoutMode getHeightMode() { + @Override + public LayoutMode getHeightMode() { if (!layout.isSetHMode()) { return defaultLayoutMode; } return toLayoutMode(layout.getHMode()); } - public void setHeightMode(LayoutMode mode) { + @Override + public void setHeightMode(LayoutMode mode) { if (!layout.isSetHMode()) { layout.addNewHMode(); } 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 b192c36bd9..98d9f8fd10 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 @@ -25,7 +25,8 @@ import org.apache.poi.ss.usermodel.charts.ChartAxis; import org.apache.poi.ss.usermodel.charts.ChartDataSource; import org.apache.poi.ss.usermodel.charts.ScatterChartData; import org.apache.poi.ss.usermodel.charts.ScatterChartSeries; -import org.apache.poi.util.Beta; +import org.apache.poi.util.Removal; +import org.apache.poi.xddf.usermodel.chart.XDDFScatterChartData; import org.apache.poi.xssf.usermodel.XSSFChart; import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; @@ -38,8 +39,11 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.STScatterStyle; /** * Represents DrawingML scatter charts. + * + * @deprecated use {@link XDDFScatterChartData} instead */ -@Beta +@Deprecated +@Removal(version="4.2") public class XSSFScatterChartData implements ScatterChartData { /** @@ -48,7 +52,7 @@ public class XSSFScatterChartData implements ScatterChartData { private List series; public XSSFScatterChartData() { - series = new ArrayList<>(); + series = new ArrayList(); } /** @@ -74,6 +78,7 @@ public class XSSFScatterChartData implements ScatterChartData { * Returns data source used for X axis values. * @return data source used for X axis values */ + @Override public ChartDataSource getXValues() { return xs; } @@ -82,6 +87,7 @@ public class XSSFScatterChartData implements ScatterChartData { * Returns data source used for Y axis values. * @return data source used for Y axis values */ + @Override public ChartDataSource getYValues() { return ys; } @@ -103,6 +109,7 @@ public class XSSFScatterChartData implements ScatterChartData { } } + @Override public ScatterChartSeries addSerie(ChartDataSource xs, ChartDataSource ys) { if (!ys.isNumeric()) { @@ -114,6 +121,7 @@ public class XSSFScatterChartData implements ScatterChartData { return newSerie; } + @Override public void fillChart(Chart chart, ChartAxis... axis) { if (!(chart instanceof XSSFChart)) { throw new IllegalArgumentException("Chart must be instance of XSSFChart"); @@ -133,6 +141,7 @@ public class XSSFScatterChartData implements ScatterChartData { } } + @Override public List getSeries() { return series; } 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 3dea67ddb4..14f16d4a11 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 @@ -24,8 +24,9 @@ import org.apache.poi.ss.usermodel.charts.AxisPosition; import org.apache.poi.ss.usermodel.charts.AxisTickMark; import org.apache.poi.ss.usermodel.charts.ChartAxis; import org.apache.poi.ss.usermodel.charts.ValueAxis; -import org.apache.poi.util.Beta; import org.apache.poi.util.Internal; +import org.apache.poi.util.Removal; +import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis; import org.apache.poi.xssf.usermodel.XSSFChart; import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos; import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean; @@ -42,9 +43,10 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; /** * Value axis type. * - * @author Roman Kashitsyn + * @deprecated use {@link XDDFValueAxis} instead */ -@Beta +@Deprecated +@Removal(version="4.2") public class XSSFValueAxis extends XSSFChartAxis implements ValueAxis { private CTValAx ctValAx; diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFChart.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFChart.java index e7df6ec69f..dbc68c2155 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFChart.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFChart.java @@ -22,39 +22,23 @@ import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.Arrays; import javax.xml.namespace.QName; -import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLException; -import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.util.Beta; import org.apache.poi.util.IOUtils; -import org.apache.poi.util.Internal; +import org.apache.poi.xddf.usermodel.chart.XDDFChart; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace; -import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument; /** * Represents a Chart in a .docx file */ @Beta -public class XWPFChart extends POIXMLDocumentPart { - - /** - * Root element of the Chart part - */ - private final CTChartSpace chartSpace; - - /** - * The Chart within that - */ - private final CTChart chart; +public class XWPFChart extends XDDFChart { // lazy initialization private Long checksum; @@ -64,39 +48,11 @@ public class XWPFChart extends POIXMLDocumentPart { * * @param part the package part holding the chart data, * the content type must be application/vnd.openxmlformats-officedocument.drawingml.chart+xml - * + * * @since POI 4.0.0 */ protected XWPFChart(PackagePart part) throws IOException, XmlException { super(part); - - chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream(), DEFAULT_XML_OPTIONS).getChartSpace(); - chart = chartSpace.getChart(); - } - - @Override - protected void onDocumentRead() throws IOException { - super.onDocumentRead(); - } - - /** - * Return the underlying CTChartSpace bean, the root element of the 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 @@ -108,7 +64,7 @@ public class XWPFChart extends POIXMLDocumentPart { chartSpace.save(out, xmlOptions); } } - + public Long getChecksum() { if (this.checksum == null) { InputStream is = null; @@ -120,7 +76,9 @@ public class XWPFChart extends POIXMLDocumentPart { throw new POIXMLException(e); } finally { try { - if (is != null) is.close(); + if (is != null) { + is.close(); + } } catch (IOException e) { throw new POIXMLException(e); } @@ -157,7 +115,7 @@ public class XWPFChart extends POIXMLDocumentPart { } return false; } - + @Override public int hashCode() { return getChecksum().hashCode(); diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java index e63b98995d..2b3c3eda7b 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java @@ -63,7 +63,27 @@ import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTComment; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CommentsDocument; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.DocumentDocument; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.EndnotesDocument; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.FootnotesDocument; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.NumberingDocument; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.STDocProtect; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument; /** *

High(ish) level class for working with .docx files.

@@ -79,7 +99,7 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; */ public class XWPFDocument extends POIXMLDocument implements Document, IBody { private static final POILogger LOG = POILogFactory.getLogger(XWPFDocument.class); - + protected List footers = new ArrayList<>(); protected List headers = new ArrayList<>(); protected List comments = new ArrayList<>(); @@ -186,8 +206,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { } docCursor.dispose(); // Sort out headers and footers - if (doc.getDocument().getBody().getSectPr() != null) + if (doc.getDocument().getBody().getSectPr() != null) { headerFooterPolicy = new XWPFHeaderFooterPolicy(this); + } // Create for each XML-part in the Package a PartClass for (RelationPart rp : getRelationParts()) { @@ -224,7 +245,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { } else if (relation.equals(XWPFRelation.CHART.getRelation())) { //now we can use all methods to modify charts in XWPFDocument XWPFChart chartData = (XWPFChart) p; - chartData.onDocumentRead(); +// chartData.onDocumentRead(); // ??? there is nothing to be done there!!! charts.add(chartData); } else if (relation.equals(XWPFRelation.GLOSSARY_DOCUMENT.getRelation())) { // We don't currently process the glossary itself @@ -380,20 +401,25 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { public XWPFHyperlink getHyperlinkByID(String id) { for (XWPFHyperlink link : hyperlinks) { - if (link.getId().equals(id)) + if (link.getId().equals(id)) { return link; + } } return null; } public XWPFFootnote getFootnoteByID(int id) { - if (footnotes == null) return null; + if (footnotes == null) { + return null; + } return footnotes.getFootnoteById(id); } public XWPFFootnote getEndnoteByID(int id) { - if (endnotes == null) return null; + if (endnotes == null) { + return null; + } return endnotes.get(id); } @@ -410,8 +436,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { public XWPFComment getCommentByID(String id) { for (XWPFComment comment : comments) { - if (comment.getId().equals(id)) + if (comment.getId().equals(id)) { return comment; + } } return null; @@ -450,7 +477,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { } return headerFooterPolicy; } - + /** * Create a header of the given type * @@ -471,8 +498,8 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { } return hfPolicy.createHeader(STHdrFtr.Enum.forInt(type.toInt())); } - - + + /** * Create a footer of the given type * @@ -619,7 +646,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { String uri = CTP.type.getName().getNamespaceURI(); /* * TODO DO not use a coded constant, find the constant in the OOXML - * classes instead, as the child of type CT_Paragraph is defined in the + * classes instead, as the child of type CT_Paragraph is defined in the * OOXML schema as 'p' */ String localPart = "p"; @@ -667,8 +694,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { cursor.toCursor(newParaPos); while (cursor.toPrevSibling()) { o = cursor.getObject(); - if (o instanceof CTP || o instanceof CTTbl) + if (o instanceof CTP || o instanceof CTTbl) { i++; + } } bodyElements.add(i, newP); cursor.toCursor(newParaPos); @@ -706,8 +734,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { cursor.toCursor(tableCursor); while (cursor.toPrevSibling()) { o = cursor.getObject(); - if (o instanceof CTP || o instanceof CTTbl) + if (o instanceof CTP || o instanceof CTTbl) { i++; + } } bodyElements.add(i, newT); cursor.toCursor(tableCursor); @@ -984,7 +1013,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { tables.set(pos, table); ctDocument.getBody().setTblArray(pos, table.getCTTbl()); } - + /** * Verifies that the documentProtection tag in settings.xml file
* specifies that the protection is enforced (w:enforcement="1")
@@ -1288,7 +1317,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { public void setZoomPercent(long zoomPercent) { settings.setZoomPercent(zoomPercent); } - + /** * inserts an existing XWPFTable to the arrays bodyElements and tables * @@ -1378,7 +1407,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { throw new POIXMLException(e); } finally { try { - if (out != null) out.close(); + if (out != null) { + out.close(); + } } catch (IOException e) { // ignore } diff --git a/src/ooxml/testcases/org/apache/poi/xddf/usermodel/chart/TestXDDFDataSourcesFactory.java b/src/ooxml/testcases/org/apache/poi/xddf/usermodel/chart/TestXDDFDataSourcesFactory.java new file mode 100644 index 0000000000..f6c547cb15 --- /dev/null +++ b/src/ooxml/testcases/org/apache/poi/xddf/usermodel/chart/TestXDDFDataSourcesFactory.java @@ -0,0 +1,134 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.xddf.usermodel.chart; + +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.SheetBuilder; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import junit.framework.TestCase; + +/** + * Tests for {@link XDDFDataSourcesFactory}. + */ +public class TestXDDFDataSourcesFactory extends TestCase { + + private static final Object[][] numericCells = { + {0.0, 1.0, 2.0, 3.0, 4.0}, + {0.0, "=B1*2", "=C1*2", "=D1*2", "=E1*2"} + }; + + private static final Object[][] stringCells = { + { 1, 2, 3, 4, 5}, + {"A", "B", "C", "D", "E"} + }; + + private static final Object[][] mixedCells = { + {1.0, "2.0", 3.0, "4.0", 5.0, "6.0"} + }; + + public void testNumericArrayDataSource() { + Double[] doubles = new Double[]{1.0, 2.0, 3.0, 4.0, 5.0}; + XDDFDataSource doubleDataSource = XDDFDataSourcesFactory.fromArray(doubles, null); + assertTrue(doubleDataSource.isNumeric()); + assertFalse(doubleDataSource.isReference()); + assertDataSourceIsEqualToArray(doubleDataSource, doubles); + } + + public void testStringArrayDataSource() { + String[] strings = new String[]{"one", "two", "three", "four", "five"}; + XDDFDataSource stringDataSource = XDDFDataSourcesFactory.fromArray(strings, null); + assertFalse(stringDataSource.isNumeric()); + assertFalse(stringDataSource.isReference()); + assertDataSourceIsEqualToArray(stringDataSource, strings); + } + + public void testNumericCellDataSource() { + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet) new SheetBuilder(wb, numericCells).build(); + CellRangeAddress numCellRange = CellRangeAddress.valueOf("A2:E2"); + XDDFDataSource numDataSource = XDDFDataSourcesFactory.fromNumericCellRange(sheet, numCellRange); + assertTrue(numDataSource.isReference()); + assertTrue(numDataSource.isNumeric()); + assertEquals(numericCells[0].length, numDataSource.getPointCount()); + for (int i = 0; i < numericCells[0].length; ++i) { + assertEquals(((Double) numericCells[0][i]) * 2, + numDataSource.getPointAt(i), 0.00001); + } + } + + public void testStringCellDataSource() { + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet) new SheetBuilder(wb, stringCells).build(); + CellRangeAddress numCellRange = CellRangeAddress.valueOf("A2:E2"); + XDDFDataSource numDataSource = XDDFDataSourcesFactory.fromStringCellRange(sheet, numCellRange); + assertTrue(numDataSource.isReference()); + assertFalse(numDataSource.isNumeric()); + assertEquals(numericCells[0].length, numDataSource.getPointCount()); + for (int i = 0; i < stringCells[1].length; ++i) { + assertEquals(stringCells[1][i], numDataSource.getPointAt(i)); + } + } + + public void testMixedCellDataSource() { + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet) new SheetBuilder(wb, mixedCells).build(); + CellRangeAddress mixedCellRange = CellRangeAddress.valueOf("A1:F1"); + XDDFDataSource strDataSource = XDDFDataSourcesFactory.fromStringCellRange(sheet, mixedCellRange); + XDDFDataSource numDataSource = XDDFDataSourcesFactory.fromNumericCellRange(sheet, mixedCellRange); + for (int i = 0; i < mixedCells[0].length; ++i) { + if (i % 2 == 0) { + assertNull(strDataSource.getPointAt(i)); + assertEquals(((Double) mixedCells[0][i]), + numDataSource.getPointAt(i), 0.00001); + } else { + assertNull(numDataSource.getPointAt(i)); + assertEquals(mixedCells[0][i], strDataSource.getPointAt(i)); + } + } + } + + public void testIOBExceptionOnInvalidIndex() { + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet) new SheetBuilder(wb, numericCells).build(); + CellRangeAddress rangeAddress = CellRangeAddress.valueOf("A2:E2"); + XDDFDataSource numDataSource = XDDFDataSourcesFactory.fromNumericCellRange(sheet, rangeAddress); + IndexOutOfBoundsException exception = null; + try { + numDataSource.getPointAt(-1); + } catch (IndexOutOfBoundsException e) { + exception = e; + } + assertNotNull(exception); + + exception = null; + try { + numDataSource.getPointAt(numDataSource.getPointCount()); + } catch (IndexOutOfBoundsException e) { + exception = e; + } + assertNotNull(exception); + } + + private void assertDataSourceIsEqualToArray(XDDFDataSource ds, T[] array) { + assertEquals(ds.getPointCount(), array.length); + for (int i = 0; i < array.length; ++i) { + assertEquals(ds.getPointAt(i), array[i]); + } + } +} diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFChart.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFChart.java index e5f531dd38..5a66e41f8d 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFChart.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFChart.java @@ -18,44 +18,151 @@ */ package org.apache.poi.xslf.usermodel; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import java.io.IOException; -import java.io.OutputStream; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.List; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; +import org.apache.poi.xddf.usermodel.chart.AxisCrossBetween; +import org.apache.poi.xddf.usermodel.chart.AxisCrosses; +import org.apache.poi.xddf.usermodel.chart.AxisOrientation; +import org.apache.poi.xddf.usermodel.chart.AxisPosition; +import org.apache.poi.xddf.usermodel.chart.AxisTickMark; +import org.apache.poi.xddf.usermodel.chart.BarDirection; +import org.apache.poi.xddf.usermodel.chart.BarGrouping; +import org.apache.poi.xddf.usermodel.chart.Grouping; +import org.apache.poi.xddf.usermodel.chart.LayoutMode; +import org.apache.poi.xddf.usermodel.chart.LayoutTarget; +import org.apache.poi.xddf.usermodel.chart.LegendPosition; +import org.apache.poi.xddf.usermodel.chart.RadarStyle; +import org.apache.poi.xddf.usermodel.chart.ScatterStyle; +import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory; +import org.apache.poi.xddf.usermodel.chart.XDDFLineChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFManualLayout; +import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFPieChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFRadarChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFScatterChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis; import org.apache.poi.xslf.XSLFTestDataSamples; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.Test; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumVal; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData; -import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrVal; +/** + * a modified version from POI-examples + */ public class TestXSLFChart { - - /** - * a modified version from POI-examples - */ @Test - public void testFillChartTemplate() throws IOException { + public void testFillPieChartTemplate() throws IOException { + XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("pie-chart.pptx"); + XSLFChart chart = findChart(pptx.getSlides().get(0)); + List data = findChartData(chart); - String chartTitle = "Apache POI"; // first line is chart title + XDDFPieChartData pie = (XDDFPieChartData) data.get(0); + XDDFPieChartData.Series firstSeries = (XDDFPieChartData.Series) pie.getSeries().get(0); + firstSeries.setExplosion(25); + assertEquals(25, firstSeries.getExplosion()); - XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("pie-chart.pptx"); + fillChartData(chart, pie); + pptx.close(); + } + + @Test + public void testFillBarChartTemplate() throws IOException { + XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("bar-chart.pptx"); XSLFSlide slide = pptx.getSlides().get(0); + // duplicate slide and chart before applying "destructive" tests to it + XSLFChart chart2 = findChart(pptx.createSlide().importContent(slide)); + XSLFChart chart = findChart(slide); + + List data = findChartData(chart); + XDDFBarChartData bar = (XDDFBarChartData) data.get(0); + assertEquals(BarDirection.BAR, bar.getBarDirection()); + assertEquals(BarGrouping.CLUSTERED, bar.getBarGrouping()); + assertEquals(100, bar.getGapWidth()); + fillChartData(chart, bar); + + XDDFBarChartData column = (XDDFBarChartData) findChartData(chart2).get(0); + column.setBarDirection(BarDirection.COL); + assertEquals(BarDirection.COL, column.getBarDirection()); + column.getCategoryAxis().setOrientation(AxisOrientation.MIN_MAX); + column.getValueAxes().get(0).setPosition(AxisPosition.BOTTOM); + fillChartData(chart2, column); + + pptx.close(); + } + + @Test + public void testFillLineChartTemplate() throws IOException { + XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("line-chart.pptx"); + XSLFChart chart = findChart(pptx.getSlides().get(0)); + List data = findChartData(chart); + + XDDFLineChartData line = (XDDFLineChartData) data.get(0); + assertEquals(Grouping.STANDARD, line.getGrouping()); + line.setGrouping(Grouping.PERCENT_STACKED); + assertEquals(Grouping.PERCENT_STACKED, line.getGrouping()); + + fillChartData(chart, line); + pptx.close(); + } + + @Test + public void testFillRadarChartTemplate() throws IOException { + XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("radar-chart.pptx"); + XSLFChart chart = findChart(pptx.getSlides().get(0)); + List data = findChartData(chart); + + XDDFRadarChartData radar = (XDDFRadarChartData) data.get(0); + assertEquals(RadarStyle.MARKER, radar.getStyle()); + radar.setStyle(RadarStyle.FILLED); + assertEquals(RadarStyle.FILLED, radar.getStyle()); + + fillChartData(chart, radar); + pptx.close(); + } + + @Test + public void testFillScatterChartTemplate() throws IOException { + XMLSlideShow pptx = XSLFTestDataSamples.openSampleDocument("scatter-chart.pptx"); + XSLFChart chart = findChart(pptx.getSlides().get(0)); + List data = findChartData(chart); + + XDDFScatterChartData scatter = (XDDFScatterChartData) data.get(0); + assertEquals(ScatterStyle.LINE_MARKER, scatter.getStyle()); + scatter.setStyle(ScatterStyle.SMOOTH); + assertEquals(ScatterStyle.SMOOTH, scatter.getStyle()); + + fillChartData(chart, scatter); + pptx.close(); + } + + private void fillChartData(XSLFChart chart, XDDFChartData data) { + final int numOfPoints = 3; + final String[] categories = {"First", "Second", "Third"}; + final Integer[] values = {1, 3, 4}; + + final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0)); + final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1)); + final XDDFChartData.Series series = data.getSeries().get(0); + final XDDFDataSource categoryData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange); + final XDDFNumericalDataSource valuesData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange); + series.replaceData(categoryData, valuesData); + final String title = "Apache POI"; + series.setTitle(title, chart.setSheetTitle(title)); + chart.plot(data); + } + + private XSLFChart findChart(XSLFSlide slide) { // find chart in the slide XSLFChart chart = null; for(POIXMLDocumentPart part : slide.getRelations()){ @@ -65,76 +172,161 @@ public class TestXSLFChart { } } - if(chart == null) throw new IllegalStateException("chart not found in the template"); + if(chart == null) { + throw new IllegalStateException("chart not found in the template"); + } - // embedded Excel workbook that holds the chart data - POIXMLDocumentPart xlsPart = chart.getRelations().get(0); - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sheet = wb.createSheet(); + checkLegendOperations(chart); + return chart; + } - CTChart ctChart = chart.getCTChart(); - CTPlotArea plotArea = ctChart.getPlotArea(); + private List findChartData(XSLFChart chart) { + List data = chart.getChartSeries(); + assertNotNull(data); + assertEquals(1, data.size()); - CTPieChart pieChart = plotArea.getPieChartArray(0); - //Pie Chart Series - CTPieSer ser = pieChart.getSerArray(0); + XDDFChartData firstSeries = data.get(0); + assertNotNull(firstSeries); + if (firstSeries instanceof XDDFScatterChartData) { + assertEquals(null, firstSeries.getCategoryAxis()); + assertEquals(2, firstSeries.getValueAxes().size()); + checkAxisOperations(firstSeries.getValueAxes().get(0)); + checkAxisOperations(firstSeries.getValueAxes().get(1)); + } else if (!(firstSeries instanceof XDDFPieChartData)) { + assertNotNull(firstSeries.getCategoryAxis()); + assertEquals(1, firstSeries.getValueAxes().size()); + checkAxisOperations(firstSeries.getValueAxes().get(0)); + } - // Series Text - CTSerTx tx = ser.getTx(); - tx.getStrRef().getStrCache().getPtArray(0).setV(chartTitle); - sheet.createRow(0).createCell(1).setCellValue(chartTitle); - String titleRef = new CellReference(sheet.getSheetName(), 0, 1, true, true).formatAsString(); - tx.getStrRef().setF(titleRef); + return data; + } + private void checkLegendOperations(XSLFChart chart) { + XDDFChartLegend legend = chart.getOrAddLegend(); + assertFalse(legend.isOverlay()); + legend.setOverlay(true); + assertTrue(legend.isOverlay()); + legend.setPosition(LegendPosition.TOP_RIGHT); + assertEquals(LegendPosition.TOP_RIGHT, legend.getPosition()); - // Category Axis Data - CTAxDataSource cat = ser.getCat(); - CTStrData strData = cat.getStrRef().getStrCache(); + XDDFManualLayout layout = legend.getOrAddManualLayout(); + assertNotNull(layout.getTarget()); + assertNotNull(layout.getXMode()); + assertNotNull(layout.getYMode()); + assertNotNull(layout.getHeightMode()); + assertNotNull(layout.getWidthMode()); + /* + * According to interface, 0.0 should be returned for + * uninitialized double properties. + */ + assertTrue(layout.getX() == 0.0); + assertTrue(layout.getY() == 0.0); + assertTrue(layout.getWidthRatio() == 0.0); + assertTrue(layout.getHeightRatio() == 0.0); - // Values - CTNumDataSource valSrc = ser.getVal(); - CTNumData numData = valSrc.getNumRef().getNumCache(); + final double newRatio = 1.1; + final double newCoordinate = 0.3; + final LayoutMode nonDefaultMode = LayoutMode.FACTOR; + final LayoutTarget nonDefaultTarget = LayoutTarget.OUTER; - strData.setPtArray(null); // unset old axis text - numData.setPtArray(null); // unset old values + layout.setWidthRatio(newRatio); + assertTrue(layout.getWidthRatio() == newRatio); - Map pieModel = new LinkedHashMap<>(); - pieModel.put("First", 1.0); - pieModel.put("Second", 3.0); - pieModel.put("Third", 4.0); + layout.setHeightRatio(newRatio); + assertTrue(layout.getHeightRatio() == newRatio); - // set model - int idx = 0; - int rownum = 1; - for(String key : pieModel.keySet()){ - double val = pieModel.get(key); + layout.setX(newCoordinate); + assertTrue(layout.getX() == newCoordinate); - CTNumVal numVal = numData.addNewPt(); - numVal.setIdx(idx); - numVal.setV("" + val); + layout.setY(newCoordinate); + assertTrue(layout.getY() == newCoordinate); - CTStrVal sVal = strData.addNewPt(); - sVal.setIdx(idx); - sVal.setV(key); + layout.setXMode(nonDefaultMode); + assertTrue(layout.getXMode() == nonDefaultMode); - idx++; - XSSFRow row = sheet.createRow(rownum++); - row.createCell(0).setCellValue(key); - row.createCell(1).setCellValue(val); - } - numData.getPtCount().setVal(idx); - strData.getPtCount().setVal(idx); - - String numDataRange = new CellRangeAddress(1, rownum-1, 1, 1).formatAsString(sheet.getSheetName(), true); - valSrc.getNumRef().setF(numDataRange); - String axisDataRange = new CellRangeAddress(1, rownum-1, 0, 0).formatAsString(sheet.getSheetName(), true); - cat.getStrRef().setF(axisDataRange); - - // updated the embedded workbook with the data - OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream(); - wb.write(xlsOut); - xlsOut.close(); - wb.close(); - } + layout.setYMode(nonDefaultMode); + assertTrue(layout.getYMode() == nonDefaultMode); + + layout.setWidthMode(nonDefaultMode); + assertTrue(layout.getWidthMode() == nonDefaultMode); + + layout.setHeightMode(nonDefaultMode); + assertTrue(layout.getHeightMode() == nonDefaultMode); + + layout.setTarget(nonDefaultTarget); + assertTrue(layout.getTarget() == nonDefaultTarget); + } + + private void checkAxisOperations(XDDFValueAxis axis) { + axis.setCrossBetween(AxisCrossBetween.MIDPOINT_CATEGORY); + assertEquals(AxisCrossBetween.MIDPOINT_CATEGORY, axis.getCrossBetween()); + + axis.setCrosses(AxisCrosses.AUTO_ZERO); + assertEquals(AxisCrosses.AUTO_ZERO, axis.getCrosses()); + + final String numberFormat = "General"; + axis.setNumberFormat(numberFormat); + assertEquals(numberFormat, axis.getNumberFormat()); + + axis.setPosition(AxisPosition.BOTTOM); + assertEquals(AxisPosition.BOTTOM, axis.getPosition()); + + 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()); + + 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()); + + axis.setVisible(true); + assertTrue(axis.isVisible()); + + axis.setVisible(false); + assertFalse(axis.isVisible()); + + final double EPSILON = 1E-7; + axis.setLogBase(Math.E); + assertTrue(Math.abs(axis.getLogBase() - Math.E) < EPSILON); + + 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); + + IllegalArgumentException iae = null; + try { + axis.setLogBase(0.0); + } catch (IllegalArgumentException e) { + iae = e; + } + assertNotNull(iae); -} \ No newline at end of file + iae = null; + try { + axis.setLogBase(30000.0); + } catch (IllegalArgumentException e) { + iae = e; + } + assertNotNull(iae); + } +} 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 f033e8ed4e..bdaacb8993 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChart.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChart.java @@ -17,46 +17,46 @@ package org.apache.poi.xssf.usermodel; -import junit.framework.TestCase; - import org.apache.poi.xssf.XSSFTestDataSamples; +import junit.framework.TestCase; + public final class TestXSSFChart extends TestCase { - + public void testGetAccessors() { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithThreeCharts.xlsx"); XSSFSheet s1 = wb.getSheetAt(0); XSSFSheet s2 = wb.getSheetAt(1); XSSFSheet s3 = wb.getSheetAt(2); - + assertEquals(0, s1.getRelations().size()); assertEquals(1, s2.getRelations().size()); assertEquals(1, s3.getRelations().size()); - + assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb)); } - + public void testGetCharts() throws Exception { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithThreeCharts.xlsx"); - + XSSFSheet s1 = wb.getSheetAt(0); XSSFSheet s2 = wb.getSheetAt(1); XSSFSheet s3 = wb.getSheetAt(2); - + assertEquals(0, s1.createDrawingPatriarch().getCharts().size()); assertEquals(2, s2.createDrawingPatriarch().getCharts().size()); assertEquals(1, s3.createDrawingPatriarch().getCharts().size()); - + // Check the titles XSSFChart chart = s2.createDrawingPatriarch().getCharts().get(0); assertEquals(null, chart.getTitleText()); - + chart = s2.createDrawingPatriarch().getCharts().get(1); assertEquals("Pie Chart Title Thingy", chart.getTitleText().getString()); - + chart = s3.createDrawingPatriarch().getCharts().get(0); assertEquals("Sheet 3 Chart with Title", chart.getTitleText().getString()); - + assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb)); } @@ -68,14 +68,15 @@ public final class TestXSSFChart extends TestCase { XSSFChart c1 = d1.createChart(a1); assertEquals(1, d1.getCharts().size()); + assertNotNull(c1.getGraphicFrame()); - assertNotNull(c1.getOrCreateLegend()); + assertNotNull(c1.getOrAddLegend()); XSSFClientAnchor a2 = new XSSFClientAnchor(0, 0, 0, 0, 1, 11, 10, 60); XSSFChart c2 = d1.createChart(a2); assertNotNull(c2); assertEquals(2, d1.getCharts().size()); - + assertNotNull(XSSFTestDataSamples.writeOutAndReadBack(wb)); } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFCategoryAxis.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFCategoryAxis.java index 64ce92b570..a7f9098e39 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFCategoryAxis.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFCategoryAxis.java @@ -17,24 +17,32 @@ package org.apache.poi.xssf.usermodel.charts; -import junit.framework.TestCase; +import org.apache.poi.xddf.usermodel.chart.AxisCrosses; +import org.apache.poi.xddf.usermodel.chart.AxisPosition; +import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis; +import org.apache.poi.xssf.usermodel.XSSFChart; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.ss.usermodel.charts.*; -import org.apache.poi.xssf.usermodel.*; +import junit.framework.TestCase; public final class TestXSSFCategoryAxis 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); - XSSFCategoryAxis axis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM); + XDDFCategoryAxis axis = chart.createCategoryAxis(AxisPosition.BOTTOM); axis.setCrosses(AxisCrosses.AUTO_ZERO); assertEquals(axis.getCrosses(), AxisCrosses.AUTO_ZERO); - assertEquals(chart.getAxis().size(), 1); + assertEquals(chart.getAxes().size(), 1); + + wb.close(); } } 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 41e02b12ff..1578755ab1 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 @@ -19,18 +19,22 @@ package org.apache.poi.xssf.usermodel.charts; import java.util.List; -import junit.framework.TestCase; - -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.*; +import org.apache.poi.xddf.usermodel.chart.AxisPosition; +import org.apache.poi.xddf.usermodel.chart.AxisTickMark; +import org.apache.poi.xddf.usermodel.chart.XDDFChartAxis; import org.apache.poi.xssf.XSSFTestDataSamples; -import org.apache.poi.xssf.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFChart; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import junit.framework.TestCase; public final class TestXSSFChartAxis extends TestCase { private static final double EPSILON = 1E-7; - private final XSSFChartAxis axis; + private final XDDFChartAxis axis; public TestXSSFChartAxis() { super(); @@ -39,9 +43,9 @@ public final class TestXSSFChartAxis extends TestCase { 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); + axis = chart.createValueAxis(AxisPosition.BOTTOM); } - + public void testLogBaseIllegalArgument() throws Exception { IllegalArgumentException iae = null; try { @@ -119,13 +123,12 @@ public final class TestXSSFChartAxis extends TestCase { public void testGetChartAxisBug57362() { //Load existing excel with some chart on it having primary and secondary axis. - final Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("57362.xlsx"); - final Sheet sh = workbook.getSheetAt(0); - final XSSFSheet xsh = (XSSFSheet) sh; - final XSSFDrawing drawing = xsh.createDrawingPatriarch(); + final XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("57362.xlsx"); + final XSSFSheet sh = workbook.getSheetAt(0); + final XSSFDrawing drawing = sh.createDrawingPatriarch(); final XSSFChart chart = drawing.getCharts().get(0); - final List axisList = chart.getAxis(); + final List axisList = chart.getAxes(); assertEquals(4, axisList.size()); assertNotNull(axisList.get(0)); 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 index 524b421da9..2a464067c1 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartLegend.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartLegend.java @@ -23,13 +23,12 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.ChartLegend; -import org.apache.poi.ss.usermodel.charts.LegendPosition; +import org.apache.poi.xddf.usermodel.chart.LegendPosition; +import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend; +import org.apache.poi.xssf.usermodel.XSSFChart; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.Test; @@ -39,28 +38,28 @@ import org.junit.Test; public final class TestXSSFChartLegend { @Test public void testLegendPositionAccessMethods() throws IOException { - 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(); + 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); + XDDFChartLegend legend = chart.getOrAddLegend(); legend.setPosition(LegendPosition.TOP_RIGHT); assertEquals(LegendPosition.TOP_RIGHT, legend.getPosition()); - + wb.close(); } @Test public void test_setOverlay_defaultChartLegend_expectOverlayInitialValueSetToFalse() throws IOException { // Arrange - 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(); + 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); + XDDFChartLegend legend = chart.getOrAddLegend(); // Act @@ -73,12 +72,12 @@ public final class TestXSSFChartLegend { @Test public void test_setOverlay_chartLegendSetToTrue_expectOverlayInitialValueSetToTrue() throws IOException { // Arrange - 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(); + 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); + XDDFChartLegend legend = chart.getOrAddLegend(); // Act legend.setOverlay(true); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartTitle.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartTitle.java index 7282aa0f41..14f467a37f 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartTitle.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFChartTitle.java @@ -26,24 +26,22 @@ import java.io.IOException; import java.util.List; import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.AxisCrosses; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ChartDataSource; -import org.apache.poi.ss.usermodel.charts.ChartLegend; -import org.apache.poi.ss.usermodel.charts.DataSources; -import org.apache.poi.ss.usermodel.charts.LegendPosition; -import org.apache.poi.ss.usermodel.charts.LineChartData; -import org.apache.poi.ss.usermodel.charts.ValueAxis; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xddf.usermodel.chart.AxisCrosses; +import org.apache.poi.xddf.usermodel.chart.AxisPosition; +import org.apache.poi.xddf.usermodel.chart.ChartTypes; +import org.apache.poi.xddf.usermodel.chart.LegendPosition; +import org.apache.poi.xddf.usermodel.chart.XDDFChartAxis; +import org.apache.poi.xddf.usermodel.chart.XDDFChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory; +import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis; import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.usermodel.XSSFChart; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; import org.apache.poi.xssf.usermodel.XSSFDrawing; import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.apache.poi.xssf.usermodel.XSSFSheet; @@ -54,9 +52,9 @@ import org.junit.Test; * Test get/set chart title. */ public class TestXSSFChartTitle { - private Workbook createWorkbookWithChart() { - Workbook wb = new XSSFWorkbook(); - Sheet sheet = wb.createSheet("linechart"); + private XSSFWorkbook createWorkbookWithChart() { + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = wb.createSheet("linechart"); final int NUM_OF_ROWS = 3; final int NUM_OF_COLUMNS = 10; @@ -71,28 +69,26 @@ public class TestXSSFChartTitle { } } - Drawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15); + XSSFDrawing drawing = sheet.createDrawingPatriarch(); + XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15); - Chart chart = drawing.createChart(anchor); - ChartLegend legend = chart.getOrCreateLegend(); + XSSFChart chart = drawing.createChart(anchor); + XDDFChartLegend legend = chart.getOrAddLegend(); 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); + XDDFChartAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); + XDDFValueAxis leftAxis = chart.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)); + XDDFDataSource xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1)); + XDDFNumericalDataSource ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1)); + XDDFNumericalDataSource ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1)); + XDDFChartData data = chart.createData(ChartTypes.LINE, bottomAxis, leftAxis); data.addSeries(xs, ys1); data.addSeries(xs, ys2); - - chart.plot(data, bottomAxis, leftAxis); + chart.plot(data); return wb; } @@ -100,16 +96,14 @@ public class TestXSSFChartTitle { /** * Gets the first chart from the named sheet in the workbook. */ - private XSSFChart getChartFromWorkbook(Workbook wb, String sheetName) { - Sheet sheet = wb.getSheet(sheetName); - if (sheet instanceof XSSFSheet) { - XSSFSheet xsheet = (XSSFSheet) sheet; - XSSFDrawing drawing = xsheet.getDrawingPatriarch(); - if (drawing != null) { - List charts = drawing.getCharts(); - if (charts != null && charts.size() > 0) { - return charts.get(0); - } + private XSSFChart getChartFromWorkbook(XSSFWorkbook wb, String sheetName) { + XSSFSheet sheet = wb.getSheet(sheetName); + XSSFSheet xsheet = sheet; + XSSFDrawing drawing = xsheet.getDrawingPatriarch(); + if (drawing != null) { + List charts = drawing.getCharts(); + if (charts != null && charts.size() > 0) { + return charts.get(0); } } return null; @@ -117,7 +111,7 @@ public class TestXSSFChartTitle { @Test public void testNewChart() throws IOException { - Workbook wb = createWorkbookWithChart(); + XSSFWorkbook wb = createWorkbookWithChart(); XSSFChart chart = getChartFromWorkbook(wb, "linechart"); assertNotNull(chart); assertNull(chart.getTitleText()); @@ -126,7 +120,7 @@ public class TestXSSFChartTitle { XSSFRichTextString queryTitle = chart.getTitleText(); assertNotNull(queryTitle); assertEquals(myTitle, queryTitle.toString()); - + final String myTitleFormula = "1 & \" and \" & 2"; chart.setTitleFormula(myTitleFormula); // setting formula should unset text, but since there is a formula, returns an empty string @@ -139,7 +133,7 @@ public class TestXSSFChartTitle { @Test public void testExistingChartWithTitle() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("chartTitle_withTitle.xlsx"); + XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("chartTitle_withTitle.xlsx"); XSSFChart chart = getChartFromWorkbook(wb, "Sheet1"); assertNotNull(chart); XSSFRichTextString originalTitle = chart.getTitleText(); @@ -155,7 +149,7 @@ public class TestXSSFChartTitle { @Test public void testExistingChartNoTitle() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("chartTitle_noTitle.xlsx"); + XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("chartTitle_noTitle.xlsx"); XSSFChart chart = getChartFromWorkbook(wb, "Sheet1"); assertNotNull(chart); assertNull(chart.getTitleText()); @@ -169,7 +163,7 @@ public class TestXSSFChartTitle { @Test public void testExistingChartWithFormulaTitle() throws IOException { - Workbook wb = XSSFTestDataSamples.openSampleWorkbook("chartTitle_withTitleFormula.xlsx"); + XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("chartTitle_withTitleFormula.xlsx"); XSSFChart chart = getChartFromWorkbook(wb, "Sheet1"); assertNotNull(chart); XSSFRichTextString originalTitle = chart.getTitleText(); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFDateAxis.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFDateAxis.java index 81a474f502..5664488185 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFDateAxis.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFDateAxis.java @@ -17,24 +17,32 @@ package org.apache.poi.xssf.usermodel.charts; -import junit.framework.TestCase; +import org.apache.poi.xddf.usermodel.chart.AxisCrosses; +import org.apache.poi.xddf.usermodel.chart.AxisPosition; +import org.apache.poi.xddf.usermodel.chart.XDDFDateAxis; +import org.apache.poi.xssf.usermodel.XSSFChart; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.ss.usermodel.charts.*; -import org.apache.poi.xssf.usermodel.*; +import junit.framework.TestCase; public final class TestXSSFDateAxis 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); - XSSFDateAxis axis = chart.getChartAxisFactory().createDateAxis(AxisPosition.BOTTOM); + XDDFDateAxis axis = chart.createDateAxis(AxisPosition.BOTTOM); axis.setCrosses(AxisCrosses.AUTO_ZERO); assertEquals(axis.getCrosses(), AxisCrosses.AUTO_ZERO); - assertEquals(chart.getAxis().size(), 1); + assertEquals(chart.getAxes().size(), 1); + + wb.close(); } } 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 index e5ee56b504..83a25dff64 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFLineChartData.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFLineChartData.java @@ -22,19 +22,20 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ChartDataSource; -import org.apache.poi.ss.usermodel.charts.DataSources; -import org.apache.poi.ss.usermodel.charts.LineChartData; -import org.apache.poi.ss.usermodel.charts.LineChartSeries; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.SheetBuilder; +import org.apache.poi.xddf.usermodel.chart.AxisPosition; +import org.apache.poi.xddf.usermodel.chart.ChartTypes; +import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis; +import org.apache.poi.xddf.usermodel.chart.XDDFChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory; +import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis; +import org.apache.poi.xssf.usermodel.XSSFChart; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.Test; @@ -50,27 +51,26 @@ public class TestXSSFLineChartData { @Test public void testOneSeriePlot() throws IOException { - 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); + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet) new SheetBuilder(wb, plotData).build(); + 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().createCategoryAxis(AxisPosition.BOTTOM); - ChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); + XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); + XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT); - LineChartData lineChartData = - chart.getChartDataFactory().createLineChartData(); + XDDFDataSource xs = XDDFDataSourcesFactory.fromStringCellRange(sheet, CellRangeAddress.valueOf("A1:J1")); + XDDFNumericalDataSource ys = XDDFDataSourcesFactory.fromNumericCellRange(sheet, CellRangeAddress.valueOf("A2:J2")); - ChartDataSource xs = DataSources.fromStringCellRange(sheet, CellRangeAddress.valueOf("A1:J1")); - ChartDataSource ys = DataSources.fromNumericCellRange(sheet, CellRangeAddress.valueOf("A2:J2")); - LineChartSeries series = lineChartData.addSeries(xs, ys); + XDDFChartData lineChartData = chart.createData(ChartTypes.LINE, bottomAxis, leftAxis); + XDDFChartData.Series series = lineChartData.addSeries(xs, ys); assertNotNull(series); assertEquals(1, lineChartData.getSeries().size()); assertTrue(lineChartData.getSeries().contains(series)); - chart.plot(lineChartData, bottomAxis, leftAxis); + chart.plot(lineChartData); wb.close(); } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFManualLayout.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFManualLayout.java index 73df559144..85ac30f30f 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFManualLayout.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFManualLayout.java @@ -22,15 +22,14 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.ChartLegend; -import org.apache.poi.ss.usermodel.charts.LayoutMode; -import org.apache.poi.ss.usermodel.charts.LayoutTarget; -import org.apache.poi.ss.usermodel.charts.ManualLayout; +import org.apache.poi.xddf.usermodel.chart.LayoutMode; +import org.apache.poi.xddf.usermodel.chart.LayoutTarget; +import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend; +import org.apache.poi.xddf.usermodel.chart.XDDFManualLayout; +import org.apache.poi.xssf.usermodel.XSSFChart; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.After; import org.junit.Before; @@ -38,25 +37,25 @@ import org.junit.Test; public final class TestXSSFManualLayout { - private Workbook wb; - private ManualLayout layout; - + private XSSFWorkbook wb; + private XDDFManualLayout layout; + @Before public void createEmptyLayout() { 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(); - layout = legend.getManualLayout(); + 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); + XDDFChartLegend legend = chart.getOrAddLegend(); + layout = legend.getOrAddManualLayout(); } @After public void closeWB() throws IOException { wb.close(); } - + /* * Accessor methods are not trivial. They use lazy underlying bean * initialization so there can be some errors (NPE, for example). diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java index 79dc71c8d2..5683bc4052 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java @@ -23,19 +23,21 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; -import org.apache.poi.ss.usermodel.Chart; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.charts.AxisPosition; -import org.apache.poi.ss.usermodel.charts.ChartAxis; -import org.apache.poi.ss.usermodel.charts.ChartDataSource; -import org.apache.poi.ss.usermodel.charts.DataSources; -import org.apache.poi.ss.usermodel.charts.ScatterChartData; -import org.apache.poi.ss.usermodel.charts.ScatterChartSeries; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.SheetBuilder; +import org.apache.poi.xddf.usermodel.chart.AxisPosition; +import org.apache.poi.xddf.usermodel.chart.ChartTypes; +import org.apache.poi.xddf.usermodel.chart.ScatterStyle; +import org.apache.poi.xddf.usermodel.chart.XDDFChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory; +import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource; +import org.apache.poi.xddf.usermodel.chart.XDDFScatterChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis; +import org.apache.poi.xssf.usermodel.XSSFChart; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.Test; @@ -51,27 +53,27 @@ public final class TestXSSFScatterChartData { @Test public void testOneSeriePlot() throws IOException { - 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); + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet) new SheetBuilder(wb, plotData).build(); + 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); + XDDFValueAxis bottomAxis = chart.createValueAxis(AxisPosition.BOTTOM); + XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT); - ScatterChartData scatterChartData = - chart.getChartDataFactory().createScatterChartData(); + XDDFDataSource xs = XDDFDataSourcesFactory.fromStringCellRange(sheet, CellRangeAddress.valueOf("A1:J1")); + XDDFNumericalDataSource ys = XDDFDataSourcesFactory.fromNumericCellRange(sheet, CellRangeAddress.valueOf("A2:J2")); - ChartDataSource xs = DataSources.fromStringCellRange(sheet, CellRangeAddress.valueOf("A1:J1")); - ChartDataSource ys = DataSources.fromNumericCellRange(sheet, CellRangeAddress.valueOf("A2:J2")); - ScatterChartSeries series = scatterChartData.addSerie(xs, ys); + XDDFScatterChartData scatterChartData = (XDDFScatterChartData) chart.createData(ChartTypes.SCATTER, bottomAxis, leftAxis); + XDDFChartData.Series series = scatterChartData.addSeries(xs, ys); + assertEquals(ScatterStyle.LINE_MARKER, scatterChartData.getStyle()); assertNotNull(series); assertEquals(1, scatterChartData.getSeries().size()); assertTrue(scatterChartData.getSeries().contains(series)); - chart.plot(scatterChartData, bottomAxis, leftAxis); + chart.plot(scatterChartData); wb.close(); } } 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 index db8ded3707..3f8ef06db4 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFValueAxis.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFValueAxis.java @@ -17,20 +17,27 @@ package org.apache.poi.xssf.usermodel.charts; -import junit.framework.TestCase; +import org.apache.poi.xddf.usermodel.chart.AxisCrossBetween; +import org.apache.poi.xddf.usermodel.chart.AxisCrosses; +import org.apache.poi.xddf.usermodel.chart.AxisPosition; +import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis; +import org.apache.poi.xssf.usermodel.XSSFChart; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.poi.ss.usermodel.charts.*; -import org.apache.poi.xssf.usermodel.*; +import junit.framework.TestCase; 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); + XDDFValueAxis axis = chart.createValueAxis(AxisPosition.BOTTOM); axis.setCrossBetween(AxisCrossBetween.MIDPOINT_CATEGORY); assertEquals(axis.getCrossBetween(), AxisCrossBetween.MIDPOINT_CATEGORY); @@ -38,6 +45,8 @@ public final class TestXSSFValueAxis extends TestCase { axis.setCrosses(AxisCrosses.AUTO_ZERO); assertEquals(axis.getCrosses(), AxisCrosses.AUTO_ZERO); - assertEquals(chart.getAxis().size(), 1); + assertEquals(chart.getAxes().size(), 1); + + wb.close(); } } diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFChart.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFChart.java index 1cb233dade..cb55371160 100644 --- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFChart.java +++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFChart.java @@ -20,6 +20,8 @@ package org.apache.poi.xwpf.usermodel; import java.io.IOException; import java.util.List; +import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData; +import org.apache.poi.xddf.usermodel.chart.XDDFChartData; import org.apache.poi.xwpf.XWPFTestDataSamples; import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart; import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle; @@ -33,7 +35,7 @@ import junit.framework.TestCase; public class TestXWPFChart extends TestCase { /** - * test method to check charts are null + * test method to check charts are not null */ public void testRead() throws IOException { @@ -41,10 +43,18 @@ public class TestXWPFChart extends TestCase { List charts = sampleDoc.getCharts(); assertNotNull(charts); assertEquals(2, charts.size()); - assertNotNull(charts.get(0)); - assertNotNull(charts.get(1)); + checkData(charts.get(0)); + checkData(charts.get(1)); } - + + private void checkData(XWPFChart chart) { + assertNotNull(chart); + assertEquals(1, chart.getChartSeries().size()); + XDDFChartData data = chart.getChartSeries().get(0); + assertEquals(XDDFBarChartData.class, data.getClass()); + assertEquals(3, data.getSeries().size()); + } + /** * test method to add chart title and check whether it's set */ diff --git a/test-data/slideshow/bar-chart.pptx b/test-data/slideshow/bar-chart.pptx new file mode 100644 index 0000000000..e4d2613046 Binary files /dev/null and b/test-data/slideshow/bar-chart.pptx differ diff --git a/test-data/slideshow/line-chart.pptx b/test-data/slideshow/line-chart.pptx new file mode 100644 index 0000000000..7fd9f4d0f8 Binary files /dev/null and b/test-data/slideshow/line-chart.pptx differ diff --git a/test-data/slideshow/radar-chart.pptx b/test-data/slideshow/radar-chart.pptx new file mode 100644 index 0000000000..f569d7f3a1 Binary files /dev/null and b/test-data/slideshow/radar-chart.pptx differ diff --git a/test-data/slideshow/scatter-chart.pptx b/test-data/slideshow/scatter-chart.pptx new file mode 100644 index 0000000000..a4f2431b97 Binary files /dev/null and b/test-data/slideshow/scatter-chart.pptx differ