]> source.dussan.org Git - poi.git/commitdiff
more progress with xssf chart api, see Bug 51196
authorYegor Kozlov <yegor@apache.org>
Sat, 10 Sep 2011 19:00:47 +0000 (19:00 +0000)
committerYegor Kozlov <yegor@apache.org>
Sat, 10 Sep 2011 19:00:47 +0000 (19:00 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1167579 13f79535-47bb-0310-9956-ffa450edef68

30 files changed:
src/examples/src/org/apache/poi/xssf/usermodel/examples/ScatterChart.java
src/java/org/apache/poi/ss/usermodel/charts/ChartAxis.java
src/java/org/apache/poi/ss/usermodel/charts/ChartAxisFactory.java
src/java/org/apache/poi/ss/usermodel/charts/ChartData.java
src/java/org/apache/poi/ss/usermodel/charts/ChartDataFactory.java
src/java/org/apache/poi/ss/usermodel/charts/ChartDataSource.java [new file with mode: 0644]
src/java/org/apache/poi/ss/usermodel/charts/ChartLegend.java
src/java/org/apache/poi/ss/usermodel/charts/DataSources.java [new file with mode: 0644]
src/java/org/apache/poi/ss/usermodel/charts/ManualLayout.java
src/java/org/apache/poi/ss/usermodel/charts/ManuallyPositionable.java
src/java/org/apache/poi/ss/usermodel/charts/ScatterChartData.java
src/java/org/apache/poi/ss/usermodel/charts/ScatterChartSerie.java
src/java/org/apache/poi/ss/usermodel/charts/ValueAxis.java
src/java/org/apache/poi/ss/util/DataMarker.java
src/java/org/apache/poi/ss/util/SheetBuilder.java
src/java/org/apache/poi/ss/util/cellwalk/CellWalk.java
src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartAxis.java
src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartDataFactory.java
src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartLegend.java
src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartUtil.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFManualLayout.java
src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFNumberCache.java [deleted file]
src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFScatterChartData.java
src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFValueAxis.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFChartSheet.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFNumberCache.java [deleted file]
src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFScatterChartData.java
src/testcases/org/apache/poi/ss/usermodel/charts/TestDataSources.java [new file with mode: 0644]
src/testcases/org/apache/poi/ss/util/TestSheetBuilder.java

index 3df1d90acfbe539f2cc9e883e54f277008410a6c..f0a94777f00aeb95751219c6d4319d073aeb63ce 100644 (file)
 package org.apache.poi.xssf.usermodel.examples;
 
 import java.io.FileOutputStream;
-import java.util.Date;
-
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.*;
 import org.apache.poi.ss.usermodel.charts.*;
-import org.apache.poi.xssf.usermodel.*;
-import org.apache.poi.xssf.usermodel.charts.*;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook; 
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 /**
  * Illustrates how to create a simple scatter chart.
+ *
+ * @author Roman Kashitsyn
  */
 public class ScatterChart {
 
-       public static void main(String[]args) throws Exception {
-               Workbook wb = new XSSFWorkbook();
-               CreationHelper creationHelper = wb.getCreationHelper();
-               Sheet sheet = wb.createSheet("Sheet 1");
-               final int NUM_OF_ROWS = 3;
-               final int NUM_OF_COLUMNS = 10;
+    public static void main(String[] args) throws Exception {
+        Workbook wb = new XSSFWorkbook();
+        Sheet sheet = wb.createSheet("Sheet 1");
+        final int NUM_OF_ROWS = 3;
+        final int NUM_OF_COLUMNS = 10;
+
+        // Create a row and put some cells in it. Rows are 0 based.
+        Row row;
+        Cell cell;
+        for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) {
+            row = sheet.createRow((short) rowIndex);
+            for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
+                cell = row.createCell((short) colIndex);
+                cell.setCellValue(colIndex * (rowIndex + 1));
+            }
+        }
 
-               // Create a row and put some cells in it. Rows are 0 based.
-               Row row;
-               Cell cell;
-               for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) {
-                       row = sheet.createRow((short)rowIndex);
-                       for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
-                               cell = row.createCell((short)colIndex);
-                               cell.setCellValue(colIndex * (rowIndex + 1));
-                       }
-               }
+        Drawing drawing = sheet.createDrawingPatriarch();
+        ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
 
-               Drawing drawing = sheet.createDrawingPatriarch();
-               ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
+        Chart chart = drawing.createChart(anchor);
+        ChartLegend legend = chart.getOrCreateLegend();
+        legend.setPosition(LegendPosition.TOP_RIGHT);
 
-               Chart chart = drawing.createChart(anchor);
-               ChartLegend legend = chart.getOrCreateLegend();
-               legend.setPosition(LegendPosition.TOP_RIGHT);
+        ScatterChartData data = chart.getChartDataFactory().createScatterChartData();
 
-               ScatterChartData data = chart.getChartDataFactory().createScatterChartData();
+        ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
+        ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
+        leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
 
-               ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
-               ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
+        ChartDataSource<Number> xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
+        ChartDataSource<Number> ys1 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));
+        ChartDataSource<Number> ys2 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
 
-               DataMarker xMarker = new DataMarker(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
-               DataMarker y1Marker = new DataMarker(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));
-               DataMarker y2Marker = new DataMarker(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
 
-               
-               data.addSerie(xMarker, y1Marker);
-               data.addSerie(xMarker, y2Marker);
+        data.addSerie(xs, ys1);
+        data.addSerie(xs, ys2);
 
-               chart.plot(data, bottomAxis, leftAxis);
+        chart.plot(data, bottomAxis, leftAxis);
 
-               // Write the output to a file
-               FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx");
-               wb.write(fileOut);
-               fileOut.close();
-       }
+        // Write the output to a file
+        FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx");
+        wb.write(fileOut);
+        fileOut.close();
+    }
 }
index 6542f991bf25033bf10d00b58d3e047ee3988163..e4ccdb5db8a0099e3edc4736cf32e21871f4c675 100644 (file)
 
 package org.apache.poi.ss.usermodel.charts;
 
+import org.apache.poi.util.Beta;
+
 /**
  * High level representation of chart axis.
  *
  * @author Roman Kashitsyn
  */
+@Beta
 public interface ChartAxis {
        
        /**
index 9c1e09dcbc592b96088db58dc021449295d7c1bc..bd037f500ff457a5a88e089bff41964b12428f51 100644 (file)
 package org.apache.poi.ss.usermodel.charts;
 
 import org.apache.poi.ss.usermodel.Chart;
+import org.apache.poi.util.Beta;
 
 /**
  * A factory for different chart axis.
  *
  * @author Roman Kashitsyn
  */
+@Beta
 public interface ChartAxisFactory {
        
        /**
index f2acc6fd0daa83e031127871b4f1ac29681a7b92..7a4aec5f0b4cece0e12f2375c1ca044e9def355b 100644 (file)
 package org.apache.poi.ss.usermodel.charts;
 
 import org.apache.poi.ss.usermodel.Chart;
+import org.apache.poi.util.Beta;
 
 /**
- * A base for all chart data types.
+ * A base for all charts data types.
  *
  * @author Roman Kashitsyn
  */
+@Beta
 public interface ChartData {
 
        /**
-        * Fills a chart with data specified by implementation.
+        * Fills a charts with data specified by implementation.
         *
-        * @param chart a chart to fill in
-        * @param axis chart axis to use
+        * @param chart a charts to fill in
+        * @param axis charts axis to use
         */
        void fillChart(Chart chart, ChartAxis... axis);
 }
index 3914fcd4a0439c7e3a672f0895cbdc9f252e9fa4..f75e66307d3cf1a18f774786b87e89c260eb7b06 100644 (file)
 
 package org.apache.poi.ss.usermodel.charts;
 
+import org.apache.poi.util.Beta;
+
 /**
- * A factory for different chart data types.
+ * A factory for different charts data types.
  *
  * @author Roman Kashitsyn
  */
+@Beta
 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
new file mode 100644 (file)
index 0000000..d843cac
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+package org.apache.poi.ss.usermodel.charts;
+
+import org.apache.poi.util.Beta;
+
+/**
+ * Represents data model of the charts.
+ *
+ * @param <T> type of points the data source contents
+ * @author Roman Kashitsyn
+ */
+@Beta
+public interface ChartDataSource<T> {
+
+    /**
+     * Return number of points contained by data source.
+     *
+     * @return number of points contained by data source
+     */
+    int getPointCount();
+
+    /**
+     * Returns point value at specified index.
+     *
+     * @param index index to value from
+     * @return point value at specified index.
+     * @throws {@code IndexOutOfBoundsException} if index
+     *                parameter not in range {@code 0 <= index <= pointCount}
+     */
+    T getPointAt(int index);
+
+    /**
+     * Returns {@code true} if charts data source is valid cell range.
+     *
+     * @return {@code true} if charts data source is valid cell range
+     */
+    boolean isReference();
+
+    /**
+     * Returns {@code true} if data source points should be treated as numbers.
+     *
+     * @return {@code true} if data source points should be treated as numbers
+     */
+    boolean isNumeric();
+
+    /**
+     * Returns formula representation of the data source. It is only applicable
+     * for data source that is valid cell range.
+     *
+     * @return formula representation of the data source
+     * @throws {@code UnsupportedOperationException} if the data source is not a
+     *                reference.
+     */
+    String getFormulaString();
+}
index b870a773ec0037c0e47a5f1fbc8534e4abe3565e..f40664f9c00295ce54cf68e220ee12dd236c22bd 100644 (file)
 
 package org.apache.poi.ss.usermodel.charts;
 
+import org.apache.poi.util.Beta;
+
 /**
  * High level representation of chart legend.
  *
  * @author Roman Kashitsyn
  */
+@Beta
 public interface ChartLegend extends ManuallyPositionable {
        
        /**
diff --git a/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java b/src/java/org/apache/poi/ss/usermodel/charts/DataSources.java
new file mode 100644 (file)
index 0000000..bd78672
--- /dev/null
@@ -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.ss.usermodel.charts;
+
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.util.Beta;
+
+/**
+ * Class {@code DataSources} is a factory for {@link ChartDataSource} instances.
+ *
+ * @author Roman Kashitsyn
+ */
+@Beta
+public class DataSources {
+
+    private DataSources() {
+    }
+
+    public static <T> ChartDataSource<T> fromArray(T[] elements) {
+        return new ArrayDataSource<T>(elements);
+    }
+
+    public static ChartDataSource<Number> fromNumericCellRange(Sheet sheet, CellRangeAddress cellRangeAddress) {
+        return new AbstractCellRangeDataSource<Number>(sheet, cellRangeAddress) {
+            public Number getPointAt(int index) {
+                CellValue cellValue = getCellValueAt(index);
+                if (cellValue != null && cellValue.getCellType() == Cell.CELL_TYPE_NUMERIC) {
+                    return Double.valueOf(cellValue.getNumberValue());
+                } else {
+                    return null;
+                }
+            }
+
+            public boolean isNumeric() {
+                return true;
+            }
+        };
+    }
+
+    public static ChartDataSource<String> fromStringCellRange(Sheet sheet, CellRangeAddress cellRangeAddress) {
+        return new AbstractCellRangeDataSource<String>(sheet, cellRangeAddress) {
+            public String getPointAt(int index) {
+                CellValue cellValue = getCellValueAt(index);
+                if (cellValue != null && cellValue.getCellType() == Cell.CELL_TYPE_STRING) {
+                    return cellValue.getStringValue();
+                } else {
+                    return null;
+                }
+            }
+
+            public boolean isNumeric() {
+                return false;
+            }
+        };
+    }
+
+    private static class ArrayDataSource<T> implements ChartDataSource<T> {
+
+        private final T[] elements;
+
+        public ArrayDataSource(T[] elements) {
+            this.elements = elements;
+        }
+
+        public int getPointCount() {
+            return elements.length;
+        }
+
+        public T getPointAt(int index) {
+            return elements[index];
+        }
+
+        public boolean isReference() {
+            return false;
+        }
+
+        public boolean isNumeric() {
+            Class<?> arrayComponentType = elements.getClass().getComponentType();
+            return (Number.class.isAssignableFrom(arrayComponentType));
+        }
+
+        public String getFormulaString() {
+            throw new UnsupportedOperationException("Literal data source can not be expressed by reference.");
+        }
+    }
+
+    private abstract static class AbstractCellRangeDataSource<T> implements ChartDataSource<T> {
+        private final Sheet sheet;
+        private final CellRangeAddress cellRangeAddress;
+        private final int numOfCells;
+        private FormulaEvaluator evaluator;
+
+        protected AbstractCellRangeDataSource(Sheet 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();
+        }
+
+        public int getPointCount() {
+            return numOfCells;
+        }
+
+        public boolean isReference() {
+            return true;
+        }
+
+        public String getFormulaString() {
+            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;
+            Row row = sheet.getRow(rowIndex);
+            return (row == null) ? null : evaluator.evaluate(row.getCell(cellIndex));
+        }
+    }
+}
index 993ab3dafd10857e58d53764e0f5637417cf1197..2d8bfbd96f94fd17ca6cae208b7d3097d7195d6b 100644 (file)
 \r
 package org.apache.poi.ss.usermodel.charts;\r
 \r
+import org.apache.poi.util.Beta;\r
+\r
 /**\r
  * High level representation of chart element manual layout.\r
  *\r
  * @author Roman Kashitsyn\r
  */\r
+@Beta\r
 public interface ManualLayout {\r
 \r
        /**\r
index 03a85a4bcef3f55a333a2bd13c56b0fe7ec00f62..0d749fb4b9ec51e06294d2942e232529dd202514 100644 (file)
 \r
 package org.apache.poi.ss.usermodel.charts;\r
 \r
+import org.apache.poi.util.Beta;\r
+\r
 /**\r
  * Abstraction of chart element that can be positioned with manual\r
  * layout.\r
  *\r
  * @author Roman Kashitsyn\r
  */\r
+@Beta\r
 public interface ManuallyPositionable {\r
 \r
        /**\r
index 09e10048efffcb8128328c0688db850aa4a2b367..81917473b0534675282c177fdce7f9eb2674b9ca 100644 (file)
 package org.apache.poi.ss.usermodel.charts;
 
 import java.util.List;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.util.DataMarker;
-
 
 /**
  * @author Roman Kashitsyn
  */
 public interface ScatterChartData extends ChartData {
        /**
-        * @param xMarker data marker to be used for X value range
-        * @param yMarker data marker to be used for Y value range
-        * @return a new scatter chart serie
+        * @param xs data source to be used for X axis values
+        * @param ys data source to be used for Y axis values
+        * @return a new scatter charts serie
         */
-       ScatterChartSerie addSerie(DataMarker xMarker, DataMarker yMarker);
+       ScatterChartSerie addSerie(ChartDataSource<?> xs, ChartDataSource<? extends Number> ys);
 
        /**
         * @return list of all series
index 16cef9c5fa8480a6bb924644a72b28f5c5decd50..c968f79698513d2c319572dc21f017e2a2ba2f3f 100644 (file)
 
 package org.apache.poi.ss.usermodel.charts;
 
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.util.DataMarker;
-import org.apache.poi.ss.usermodel.charts.ChartDataFactory;
+import org.apache.poi.util.Beta;
 
 /**
+ * Represents scatter charts serie.
+ *
  * @author Roman Kashitsyn
  */
+@Beta
 public interface ScatterChartSerie {
 
-       /**
-        * @param xMarker data marker to use for X values.
-        */
-       void setXValues(DataMarker xMarker);
+    /**
+     * @return data source used for X axis values
+     */
+    ChartDataSource<?> getXValues();
 
-       /**'
-        * @param yMarker data marker to use for Y values.
-        */
-       void setYValues(DataMarker yMarker);
+    /**
+     * @return data source used for Y axis values
+     */
+    ChartDataSource<? extends Number> getYValues();
 
 }
index 56132573ab7a0c34dbbfca689fdf3e225868d9e6..f6673dae47e5a9676b3a38b1fb510d104591187c 100644 (file)
 
 package org.apache.poi.ss.usermodel.charts;
 
+import org.apache.poi.util.Beta;
+
 /**
  * @author Roman Kashitsyn
  */
+@Beta
 public interface ValueAxis extends ChartAxis {
 
        /**
index 628a975aaa5f63256d466c414bd5d690add5e7ea..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,87 +0,0 @@
-/*\r
- *  ====================================================================\r
- *    Licensed to the Apache Software Foundation (ASF) under one or more\r
- *    contributor license agreements.  See the NOTICE file distributed with\r
- *    this work for additional information regarding copyright ownership.\r
- *    The ASF licenses this file to You under the Apache License, Version 2.0\r
- *    (the "License"); you may not use this file except in compliance with\r
- *    the License.  You may obtain a copy of the License at\r
- *\r
- *        http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- *    Unless required by applicable law or agreed to in writing, software\r
- *    distributed under the License is distributed on an "AS IS" BASIS,\r
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- *    See the License for the specific language governing permissions and\r
- *    limitations under the License.\r
- * ====================================================================\r
- */\r
-\r
-package org.apache.poi.ss.util;\r
-\r
-import org.apache.poi.ss.usermodel.Sheet;\r
-\r
-/**\r
- * Represents data marker used in charts.\r
- * @author Roman Kashitsyn\r
- */\r
-public class DataMarker {\r
-       \r
-       private Sheet sheet;\r
-       private CellRangeAddress range;\r
-\r
-       /**\r
-        * @param sheet the sheet where data located.\r
-        * @param range the range within that sheet.\r
-        */\r
-       public DataMarker(Sheet sheet, CellRangeAddress range) {\r
-               this.sheet = sheet;\r
-               this.range = range;\r
-       }\r
-\r
-       /**\r
-        * Returns the sheet marker points to.\r
-        * @return sheet marker points to.\r
-        */\r
-       public Sheet getSheet() {\r
-               return sheet;\r
-       }\r
-\r
-       /**\r
-        * Sets sheet marker points to.\r
-        * @param sheet new sheet for the marker.\r
-        */\r
-       public void setSheet(Sheet sheet) {\r
-               this.sheet = sheet;\r
-       }\r
-\r
-       /**\r
-        * Returns range of the marker.\r
-        * @return range of cells marker points to.\r
-        */\r
-       public CellRangeAddress getRange() {\r
-               return range;\r
-       }\r
-\r
-       /**\r
-        * Sets range of the marker.\r
-        * @param range new range for the marker.\r
-        */\r
-       public void setRange(CellRangeAddress range) {\r
-               this.range = range;\r
-       }\r
-\r
-       /**\r
-        * Formats data marker using canonical format, for example\r
-        * `SheetName!$A$1:$A$5'.\r
-        * @return formatted data marker.\r
-        */\r
-    public String formatAsString() {\r
-               String sheetName = (sheet == null) ? (null) : (sheet.getSheetName());\r
-               if (range == null) {\r
-                       return null;\r
-               } else {\r
-                       return range.formatAsString(sheetName, true);\r
-               }\r
-    }\r
-}\r
index 31609001fd5d75f241a7d6472ba55f7f5c97bcaf..960d2d6ca207cd7f86165314f9c540bd8a23138f 100644 (file)
@@ -25,115 +25,134 @@ import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Cell;
 
 /**
- * Class that provides useful sheet build capabilities. It can be used
- * in test cases to improve readability or in Swing applications with
- * tables.
+ * Class {@code SheetBuilder} provides an easy way of building workbook sheets
+ * from 2D array of Objects. It can be used in test cases to improve code
+ * readability or in Swing applications with tables.
  *
  * @author Roman Kashitsyn
  */
 public class SheetBuilder {
 
-    private Workbook workbook;
-    private Object[][] cells;
+    private final Workbook workbook;
+    private final Object[][] cells;
     private boolean shouldCreateEmptyCells = false;
+    private String sheetName = null;
 
     public SheetBuilder(Workbook workbook, Object[][] cells) {
-       this.workbook = workbook;
-       this.cells = cells;
+        this.workbook = workbook;
+        this.cells = cells;
     }
 
     /**
-     * @return true if null objects should be trated as empty cells
-     *         false otherwise
+     * Returns {@code true} if null array elements should be treated as empty
+     * cells.
+     *
+     * @return {@code true} if null objects should be treated as empty cells
+     *         and {@code false} otherwise
      */
     public boolean getCreateEmptyCells() {
-       return shouldCreateEmptyCells;
+        return shouldCreateEmptyCells;
     }
 
     /**
-     * @param shouldCreateEmptyCells true if null array elements should be
-     *        trated as empty cells
-     * @return this
+     * Specifies if null array elements should be treated as empty cells.
+     *
+     * @param shouldCreateEmptyCells {@code true} if null array elements should be
+     *                               treated as empty cells
+     * @return {@code this}
      */
     public SheetBuilder setCreateEmptyCells(boolean shouldCreateEmptyCells) {
-       this.shouldCreateEmptyCells = shouldCreateEmptyCells;
-       return this;
+        this.shouldCreateEmptyCells = shouldCreateEmptyCells;
+        return this;
+    }
+
+    /**
+     * Specifies name of the sheet to build. If not specified, default name (provided by
+     * workbook) will be used instead.
+     * @param sheetName sheet name to use
+     * @return {@code this}
+     */
+    public SheetBuilder setSheetName(String sheetName) {
+        this.sheetName = sheetName;
+        return this;
     }
 
     /**
      * Builds sheet from parent workbook and 2D array with cell
      * values. Creates rows anyway (even if row contains only null
-     * cells), creates cells only if corresponding property is true.
+     * cells), creates cells if either corresponding array value is not
+     * null or createEmptyCells property is true.
      * The conversion is performed in the following way:
-     *
+     * <p/>
      * <ul>
      * <li>Numbers become numeric cells.</li>
      * <li><code>java.util.Date</code> or <code>java.util.Calendar</code>
-     *     instances become date cells.</li>
+     * instances become date cells.</li>
      * <li>String with leading '=' char become formulas (leading '='
-     *     trancated).</li>
+     * will be truncated).</li>
      * <li>Other objects become strings via <code>Object.toString()</code>
-     *     method.</li>
+     * method call.</li>
      * </ul>
      *
      * @return newly created sheet
      */
     public Sheet build() {
-       Sheet sheet = workbook.createSheet();
-       Row currentRow = null;
-       Cell currentCell = null;
+        Sheet sheet = (sheetName == null) ? workbook.createSheet() : workbook.createSheet(sheetName);
+        Row currentRow = null;
+        Cell currentCell = null;
 
-       for (int rowIndex = 0; rowIndex < cells.length; ++rowIndex) {
-           Object[] rowArray = cells[rowIndex];
-           currentRow = sheet.createRow(rowIndex);
+        for (int rowIndex = 0; rowIndex < cells.length; ++rowIndex) {
+            Object[] rowArray = cells[rowIndex];
+            currentRow = sheet.createRow(rowIndex);
 
-           for (int cellIndex = 0; cellIndex < rowArray.length; ++cellIndex) {
-               Object cellValue = rowArray[cellIndex];
-               if (cellValue != null || shouldCreateEmptyCells) {
-                   currentCell = currentRow.createCell(cellIndex);
-                   setCellValue(currentCell, cellValue);
-               }
-           }
-       }
-       return sheet;
+            for (int cellIndex = 0; cellIndex < rowArray.length; ++cellIndex) {
+                Object cellValue = rowArray[cellIndex];
+                if (cellValue != null || shouldCreateEmptyCells) {
+                    currentCell = currentRow.createCell(cellIndex);
+                    setCellValue(currentCell, cellValue);
+                }
+            }
+        }
+        return sheet;
     }
 
     /**
      * Sets the cell value using object type information.
-     * @param cell cell to change
+     *
+     * @param cell  cell to change
      * @param value value to set
      */
-    public void setCellValue(Cell cell, Object value) {
-       if (value == null || cell == null) {
-           return;
-       } else if (value instanceof Number) {
-           double doubleValue = ((Number) value).doubleValue();
-           cell.setCellValue(doubleValue);
-       } else if (value instanceof Date) {
-           cell.setCellValue((Date) value);
-       } else if (value instanceof Calendar) {
-           cell.setCellValue((Calendar) value);
-       } else if (isFormulaDefinition(value)) {
-           cell.setCellFormula(getFormula(value));
-       } else {
-           cell.setCellValue(value.toString());
-       }
+    private void setCellValue(Cell cell, Object value) {
+        if (value == null || cell == null) {
+            return;
+        } else if (value instanceof Number) {
+            double doubleValue = ((Number) value).doubleValue();
+            cell.setCellValue(doubleValue);
+        } else if (value instanceof Date) {
+            cell.setCellValue((Date) value);
+        } else if (value instanceof Calendar) {
+            cell.setCellValue((Calendar) value);
+        } else if (isFormulaDefinition(value)) {
+            cell.setCellFormula(getFormula(value));
+        } else {
+            cell.setCellValue(value.toString());
+        }
     }
 
     private boolean isFormulaDefinition(Object obj) {
-       if (obj instanceof String) {
-           String str = (String) obj;
-           if (str.length() < 2) {
-               return false;
-           } else {
-               return ((String) obj).charAt(0) == '=';
-           }
-       } else {
-           return false;
-       }
+        if (obj instanceof String) {
+            String str = (String) obj;
+            if (str.length() < 2) {
+                return false;
+            } else {
+                return ((String) obj).charAt(0) == '=';
+            }
+        } else {
+            return false;
+        }
     }
 
     private String getFormula(Object obj) {
-       return ((String) obj).substring(1);
+        return ((String) obj).substring(1);
     }
 }
\ No newline at end of file
index 53e21640cfc13543dc7826ed051aee8044ae0acc..4efd80d60c8a1844d556cf8ee9e208c1ba0754e0 100644 (file)
 
 package org.apache.poi.ss.util.cellwalk;
 
-
 import org.apache.poi.ss.usermodel.Cell;
 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.ss.util.DataMarker;
 
 /**
  * Traverse cell range.
@@ -35,95 +33,96 @@ public class CellWalk {
     private CellRangeAddress range;
     private boolean traverseEmptyCells;
 
-    public CellWalk(DataMarker dm) {
-       this(dm.getSheet(), dm.getRange());
-    }
 
     public CellWalk(Sheet sheet, CellRangeAddress range) {
-       this.sheet = sheet;
-       this.range = range;
-       this.traverseEmptyCells = false;
+        this.sheet = sheet;
+        this.range = range;
+        this.traverseEmptyCells = false;
     }
 
     /**
      * Should we call handler on empty (blank) cells. Default is
      * false.
+     *
      * @return true if handler should be called on empty (blank)
-     * cells, false otherwise.
+     *         cells, false otherwise.
      */
     public boolean isTraverseEmptyCells() {
-       return traverseEmptyCells;
+        return traverseEmptyCells;
     }
 
     /**
      * Sets the traverseEmptyCells property.
+     *
      * @param traverseEmptyCells new property value
      */
     public void setTraverseEmptyCells(boolean traverseEmptyCells) {
-       this.traverseEmptyCells = traverseEmptyCells;
+        this.traverseEmptyCells = traverseEmptyCells;
     }
 
     /**
      * Traverse cell range from top left to bottom right cell.
+     *
      * @param handler handler to call on each appropriate cell
      */
     public void traverse(CellHandler handler) {
-       int firstRow = range.getFirstRow();
-       int lastRow = range.getLastRow();
-       int firstColumn = range.getFirstColumn();
-       int lastColumn = range.getLastColumn();
-       final int width = lastColumn - firstColumn + 1;
-       SimpleCellWalkContext ctx = new SimpleCellWalkContext();
-       Row currentRow = null;
-       Cell currentCell = null;
-
-       for (ctx.rowNumber = firstRow; ctx.rowNumber <= lastRow; ++ctx.rowNumber) {
-           currentRow = sheet.getRow(ctx.rowNumber);
-           if (currentRow == null) {
-               continue;
-           }
-           for (ctx.colNumber = firstColumn; ctx.colNumber <= lastColumn; ++ctx.colNumber) {
-               currentCell = currentRow.getCell(ctx.colNumber);
-
-               if (currentCell == null) {
-                   continue;
-               }
-               if (isEmpty(currentCell) && !traverseEmptyCells) {
-                   continue;
-               }
-
-               ctx.ordinalNumber =
-                   (ctx.rowNumber - firstRow) * width +
-                   (ctx.colNumber - firstColumn + 1);
-
-               handler.onCell(currentCell, ctx);
-           }
-       }
+        int firstRow = range.getFirstRow();
+        int lastRow = range.getLastRow();
+        int firstColumn = range.getFirstColumn();
+        int lastColumn = range.getLastColumn();
+        final int width = lastColumn - firstColumn + 1;
+        SimpleCellWalkContext ctx = new SimpleCellWalkContext();
+        Row currentRow = null;
+        Cell currentCell = null;
+
+        for (ctx.rowNumber = firstRow; ctx.rowNumber <= lastRow; ++ctx.rowNumber) {
+            currentRow = sheet.getRow(ctx.rowNumber);
+            if (currentRow == null) {
+                continue;
+            }
+            for (ctx.colNumber = firstColumn; ctx.colNumber <= lastColumn; ++ctx.colNumber) {
+                currentCell = currentRow.getCell(ctx.colNumber);
+
+                if (currentCell == null) {
+                    continue;
+                }
+                if (isEmpty(currentCell) && !traverseEmptyCells) {
+                    continue;
+                }
+
+                ctx.ordinalNumber =
+                        (ctx.rowNumber - firstRow) * width +
+                                (ctx.colNumber - firstColumn + 1);
+
+                handler.onCell(currentCell, ctx);
+            }
+        }
     }
 
     private boolean isEmpty(Cell cell) {
-       return (cell.getCellType() == Cell.CELL_TYPE_BLANK);
+        return (cell.getCellType() == Cell.CELL_TYPE_BLANK);
     }
 
     /**
      * Inner class to hold walk context.
+     *
      * @author Roman Kashitsyn
      */
     private class SimpleCellWalkContext implements CellWalkContext {
-       public long ordinalNumber = 0;
-       public int rowNumber = 0;
-       public int colNumber = 0;
+        public long ordinalNumber = 0;
+        public int rowNumber = 0;
+        public int colNumber = 0;
 
-       public long getOrdinalNumber() {
-           return ordinalNumber;
-       }
+        public long getOrdinalNumber() {
+            return ordinalNumber;
+        }
 
-       public int getRowNumber() {
-           return rowNumber;
-       }
+        public int getRowNumber() {
+            return rowNumber;
+        }
 
-       public int getColumnNumber() {
-           return colNumber;
-       }
+        public int getColumnNumber() {
+            return colNumber;
+        }
     }
 }
index 95467c6b18138f05f96b7be50a3b5ded5676e458..d2162d05317131eeaccdf92fdf7dcc04c98db643 100644 (file)
@@ -21,6 +21,7 @@ import org.apache.poi.ss.usermodel.charts.ChartAxis;
 import org.apache.poi.ss.usermodel.charts.AxisPosition;
 import org.apache.poi.ss.usermodel.charts.AxisOrientation;
 import org.apache.poi.ss.usermodel.charts.AxisCrosses;
+import org.apache.poi.util.Beta;
 import org.apache.poi.xssf.usermodel.XSSFChart;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos;
@@ -38,6 +39,7 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.STCrosses;
  *
  * @author Roman Kashitsyn
  */
+@Beta
 public abstract class XSSFChartAxis implements ChartAxis {
 
        protected XSSFChart chart;
index b36f917875f595cb5aac1ff8dff62683fc1da799..57b826a186a4e3222b9c1a9e29df1e78fcb0b52b 100644 (file)
 package org.apache.poi.xssf.usermodel.charts;
 
 import org.apache.poi.ss.usermodel.charts.*;
+import org.apache.poi.util.Beta;
 
 /**
  * @author Roman Kashitsyn
  */
+@Beta
 public class XSSFChartDataFactory implements ChartDataFactory {
 
        private static XSSFChartDataFactory instance;
@@ -31,7 +33,7 @@ public class XSSFChartDataFactory implements ChartDataFactory {
        }
 
        /**
-        * @return new scatter chart data instance
+        * @return new scatter charts data instance
         */
        public XSSFScatterChartData createScatterChartData() {
                return new XSSFScatterChartData();
index 112357349101e2f9454d6b8b4ee2698d8bbcbccd..896e6dff2269b7e632c93fb6485ea07223cccdb2 100644 (file)
@@ -17,6 +17,7 @@
 
 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.ChartLegend;
 import org.apache.poi.ss.usermodel.charts.LegendPosition;
@@ -30,6 +31,7 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.STLegendPos;
  * Represents a SpreadsheetML chart legend
  * @author Roman Kashitsyn
  */
+@Beta
 public final class XSSFChartLegend implements ChartLegend {
 
        /**
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartUtil.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFChartUtil.java
new file mode 100644 (file)
index 0000000..d0a13b4
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.xssf.usermodel.charts;
+
+import org.apache.poi.ss.usermodel.charts.ChartDataSource;
+import org.openxmlformats.schemas.drawingml.x2006.chart.*;
+
+/**
+ * Package private class with utility methods.
+ *
+ * @author Roman Kashitsyn
+ */
+class XSSFChartUtil {
+
+    private XSSFChartUtil() {}
+
+    /**
+     * Builds CTAxDataSource object content from POI ChartDataSource.
+     * @param ctAxDataSource OOXML data source to build
+     * @param dataSource POI data source to use
+     */
+    public static void buildAxDataSource(CTAxDataSource ctAxDataSource, ChartDataSource<?> dataSource) {
+        if (dataSource.isNumeric()) {
+            if (dataSource.isReference()) {
+                buildNumRef(ctAxDataSource.addNewNumRef(), dataSource);
+            } else {
+                buildNumLit(ctAxDataSource.addNewNumLit(), dataSource);
+            }
+        } else {
+            if (dataSource.isReference()) {
+                buildStrRef(ctAxDataSource.addNewStrRef(), dataSource);
+            } else {
+                buildStrLit(ctAxDataSource.addNewStrLit(), dataSource);
+            }
+        }
+    }
+
+    /**
+     * Builds CTNumDataSource object content from POI ChartDataSource
+     * @param ctNumDataSource OOXML data source to build
+     * @param dataSource POI data source to use
+     */
+    public static void buildNumDataSource(CTNumDataSource ctNumDataSource,
+                                          ChartDataSource<? extends Number> dataSource) {
+        if (dataSource.isReference()) {
+            buildNumRef(ctNumDataSource.addNewNumRef(), dataSource);
+        } else {
+            buildNumLit(ctNumDataSource.addNewNumLit(), dataSource);
+        }
+    }
+
+    private static void buildNumRef(CTNumRef ctNumRef, ChartDataSource<?> dataSource) {
+        ctNumRef.setF(dataSource.getFormulaString());
+        CTNumData cache = ctNumRef.addNewNumCache();
+        fillNumCache(cache, dataSource);
+    }
+
+    private static void buildNumLit(CTNumData ctNumData, ChartDataSource<?> dataSource) {
+        fillNumCache(ctNumData, dataSource);
+    }
+
+    private static void buildStrRef(CTStrRef ctStrRef, ChartDataSource<?> dataSource) {
+        ctStrRef.setF(dataSource.getFormulaString());
+        CTStrData cache = ctStrRef.addNewStrCache();
+        fillStringCache(cache, dataSource);
+    }
+
+    private static void buildStrLit(CTStrData ctStrData, ChartDataSource<?> dataSource) {
+        fillStringCache(ctStrData, dataSource);
+    }
+
+    private static void fillStringCache(CTStrData cache, ChartDataSource<?> dataSource) {
+        int numOfPoints = dataSource.getPointCount();
+        cache.addNewPtCount().setVal(numOfPoints);
+        for (int i = 0; i < numOfPoints; ++i) {
+            Object value = dataSource.getPointAt(i);
+            if (value != null) {
+                CTStrVal ctStrVal = cache.addNewPt();
+                ctStrVal.setIdx(i);
+                ctStrVal.setV(value.toString());
+            }
+        }
+
+    }
+
+    private static void fillNumCache(CTNumData cache, ChartDataSource<?> dataSource) {
+        int numOfPoints = dataSource.getPointCount();
+        cache.addNewPtCount().setVal(numOfPoints);
+        for (int i = 0; i < numOfPoints; ++i) {
+            Number value = (Number) dataSource.getPointAt(i);
+            if (value != null) {
+                CTNumVal ctNumVal = cache.addNewPt();
+                ctNumVal.setIdx(i);
+                ctNumVal.setV(value.toString());
+            }
+        }
+    }
+}
index 81bf55a06ae6dfe2d06e3c75dcd7a336971968eb..087dfb553d14693522df837c57b5d97633c6a951 100644 (file)
@@ -17,6 +17,7 @@
 \r
 package org.apache.poi.xssf.usermodel.charts;\r
 \r
+import org.apache.poi.util.Beta;\r
 import org.apache.poi.util.Internal;\r
 import org.apache.poi.ss.usermodel.charts.ManualLayout;\r
 import org.apache.poi.ss.usermodel.charts.LayoutMode;\r
@@ -35,6 +36,7 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget;
  * Represents a SpreadsheetML manual layout.\r
  * @author Roman Kashitsyn\r
  */\r
+@Beta\r
 public final class XSSFManualLayout implements ManualLayout {\r
 \r
        /**\r
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFNumberCache.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/charts/XSSFNumberCache.java
deleted file mode 100644 (file)
index 0490204..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-==================================================================== */
-
-package org.apache.poi.xssf.usermodel.charts;
-
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.FormulaEvaluator;
-import org.apache.poi.ss.usermodel.CellValue;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.ss.util.CellRangeAddress;
-import org.apache.poi.ss.util.NumberToTextConverter;
-import org.apache.poi.ss.util.DataMarker;
-import org.apache.poi.ss.util.cellwalk.CellWalk;
-import org.apache.poi.ss.util.cellwalk.CellHandler;
-import org.apache.poi.ss.util.cellwalk.CellWalkContext;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumVal;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTUnsignedInt;
-
-/**
- * Package private class to fill chart's number reference with cached
- * numeric values. If a formula-typed cell referenced by data marker,
- * cell's value will be calculated and placed to cache. Numeric cells
- * will be placed to cache as is. Non-numeric cells will be ignored.
- *
- * @author Roman Kashitsyn
- */
-class XSSFNumberCache {
-
-    private CTNumData ctNumData;
-
-    XSSFNumberCache(CTNumData ctNumData) {
-       this.ctNumData = ctNumData;
-    }
-
-    /**
-     * Builds new numeric cache container.
-     * @param marker data marker to use for cache evaluation
-     * @param ctNumRef parent number reference
-     * @return numeric cache instance
-     */
-    static XSSFNumberCache buildCache(DataMarker marker, CTNumRef ctNumRef) {
-       CellRangeAddress range = marker.getRange();
-       int numOfPoints = range.getNumberOfCells();
-
-       if (numOfPoints == 0) {
-           // Nothing to do.
-           return null;
-       }
-
-       XSSFNumberCache cache = new XSSFNumberCache(ctNumRef.addNewNumCache());
-       cache.setPointCount(numOfPoints);
-
-       Workbook wb = marker.getSheet().getWorkbook();
-       FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
-
-       CellWalk cellWalk = new CellWalk(marker);
-       NumCacheCellHandler numCacheHandler = cache.new NumCacheCellHandler(evaluator);
-       cellWalk.traverse(numCacheHandler);
-       return cache;
-    }
-    
-    /**
-     * Returns total count of points in cache. Some (or even all) of
-     * them might be empty.
-     * @return total count of points in cache
-     */
-    long getPointCount() {
-       CTUnsignedInt pointCount = ctNumData.getPtCount();
-       if (pointCount != null) {
-           return pointCount.getVal();
-       } else {
-           return 0L;
-       }
-    }
-
-    /**
-     * Returns cache value at specified index.
-     * @param index index of the point in cache
-     * @return point value
-     */
-    double getValueAt(int index) {
-       /* TODO: consider more effective algorithm. Left as is since
-        * this method should be invoked mostly in tests. */
-       for (CTNumVal pt : ctNumData.getPtList()) {
-           if (pt.getIdx() == index) {
-               return Double.valueOf(pt.getV()).doubleValue();
-           }
-       }
-       return 0.0;
-    }
-
-    private void setPointCount(int numOfPoints) {
-       ctNumData.addNewPtCount().setVal(numOfPoints);
-    }
-
-    private class NumCacheCellHandler implements CellHandler {
-
-       private FormulaEvaluator evaluator;
-
-       public NumCacheCellHandler(FormulaEvaluator evaluator) {
-           this.evaluator = evaluator;
-       }
-
-       public void onCell(Cell cell, CellWalkContext ctx) {
-           double pointValue = getOrEvalCellValue(cell);
-           /* Silently ignore non-numeric values.
-            * This is Office default behaviour. */
-           if (Double.isNaN(pointValue)) {
-               return;
-           }
-
-           CTNumVal point = ctNumData.addNewPt();
-           point.setIdx(ctx.getOrdinalNumber());
-           point.setV(NumberToTextConverter.toText(pointValue));
-       }
-
-       private double getOrEvalCellValue(Cell cell) {
-           int cellType = cell.getCellType();
-
-           if (cellType == Cell.CELL_TYPE_NUMERIC) {
-               return cell.getNumericCellValue();
-           } else if (cellType == Cell.CELL_TYPE_FORMULA) {
-               CellValue value = evaluator.evaluate(cell);
-               if (value.getCellType() == Cell.CELL_TYPE_NUMERIC) {
-                   return value.getNumberValue();
-               }
-           }
-           return Double.NaN;
-       }
-
-    }
-}
index 36959b2d4d88250d4adf12da8981c82580ec6164..23876272ee037682401c5fc891c09b88717f462c 100644 (file)
 
 package org.apache.poi.xssf.usermodel.charts;
 
-import java.util.List;
-import java.util.ArrayList;
-
 import org.apache.poi.ss.usermodel.Chart;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.util.DataMarker;
+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.ScatterChartSerie;
-import org.apache.poi.ss.usermodel.charts.ChartDataFactory;
-import org.apache.poi.ss.usermodel.charts.ChartAxis;
+import org.apache.poi.util.Beta;
+import org.apache.poi.xssf.usermodel.XSSFChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.*;
 
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterStyle;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterSer;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumFmt;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
-import org.openxmlformats.schemas.drawingml.x2006.chart.STScatterStyle;
-import org.openxmlformats.schemas.drawingml.x2006.chart.STCrosses;
-import org.openxmlformats.schemas.drawingml.x2006.chart.STCrossBetween;
-import org.openxmlformats.schemas.drawingml.x2006.chart.STOrientation;
-import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos;
-import org.openxmlformats.schemas.drawingml.x2006.chart.STAxPos;
+import java.util.ArrayList;
+import java.util.List;
 
-import org.apache.poi.xssf.usermodel.XSSFChart;
 
 /**
- * Represents DrawingML scatter chart.
+ * Represents DrawingML scatter charts.
  *
  * @author Roman Kashitsyn
  */
+@Beta
 public class XSSFScatterChartData implements ScatterChartData {
 
     /**
@@ -59,118 +44,93 @@ public class XSSFScatterChartData implements ScatterChartData {
     private List<Serie> series;
 
     public XSSFScatterChartData() {
-       series = new ArrayList<Serie>();
+        series = new ArrayList<Serie>();
     }
 
     /**
      * Package private ScatterChartSerie implementation.
      */
     static class Serie implements ScatterChartSerie {
-       private int id;
-       private int order;
-       private boolean useCache;
-       private DataMarker xMarker;
-       private DataMarker yMarker;
-       private XSSFNumberCache lastCaclulatedXCache;
-       private XSSFNumberCache lastCalculatedYCache;
-
-       protected Serie(int id, int order) {
-           super();
-           this.id = id;
-           this.order = order;
-           this.useCache = true;
-       }
-
-       public void setXValues(DataMarker marker) {
-           xMarker = marker;
-       }
-
-       public void setYValues(DataMarker marker) {
-           yMarker = marker;
-       }
-
-       /**
-        * @param useCache if true, cached results will be added on plot
-        */
-       public void setUseCache(boolean useCache) {
-           this.useCache = useCache;
-       }
-
-       /**
-        * Returns last calculated number cache for X axis.
-        * @return last calculated number cache for X axis.
-        */
-       XSSFNumberCache getLastCaculatedXCache() {
-           return lastCaclulatedXCache;
-       }
-
-       /**
-        * Returns last calculated number cache for Y axis.
-        * @return last calculated number cache for Y axis.
-        */
-       XSSFNumberCache getLastCalculatedYCache() {
-           return lastCalculatedYCache;
-       }
-
-       protected void addToChart(CTScatterChart ctScatterChart) {
-           CTScatterSer scatterSer = ctScatterChart.addNewSer();
-           scatterSer.addNewIdx().setVal(this.id);
-           scatterSer.addNewOrder().setVal(this.order);
-
-           /* TODO: add some logic to automatically recognize cell
-            * types and choose appropriate data representation for
-            * X axis.
-            */
-           CTAxDataSource xVal = scatterSer.addNewXVal();
-           CTNumRef xNumRef = xVal.addNewNumRef();
-           xNumRef.setF(xMarker.formatAsString());
-
-           CTNumDataSource yVal = scatterSer.addNewYVal();
-           CTNumRef yNumRef = yVal.addNewNumRef();
-           yNumRef.setF(yMarker.formatAsString());
-
-           if (useCache) {
-               /* We can not store cache since markers are not immutable */
-               XSSFNumberCache.buildCache(xMarker, xNumRef);
-               lastCalculatedYCache = XSSFNumberCache.buildCache(yMarker, yNumRef);
-           }
-       }
+        private int id;
+        private int order;
+        private ChartDataSource<?> xs;
+        private ChartDataSource<? extends Number> ys;
+
+        protected Serie(int id, int order,
+                        ChartDataSource<?> xs,
+                        ChartDataSource<? extends Number> ys) {
+            super();
+            this.id = id;
+            this.order = order;
+            this.xs = xs;
+            this.ys = ys;
+        }
+
+        /**
+         * Returns data source used for X axis values.
+         * @return data source used for X axis values
+         */
+        public ChartDataSource<?> getXValues() {
+            return xs;
+        }
+
+        /**
+         * Returns data source used for Y axis values.
+         * @return data source used for Y axis values
+         */
+        public ChartDataSource<? extends Number> getYValues() {
+            return ys;
+        }
+
+        protected void addToChart(CTScatterChart ctScatterChart) {
+            CTScatterSer scatterSer = ctScatterChart.addNewSer();
+            scatterSer.addNewIdx().setVal(this.id);
+            scatterSer.addNewOrder().setVal(this.order);
+
+            CTAxDataSource xVal = scatterSer.addNewXVal();
+            XSSFChartUtil.buildAxDataSource(xVal, xs);
+
+            CTNumDataSource yVal = scatterSer.addNewYVal();
+            XSSFChartUtil.buildNumDataSource(yVal, ys);
+        }
     }
 
-    public ScatterChartSerie addSerie(DataMarker xMarker, DataMarker yMarker) {
-       int numOfSeries = series.size();
-       Serie newSerie = new Serie(numOfSeries, numOfSeries);
-       newSerie.setXValues(xMarker);
-       newSerie.setYValues(yMarker);
-       series.add(newSerie);
-       return newSerie;
+    public ScatterChartSerie addSerie(ChartDataSource<?> xs,
+                                      ChartDataSource<? extends Number> ys) {
+        if (!ys.isNumeric()) {
+            throw new IllegalArgumentException("Y axis data source must be numeric.");
+        }
+        int numOfSeries = series.size();
+        Serie newSerie = new Serie(numOfSeries, numOfSeries, xs, ys);
+        series.add(newSerie);
+        return newSerie;
     }
 
     public void fillChart(Chart chart, ChartAxis... axis) {
-       if (!(chart instanceof XSSFChart)) {
-           throw new IllegalArgumentException("Chart must be instance of XSSFChart");
-       }
-
-       XSSFChart xssfChart = (XSSFChart) chart;
-       CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea();
-       CTScatterChart scatterChart = plotArea.addNewScatterChart();
-       addStyle(scatterChart);
-
-       for (Serie s : series) {
-           s.addToChart(scatterChart);
-       }
-
-       for (ChartAxis ax : axis) {
-           scatterChart.addNewAxId().setVal(ax.getId());
-       }
+        if (!(chart instanceof XSSFChart)) {
+            throw new IllegalArgumentException("Chart must be instance of XSSFChart");
+        }
+
+        XSSFChart xssfChart = (XSSFChart) chart;
+        CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea();
+        CTScatterChart scatterChart = plotArea.addNewScatterChart();
+        addStyle(scatterChart);
+
+        for (Serie s : series) {
+            s.addToChart(scatterChart);
+        }
+
+        for (ChartAxis ax : axis) {
+            scatterChart.addNewAxId().setVal(ax.getId());
+        }
     }
 
     public List<? extends Serie> getSeries() {
-       return series;
+        return series;
     }
 
     private void addStyle(CTScatterChart ctScatterChart) {
-       CTScatterStyle scatterStyle = ctScatterChart.addNewScatterStyle();
-       scatterStyle.setVal(STScatterStyle.LINE_MARKER);
+        CTScatterStyle scatterStyle = ctScatterChart.addNewScatterStyle();
+        scatterStyle.setVal(STScatterStyle.LINE_MARKER);
     }
 }
index 1646db593c723138e547d43fa707dc46824793a7..3f701f04b93f2cd0a37ac155d095ac3271c344d1 100644 (file)
@@ -24,6 +24,7 @@ import org.apache.poi.ss.usermodel.charts.AxisOrientation;
 import org.apache.poi.ss.usermodel.charts.AxisCrossBetween;
 import org.apache.poi.ss.usermodel.charts.AxisCrosses;
 
+import org.apache.poi.util.Beta;
 import org.apache.poi.xssf.usermodel.XSSFChart;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos;
@@ -39,6 +40,7 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos;
  *
  * @author Roman Kashitsyn
  */
+@Beta
 public class XSSFValueAxis extends XSSFChartAxis implements ValueAxis {
 
        private CTValAx ctValAx;
index a5de464e5f4e642a128d693cbbc45f1c5fc09c41..3ca926394062975c108ef78ca59929b31a60fe6a 100644 (file)
@@ -40,7 +40,7 @@ public final class TestXSSFChartSheet extends TestCase {
         XSSFChartSheet sheet = (XSSFChartSheet)wb.getSheetAt(2);
 
         for(Row row : sheet) {
-            fail("Row iterator for chart sheets should return zero rows");
+            fail("Row iterator for charts sheets should return zero rows");
         }
         //access to a arbitrary row
         assertEquals(null, sheet.getRow(1));
index 526ab9224a3338ac842ff39dd4bb697f69c00a2a..e0cfcc03363ce6e04f102b96275651a2bceb0971 100644 (file)
@@ -332,7 +332,7 @@ public final class TestXSSFWorkbook extends BaseTestWorkbook {
        }
 
        /**
-        * Problems with XSSFWorkbook.removeSheetAt when workbook contains chart
+        * Problems with XSSFWorkbook.removeSheetAt when workbook contains charts
         */
        public void testBug47813() {
                XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47813.xlsx");
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFNumberCache.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/charts/TestXSSFNumberCache.java
deleted file mode 100644 (file)
index 94621de..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-   
-   http://www.apache.org/licenses/LICENSE-2.0
-   
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-   ==================================================================== */
-package org.apache.poi.xssf.usermodel.charts;
-
-import org.apache.poi.ss.usermodel.*;
-import org.apache.poi.ss.util.CellRangeAddress;
-import org.apache.poi.ss.util.DataMarker;
-import org.apache.poi.ss.util.SheetBuilder;
-import org.apache.poi.ss.usermodel.charts.*;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-
-
-import junit.framework.TestCase;
-
-public class TestXSSFNumberCache extends TestCase {
-    private static Object[][] plotData = {
-       {0,      1,       2,       3,       4},
-       {0, "=B1*2", "=C1*2", "=D1*2", "=E1*4"}
-    };
-
-    public void testFormulaCache() {
-       Workbook wb = new XSSFWorkbook();
-       Sheet sheet = new SheetBuilder(wb, plotData).build();
-       Drawing drawing = sheet.createDrawingPatriarch();
-       ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30);
-       Chart chart = drawing.createChart(anchor);
-
-       ChartAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
-       ChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
-
-       ScatterChartData scatterChartData =
-           chart.getChartDataFactory().createScatterChartData();
-
-       DataMarker xMarker = new DataMarker(sheet, CellRangeAddress.valueOf("A1:E1"));
-       DataMarker yMarker = new DataMarker(sheet, CellRangeAddress.valueOf("A2:E2"));
-       ScatterChartSerie serie = scatterChartData.addSerie(xMarker, yMarker);
-
-       chart.plot(scatterChartData, bottomAxis, leftAxis);
-
-       XSSFScatterChartData.Serie xssfScatterSerie =
-           (XSSFScatterChartData.Serie) serie;
-       XSSFNumberCache yCache = xssfScatterSerie.getLastCalculatedYCache();
-
-       assertEquals(5, yCache.getPointCount());
-       assertEquals(4.0, yCache.getValueAt(3), 0.00001);
-       assertEquals(16.0, yCache.getValueAt(5), 0.00001);
-    }
-
-
-}
\ No newline at end of file
index 4a3b9c0f430dc988340f56ad90420662a0f0d999..87f8ea7b12408ec9261943beb6a42df789eb4c37 100644 (file)
@@ -21,42 +21,43 @@ import junit.framework.TestCase;
 
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
-import org.apache.poi.ss.util.DataMarker;
 import org.apache.poi.ss.util.SheetBuilder;
 import org.apache.poi.ss.usermodel.charts.*;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 /**
  * Tests for XSSFScatterChartData.
+ *
  * @author Roman Kashitsyn
  */
-public final class TestXSSFScatterChartData  extends TestCase {
+public final class TestXSSFScatterChartData extends TestCase {
 
-    private static Object[][] plotData = new Object[][] {
-       {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
-       {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
+    private static final Object[][] plotData = {
+            {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"},
+            {  1,    2,   3,    4,    5,   6,    7,   8,    9,  10}
     };
-    
+
     public void testOneSeriePlot() throws Exception {
-       Workbook wb = new XSSFWorkbook();
-       Sheet sheet = new SheetBuilder(wb, plotData).build();
-       Drawing drawing = sheet.createDrawingPatriarch();
-       ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30);
-       Chart chart = drawing.createChart(anchor);
+        Workbook wb = new XSSFWorkbook();
+        Sheet sheet = new SheetBuilder(wb, plotData).build();
+        Drawing drawing = sheet.createDrawingPatriarch();
+        ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30);
+        Chart chart = drawing.createChart(anchor);
 
-       ChartAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
-       ChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
+        ChartAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
+        ChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
 
-       ScatterChartData scatterChartData =
-           chart.getChartDataFactory().createScatterChartData();
+        ScatterChartData scatterChartData =
+                chart.getChartDataFactory().createScatterChartData();
 
-       DataMarker xMarker = new DataMarker(sheet, CellRangeAddress.valueOf("A1:A10"));
-       DataMarker yMarker = new DataMarker(sheet, CellRangeAddress.valueOf("B1:B10"));
-       ScatterChartSerie serie = scatterChartData.addSerie(xMarker, yMarker);
+        ChartDataSource<String> xs = DataSources.fromStringCellRange(sheet, CellRangeAddress.valueOf("A1:J1"));
+        ChartDataSource<Number> ys = DataSources.fromNumericCellRange(sheet, CellRangeAddress.valueOf("A2:J2"));
+        ScatterChartSerie serie = scatterChartData.addSerie(xs, ys);
 
-       assertEquals(1, scatterChartData.getSeries().size());
+        assertNotNull(serie);
+        assertEquals(1, scatterChartData.getSeries().size());
+        assertTrue(scatterChartData.getSeries().contains(serie));
 
-       chart.plot(scatterChartData, bottomAxis, leftAxis);
+        chart.plot(scatterChartData, bottomAxis, leftAxis);
     }
-
 }
diff --git a/src/testcases/org/apache/poi/ss/usermodel/charts/TestDataSources.java b/src/testcases/org/apache/poi/ss/usermodel/charts/TestDataSources.java
new file mode 100644 (file)
index 0000000..6bf3551
--- /dev/null
@@ -0,0 +1,136 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.ss.usermodel.charts;
+
+import junit.framework.TestCase;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.SheetBuilder;
+
+/**
+ * Tests for {@link org.apache.poi.ss.usermodel.charts.DataSources}.
+ *
+ * @author Roman Kashitsyn
+ */
+public class TestDataSources 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};
+        ChartDataSource<Double> doubleDataSource = DataSources.fromArray(doubles);
+        assertTrue(doubleDataSource.isNumeric());
+        assertFalse(doubleDataSource.isReference());
+        assertDataSourceIsEqualToArray(doubleDataSource, doubles);
+    }
+
+    public void testStringArrayDataSource() {
+        String[] strings = new String[]{"one", "two", "three", "four", "five"};
+        ChartDataSource<String> stringDataSource = DataSources.fromArray(strings);
+        assertFalse(stringDataSource.isNumeric());
+        assertFalse(stringDataSource.isReference());
+        assertDataSourceIsEqualToArray(stringDataSource, strings);
+    }
+
+    public void testNumericCellDataSource() {
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = new SheetBuilder(wb, numericCells).build();
+        CellRangeAddress numCellRange = CellRangeAddress.valueOf("A2:E2");
+        ChartDataSource<Number> numDataSource = DataSources.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(((Number) numericCells[0][i]).doubleValue() * 2,
+                    numDataSource.getPointAt(i).doubleValue(), 0.00001);
+        }
+    }
+
+    public void testStringCellDataSource() {
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = new SheetBuilder(wb, stringCells).build();
+        CellRangeAddress numCellRange = CellRangeAddress.valueOf("A2:E2");
+        ChartDataSource<String> numDataSource = DataSources.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() {
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = new SheetBuilder(wb, mixedCells).build();
+        CellRangeAddress mixedCellRange = CellRangeAddress.valueOf("A1:F1");
+        ChartDataSource<String> strDataSource = DataSources.fromStringCellRange(sheet, mixedCellRange);
+        ChartDataSource<Number> numDataSource = DataSources.fromNumericCellRange(sheet, mixedCellRange);
+        for (int i = 0; i < mixedCells[0].length; ++i) {
+            if (i % 2 == 0) {
+                assertNull(strDataSource.getPointAt(i));
+                assertEquals(((Number) mixedCells[0][i]).doubleValue(),
+                        numDataSource.getPointAt(i).doubleValue(), 0.00001);
+            } else {
+                assertNull(numDataSource.getPointAt(i));
+                assertEquals(mixedCells[0][i], strDataSource.getPointAt(i));
+            }
+        }
+    }
+
+    public void testIOBExceptionOnInvalidIndex() {
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = new SheetBuilder(wb, numericCells).build();
+        CellRangeAddress rangeAddress = CellRangeAddress.valueOf("A2:E2");
+        ChartDataSource<Number> numDataSource = DataSources.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 <T> void assertDataSourceIsEqualToArray(ChartDataSource<T> ds, T[] array) {
+        assertEquals(ds.getPointCount(), array.length);
+        for (int i = 0; i < array.length; ++i) {
+            assertEquals(ds.getPointAt(i), array[i]);
+        }
+    }
+}
index edb3df93556b882b1b9059c9475ad241129b4e2e..ee90ee6c5a490a723cd47250c41500a84a2b5e9a 100644 (file)
@@ -29,49 +29,56 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
 /**
  * Tests SheetBuilder.
+ *
  * @see org.apache.poi.ss.util.SheetBuilder
  */
 public final class TestSheetBuilder extends TestCase {
-    
-    private static Object[][] testData = new Object[][] {
-       {         1,     2,        3},
-       {new Date(),  null,     null},
-       {     "one", "two", "=A1+B2"}
+
+    private static Object[][] testData = new Object[][]{
+            {1, 2, 3},
+            {new Date(), null, null},
+            {"one", "two", "=A1+B2"}
     };
 
     public void testNotCreateEmptyCells() {
-       Workbook wb = new HSSFWorkbook();
-       Sheet sheet = new SheetBuilder(wb, testData).build();
-       
-       assertEquals(sheet.getPhysicalNumberOfRows(), 3);
-
-       Row firstRow = sheet.getRow(0);
-       Cell firstCell = firstRow.getCell(0);
-
-       assertEquals(firstCell.getCellType(), Cell.CELL_TYPE_NUMERIC);
-       assertEquals(1.0, firstCell.getNumericCellValue(), 0.00001);
-       
-
-       Row secondRow = sheet.getRow(1);
-       assertNotNull(secondRow.getCell(0));
-       assertNull(secondRow.getCell(2));
-
-       Row thirdRow = sheet.getRow(2);
-       assertEquals(Cell.CELL_TYPE_STRING, thirdRow.getCell(0).getCellType());
-       String cellValue = thirdRow.getCell(0).getStringCellValue();
-       assertEquals(testData[2][0].toString(), cellValue);
-       
-       assertEquals(Cell.CELL_TYPE_FORMULA, thirdRow.getCell(2).getCellType());
-       assertEquals("A1+B2", thirdRow.getCell(2).getCellFormula());
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = new SheetBuilder(wb, testData).build();
+
+        assertEquals(sheet.getPhysicalNumberOfRows(), 3);
+
+        Row firstRow = sheet.getRow(0);
+        Cell firstCell = firstRow.getCell(0);
+
+        assertEquals(firstCell.getCellType(), Cell.CELL_TYPE_NUMERIC);
+        assertEquals(1.0, firstCell.getNumericCellValue(), 0.00001);
+
+
+        Row secondRow = sheet.getRow(1);
+        assertNotNull(secondRow.getCell(0));
+        assertNull(secondRow.getCell(2));
+
+        Row thirdRow = sheet.getRow(2);
+        assertEquals(Cell.CELL_TYPE_STRING, thirdRow.getCell(0).getCellType());
+        String cellValue = thirdRow.getCell(0).getStringCellValue();
+        assertEquals(testData[2][0].toString(), cellValue);
+
+        assertEquals(Cell.CELL_TYPE_FORMULA, thirdRow.getCell(2).getCellType());
+        assertEquals("A1+B2", thirdRow.getCell(2).getCellFormula());
     }
 
     public void testEmptyCells() {
-       Workbook wb = new HSSFWorkbook();
-       Sheet sheet = new SheetBuilder(wb, testData).setCreateEmptyCells(true).build();
-       
-       Cell emptyCell = sheet.getRow(1).getCell(1);
-       assertNotNull(emptyCell);
-       assertEquals(Cell.CELL_TYPE_BLANK, emptyCell.getCellType());
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = new SheetBuilder(wb, testData).setCreateEmptyCells(true).build();
+
+        Cell emptyCell = sheet.getRow(1).getCell(1);
+        assertNotNull(emptyCell);
+        assertEquals(Cell.CELL_TYPE_BLANK, emptyCell.getCellType());
     }
 
+    public void testSheetName() {
+        final String sheetName = "TEST SHEET NAME";
+        Workbook wb = new HSSFWorkbook();
+        Sheet sheet = new SheetBuilder(wb, testData).setSheetName(sheetName).build();
+        assertEquals(sheetName, sheet.getSheetName());
+    }
 }
\ No newline at end of file