Source Code Cross Referenced for DatasetUtilities.java in  » Chart » jfreechart » org » jfree » data » general » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Chart » jfreechart » org.jfree.data.general 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ===========================================================
0002:         * JFreeChart : a free chart library for the Java(tm) platform
0003:         * ===========================================================
0004:         *
0005:         * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
0006:         *
0007:         * Project Info:  http://www.jfree.org/jfreechart/index.html
0008:         *
0009:         * This library is free software; you can redistribute it and/or modify it 
0010:         * under the terms of the GNU Lesser General Public License as published by 
0011:         * the Free Software Foundation; either version 2.1 of the License, or 
0012:         * (at your option) any later version.
0013:         *
0014:         * This library is distributed in the hope that it will be useful, but 
0015:         * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
0016:         * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
0017:         * License for more details.
0018:         *
0019:         * You should have received a copy of the GNU Lesser General Public
0020:         * License along with this library; if not, write to the Free Software
0021:         * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
0022:         * USA.  
0023:         *
0024:         * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
0025:         * in the United States and other countries.]
0026:         *
0027:         * ---------------------
0028:         * DatasetUtilities.java
0029:         * ---------------------
0030:         * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
0031:         *
0032:         * Original Author:  David Gilbert (for Object Refinery Limited);
0033:         * Contributor(s):   Andrzej Porebski (bug fix);
0034:         *                   Jonathan Nash (bug fix);
0035:         *                   Richard Atkinson;
0036:         *                   Andreas Schroeder;
0037:         *
0038:         * $Id: DatasetUtilities.java,v 1.18.2.8 2007/06/12 14:54:30 mungady Exp $
0039:         *
0040:         * Changes (from 18-Sep-2001)
0041:         * --------------------------
0042:         * 18-Sep-2001 : Added standard header and fixed DOS encoding problem (DG);
0043:         * 22-Oct-2001 : Renamed DataSource.java --> Dataset.java etc. (DG);
0044:         * 15-Nov-2001 : Moved to package com.jrefinery.data.* in the JCommon class 
0045:         *               library (DG);
0046:         *               Changed to handle null values from datasets (DG);
0047:         *               Bug fix (thanks to Andrzej Porebski) - initial value now set 
0048:         *               to positive or negative infinity when iterating (DG);
0049:         * 22-Nov-2001 : Datasets with containing no data now return null for min and 
0050:         *               max calculations (DG);
0051:         * 13-Dec-2001 : Extended to handle HighLowDataset and IntervalXYDataset (DG);
0052:         * 15-Feb-2002 : Added getMinimumStackedRangeValue() and 
0053:         *               getMaximumStackedRangeValue() (DG);
0054:         * 28-Feb-2002 : Renamed Datasets.java --> DatasetUtilities.java (DG);
0055:         * 18-Mar-2002 : Fixed bug in min/max domain calculation for datasets that 
0056:         *               implement the CategoryDataset interface AND the XYDataset 
0057:         *               interface at the same time.  Thanks to Jonathan Nash for the 
0058:         *               fix (DG);
0059:         * 23-Apr-2002 : Added getDomainExtent() and getRangeExtent() methods (DG);
0060:         * 13-Jun-2002 : Modified range measurements to handle 
0061:         *               IntervalCategoryDataset (DG);
0062:         * 12-Jul-2002 : Method name change in DomainInfo interface (DG);
0063:         * 30-Jul-2002 : Added pie dataset summation method (DG);
0064:         * 01-Oct-2002 : Added a method for constructing an XYDataset from a Function2D
0065:         *               instance (DG);
0066:         * 24-Oct-2002 : Amendments required following changes to the CategoryDataset 
0067:         *               interface (DG);
0068:         * 18-Nov-2002 : Changed CategoryDataset to TableDataset (DG);
0069:         * 04-Mar-2003 : Added isEmpty(XYDataset) method (DG);
0070:         * 05-Mar-2003 : Added a method for creating a CategoryDataset from a 
0071:         *               KeyedValues instance (DG);
0072:         * 15-May-2003 : Renamed isEmpty --> isEmptyOrNull (DG);
0073:         * 25-Jun-2003 : Added limitPieDataset methods (RA);
0074:         * 26-Jun-2003 : Modified getDomainExtent() method to accept null datasets (DG);
0075:         * 27-Jul-2003 : Added getStackedRangeExtent(TableXYDataset data) (RA);
0076:         * 18-Aug-2003 : getStackedRangeExtent(TableXYDataset data) now handles null 
0077:         *               values (RA);
0078:         * 02-Sep-2003 : Added method to check for null or empty PieDataset (DG);
0079:         * 18-Sep-2003 : Fix for bug 803660 (getMaximumRangeValue for 
0080:         *               CategoryDataset) (DG);
0081:         * 20-Oct-2003 : Added getCumulativeRangeExtent() method (DG);
0082:         * 09-Jan-2003 : Added argument checking code to the createCategoryDataset() 
0083:         *               method (DG);
0084:         * 23-Mar-2004 : Fixed bug in getMaximumStackedRangeValue() method (DG);
0085:         * 31-Mar-2004 : Exposed the extent iteration algorithms to use one of them and 
0086:         *               applied noninstantiation pattern (AS);
0087:         * 11-May-2004 : Renamed getPieDatasetTotal --> calculatePieDatasetTotal (DG);
0088:         * 15-Jul-2004 : Switched getX() with getXValue() and getY() with getYValue();
0089:         * 24-Aug-2004 : Added argument checks to createCategoryDataset() method (DG);
0090:         * 04-Oct-2004 : Renamed ArrayUtils --> ArrayUtilities (DG);
0091:         * 06-Oct-2004 : Renamed findDomainExtent() --> findDomainBounds(),
0092:         *               findRangeExtent() --> findRangeBounds() (DG);
0093:         * 07-Jan-2005 : Renamed findStackedRangeExtent() --> findStackedRangeBounds(),
0094:         *               findCumulativeRangeExtent() --> findCumulativeRangeBounds(),
0095:         *               iterateXYRangeExtent() --> iterateXYRangeBounds(), 
0096:         *               removed deprecated methods (DG);
0097:         * 03-Feb-2005 : The findStackedRangeBounds() methods now return null for 
0098:         *               empty datasets (DG);
0099:         * 03-Mar-2005 : Moved createNumberArray() and createNumberArray2D() methods
0100:         *               from DatasetUtilities --> DataUtilities (DG);
0101:         * 22-Sep-2005 : Added new findStackedRangeBounds() method that takes base
0102:         *               argument (DG);
0103:         * ------------- JFREECHART 1.0.x ---------------------------------------------
0104:         * 15-Mar-2007 : Added calculateStackTotal() method (DG);
0105:         * 
0106:         */
0107:
0108:        package org.jfree.data.general;
0109:
0110:        import java.util.ArrayList;
0111:        import java.util.Iterator;
0112:        import java.util.List;
0113:
0114:        import org.jfree.data.DomainInfo;
0115:        import org.jfree.data.KeyToGroupMap;
0116:        import org.jfree.data.KeyedValues;
0117:        import org.jfree.data.Range;
0118:        import org.jfree.data.RangeInfo;
0119:        import org.jfree.data.category.CategoryDataset;
0120:        import org.jfree.data.category.DefaultCategoryDataset;
0121:        import org.jfree.data.category.IntervalCategoryDataset;
0122:        import org.jfree.data.function.Function2D;
0123:        import org.jfree.data.xy.IntervalXYDataset;
0124:        import org.jfree.data.xy.OHLCDataset;
0125:        import org.jfree.data.xy.TableXYDataset;
0126:        import org.jfree.data.xy.XYDataset;
0127:        import org.jfree.data.xy.XYSeries;
0128:        import org.jfree.data.xy.XYSeriesCollection;
0129:        import org.jfree.util.ArrayUtilities;
0130:
0131:        /**
0132:         * A collection of useful static methods relating to datasets.
0133:         */
0134:        public final class DatasetUtilities {
0135:
0136:            /**
0137:             * Private constructor for non-instanceability.
0138:             */
0139:            private DatasetUtilities() {
0140:                // now try to instantiate this ;-)
0141:            }
0142:
0143:            /**
0144:             * Calculates the total of all the values in a {@link PieDataset}.  If 
0145:             * the dataset contains negative or <code>null</code> values, they are 
0146:             * ignored. 
0147:             *
0148:             * @param dataset  the dataset (<code>null</code> not permitted).
0149:             *
0150:             * @return The total.
0151:             */
0152:            public static double calculatePieDatasetTotal(PieDataset dataset) {
0153:                if (dataset == null) {
0154:                    throw new IllegalArgumentException(
0155:                            "Null 'dataset' argument.");
0156:                }
0157:                List keys = dataset.getKeys();
0158:                double totalValue = 0;
0159:                Iterator iterator = keys.iterator();
0160:                while (iterator.hasNext()) {
0161:                    Comparable current = (Comparable) iterator.next();
0162:                    if (current != null) {
0163:                        Number value = dataset.getValue(current);
0164:                        double v = 0.0;
0165:                        if (value != null) {
0166:                            v = value.doubleValue();
0167:                        }
0168:                        if (v > 0) {
0169:                            totalValue = totalValue + v;
0170:                        }
0171:                    }
0172:                }
0173:                return totalValue;
0174:            }
0175:
0176:            /**
0177:             * Creates a pie dataset from a table dataset by taking all the values
0178:             * for a single row.
0179:             *
0180:             * @param dataset  the dataset (<code>null</code> not permitted).
0181:             * @param rowKey  the row key.
0182:             *
0183:             * @return A pie dataset.
0184:             */
0185:            public static PieDataset createPieDatasetForRow(
0186:                    CategoryDataset dataset, Comparable rowKey) {
0187:                int row = dataset.getRowIndex(rowKey);
0188:                return createPieDatasetForRow(dataset, row);
0189:            }
0190:
0191:            /**
0192:             * Creates a pie dataset from a table dataset by taking all the values
0193:             * for a single row.
0194:             *
0195:             * @param dataset  the dataset (<code>null</code> not permitted).
0196:             * @param row  the row (zero-based index).
0197:             *
0198:             * @return A pie dataset.
0199:             */
0200:            public static PieDataset createPieDatasetForRow(
0201:                    CategoryDataset dataset, int row) {
0202:                DefaultPieDataset result = new DefaultPieDataset();
0203:                int columnCount = dataset.getColumnCount();
0204:                for (int current = 0; current < columnCount; current++) {
0205:                    Comparable columnKey = dataset.getColumnKey(current);
0206:                    result.setValue(columnKey, dataset.getValue(row, current));
0207:                }
0208:                return result;
0209:            }
0210:
0211:            /**
0212:             * Creates a pie dataset from a table dataset by taking all the values
0213:             * for a single column.
0214:             *
0215:             * @param dataset  the dataset (<code>null</code> not permitted).
0216:             * @param columnKey  the column key.
0217:             *
0218:             * @return A pie dataset.
0219:             */
0220:            public static PieDataset createPieDatasetForColumn(
0221:                    CategoryDataset dataset, Comparable columnKey) {
0222:                int column = dataset.getColumnIndex(columnKey);
0223:                return createPieDatasetForColumn(dataset, column);
0224:            }
0225:
0226:            /**
0227:             * Creates a pie dataset from a {@link CategoryDataset} by taking all the 
0228:             * values for a single column.
0229:             *
0230:             * @param dataset  the dataset (<code>null</code> not permitted).
0231:             * @param column  the column (zero-based index).
0232:             *
0233:             * @return A pie dataset.
0234:             */
0235:            public static PieDataset createPieDatasetForColumn(
0236:                    CategoryDataset dataset, int column) {
0237:                DefaultPieDataset result = new DefaultPieDataset();
0238:                int rowCount = dataset.getRowCount();
0239:                for (int i = 0; i < rowCount; i++) {
0240:                    Comparable rowKey = dataset.getRowKey(i);
0241:                    result.setValue(rowKey, dataset.getValue(i, column));
0242:                }
0243:                return result;
0244:            }
0245:
0246:            /**
0247:             * Creates a new pie dataset based on the supplied dataset, but modified
0248:             * by aggregating all the low value items (those whose value is lower
0249:             * than the <code>percentThreshold</code>) into a single item with the
0250:             * key "Other".
0251:             *
0252:             * @param source  the source dataset (<code>null</code> not permitted).
0253:             * @param key  a new key for the aggregated items (<code>null</code> not
0254:             *             permitted).
0255:             * @param minimumPercent  the percent threshold.
0256:             * 
0257:             * @return The pie dataset with (possibly) aggregated items.
0258:             */
0259:            public static PieDataset createConsolidatedPieDataset(
0260:                    PieDataset source, Comparable key, double minimumPercent) {
0261:                return DatasetUtilities.createConsolidatedPieDataset(source,
0262:                        key, minimumPercent, 2);
0263:            }
0264:
0265:            /**
0266:             * Creates a new pie dataset based on the supplied dataset, but modified 
0267:             * by aggregating all the low value items (those whose value is lower 
0268:             * than the <code>percentThreshold</code>) into a single item.  The 
0269:             * aggregated items are assigned the specified key.  Aggregation only 
0270:             * occurs if there are at least <code>minItems</code> items to aggregate.
0271:             *
0272:             * @param source  the source dataset (<code>null</code> not permitted).
0273:             * @param key  the key to represent the aggregated items.
0274:             * @param minimumPercent  the percent threshold (ten percent is 0.10).
0275:             * @param minItems  only aggregate low values if there are at least this 
0276:             *                  many.
0277:             * 
0278:             * @return The pie dataset with (possibly) aggregated items.
0279:             */
0280:            public static PieDataset createConsolidatedPieDataset(
0281:                    PieDataset source, Comparable key, double minimumPercent,
0282:                    int minItems) {
0283:
0284:                DefaultPieDataset result = new DefaultPieDataset();
0285:                double total = DatasetUtilities
0286:                        .calculatePieDatasetTotal(source);
0287:
0288:                //  Iterate and find all keys below threshold percentThreshold
0289:                List keys = source.getKeys();
0290:                ArrayList otherKeys = new ArrayList();
0291:                Iterator iterator = keys.iterator();
0292:                while (iterator.hasNext()) {
0293:                    Comparable currentKey = (Comparable) iterator.next();
0294:                    Number dataValue = source.getValue(currentKey);
0295:                    if (dataValue != null) {
0296:                        double value = dataValue.doubleValue();
0297:                        if (value / total < minimumPercent) {
0298:                            otherKeys.add(currentKey);
0299:                        }
0300:                    }
0301:                }
0302:
0303:                //  Create new dataset with keys above threshold percentThreshold
0304:                iterator = keys.iterator();
0305:                double otherValue = 0;
0306:                while (iterator.hasNext()) {
0307:                    Comparable currentKey = (Comparable) iterator.next();
0308:                    Number dataValue = source.getValue(currentKey);
0309:                    if (dataValue != null) {
0310:                        if (otherKeys.contains(currentKey)
0311:                                && otherKeys.size() >= minItems) {
0312:                            //  Do not add key to dataset
0313:                            otherValue += dataValue.doubleValue();
0314:                        } else {
0315:                            //  Add key to dataset
0316:                            result.setValue(currentKey, dataValue);
0317:                        }
0318:                    }
0319:                }
0320:                //  Add other category if applicable
0321:                if (otherKeys.size() >= minItems) {
0322:                    result.setValue(key, otherValue);
0323:                }
0324:                return result;
0325:            }
0326:
0327:            /**
0328:             * Creates a {@link CategoryDataset} that contains a copy of the data in an
0329:             * array (instances of <code>Double</code> are created to represent the 
0330:             * data items).
0331:             * <p>
0332:             * Row and column keys are created by appending 0, 1, 2, ... to the 
0333:             * supplied prefixes.
0334:             *
0335:             * @param rowKeyPrefix  the row key prefix.
0336:             * @param columnKeyPrefix  the column key prefix.
0337:             * @param data  the data.
0338:             *
0339:             * @return The dataset.
0340:             */
0341:            public static CategoryDataset createCategoryDataset(
0342:                    String rowKeyPrefix, String columnKeyPrefix, double[][] data) {
0343:
0344:                DefaultCategoryDataset result = new DefaultCategoryDataset();
0345:                for (int r = 0; r < data.length; r++) {
0346:                    String rowKey = rowKeyPrefix + (r + 1);
0347:                    for (int c = 0; c < data[r].length; c++) {
0348:                        String columnKey = columnKeyPrefix + (c + 1);
0349:                        result.addValue(new Double(data[r][c]), rowKey,
0350:                                columnKey);
0351:                    }
0352:                }
0353:                return result;
0354:
0355:            }
0356:
0357:            /**
0358:             * Creates a {@link CategoryDataset} that contains a copy of the data in 
0359:             * an array.
0360:             * <p>
0361:             * Row and column keys are created by appending 0, 1, 2, ... to the 
0362:             * supplied prefixes.
0363:             *
0364:             * @param rowKeyPrefix  the row key prefix.
0365:             * @param columnKeyPrefix  the column key prefix.
0366:             * @param data  the data.
0367:             *
0368:             * @return The dataset.
0369:             */
0370:            public static CategoryDataset createCategoryDataset(
0371:                    String rowKeyPrefix, String columnKeyPrefix, Number[][] data) {
0372:
0373:                DefaultCategoryDataset result = new DefaultCategoryDataset();
0374:                for (int r = 0; r < data.length; r++) {
0375:                    String rowKey = rowKeyPrefix + (r + 1);
0376:                    for (int c = 0; c < data[r].length; c++) {
0377:                        String columnKey = columnKeyPrefix + (c + 1);
0378:                        result.addValue(data[r][c], rowKey, columnKey);
0379:                    }
0380:                }
0381:                return result;
0382:
0383:            }
0384:
0385:            /**
0386:             * Creates a {@link CategoryDataset} that contains a copy of the data in 
0387:             * an array (instances of <code>Double</code> are created to represent the 
0388:             * data items).
0389:             * <p>
0390:             * Row and column keys are taken from the supplied arrays.
0391:             *
0392:             * @param rowKeys  the row keys (<code>null</code> not permitted).
0393:             * @param columnKeys  the column keys (<code>null</code> not permitted).
0394:             * @param data  the data.
0395:             *
0396:             * @return The dataset.
0397:             */
0398:            public static CategoryDataset createCategoryDataset(
0399:                    Comparable[] rowKeys, Comparable[] columnKeys,
0400:                    double[][] data) {
0401:
0402:                // check arguments...
0403:                if (rowKeys == null) {
0404:                    throw new IllegalArgumentException(
0405:                            "Null 'rowKeys' argument.");
0406:                }
0407:                if (columnKeys == null) {
0408:                    throw new IllegalArgumentException(
0409:                            "Null 'columnKeys' argument.");
0410:                }
0411:                if (ArrayUtilities.hasDuplicateItems(rowKeys)) {
0412:                    throw new IllegalArgumentException(
0413:                            "Duplicate items in 'rowKeys'.");
0414:                }
0415:                if (ArrayUtilities.hasDuplicateItems(columnKeys)) {
0416:                    throw new IllegalArgumentException(
0417:                            "Duplicate items in 'columnKeys'.");
0418:                }
0419:                if (rowKeys.length != data.length) {
0420:                    throw new IllegalArgumentException(
0421:                            "The number of row keys does not match the number of rows in "
0422:                                    + "the data array.");
0423:                }
0424:                int columnCount = 0;
0425:                for (int r = 0; r < data.length; r++) {
0426:                    columnCount = Math.max(columnCount, data[r].length);
0427:                }
0428:                if (columnKeys.length != columnCount) {
0429:                    throw new IllegalArgumentException(
0430:                            "The number of column keys does not match the number of "
0431:                                    + "columns in the data array.");
0432:                }
0433:
0434:                // now do the work...
0435:                DefaultCategoryDataset result = new DefaultCategoryDataset();
0436:                for (int r = 0; r < data.length; r++) {
0437:                    Comparable rowKey = rowKeys[r];
0438:                    for (int c = 0; c < data[r].length; c++) {
0439:                        Comparable columnKey = columnKeys[c];
0440:                        result.addValue(new Double(data[r][c]), rowKey,
0441:                                columnKey);
0442:                    }
0443:                }
0444:                return result;
0445:
0446:            }
0447:
0448:            /**
0449:             * Creates a {@link CategoryDataset} by copying the data from the supplied 
0450:             * {@link KeyedValues} instance.
0451:             *
0452:             * @param rowKey  the row key (<code>null</code> not permitted).
0453:             * @param rowData  the row data (<code>null</code> not permitted).
0454:             *
0455:             * @return A dataset.
0456:             */
0457:            public static CategoryDataset createCategoryDataset(
0458:                    Comparable rowKey, KeyedValues rowData) {
0459:
0460:                if (rowKey == null) {
0461:                    throw new IllegalArgumentException(
0462:                            "Null 'rowKey' argument.");
0463:                }
0464:                if (rowData == null) {
0465:                    throw new IllegalArgumentException(
0466:                            "Null 'rowData' argument.");
0467:                }
0468:                DefaultCategoryDataset result = new DefaultCategoryDataset();
0469:                for (int i = 0; i < rowData.getItemCount(); i++) {
0470:                    result.addValue(rowData.getValue(i), rowKey, rowData
0471:                            .getKey(i));
0472:                }
0473:                return result;
0474:
0475:            }
0476:
0477:            /**
0478:             * Creates an {@link XYDataset} by sampling the specified function over a 
0479:             * fixed range.
0480:             *
0481:             * @param f  the function (<code>null</code> not permitted).
0482:             * @param start  the start value for the range.
0483:             * @param end  the end value for the range.
0484:             * @param samples  the number of sample points (must be > 1).
0485:             * @param seriesKey  the key to give the resulting series 
0486:             *                   (<code>null</code> not permitted).
0487:             *
0488:             * @return A dataset.
0489:             */
0490:            public static XYDataset sampleFunction2D(Function2D f,
0491:                    double start, double end, int samples, Comparable seriesKey) {
0492:
0493:                if (f == null) {
0494:                    throw new IllegalArgumentException("Null 'f' argument.");
0495:                }
0496:                if (seriesKey == null) {
0497:                    throw new IllegalArgumentException(
0498:                            "Null 'seriesKey' argument.");
0499:                }
0500:                if (start >= end) {
0501:                    throw new IllegalArgumentException(
0502:                            "Requires 'start' < 'end'.");
0503:                }
0504:                if (samples < 2) {
0505:                    throw new IllegalArgumentException("Requires 'samples' > 1");
0506:                }
0507:
0508:                XYSeries series = new XYSeries(seriesKey);
0509:                double step = (end - start) / samples;
0510:                for (int i = 0; i <= samples; i++) {
0511:                    double x = start + (step * i);
0512:                    series.add(x, f.getValue(x));
0513:                }
0514:                XYSeriesCollection collection = new XYSeriesCollection(series);
0515:                return collection;
0516:
0517:            }
0518:
0519:            /**
0520:             * Returns <code>true</code> if the dataset is empty (or <code>null</code>),
0521:             * and <code>false</code> otherwise.
0522:             *
0523:             * @param dataset  the dataset (<code>null</code> permitted).
0524:             *
0525:             * @return A boolean.
0526:             */
0527:            public static boolean isEmptyOrNull(PieDataset dataset) {
0528:
0529:                if (dataset == null) {
0530:                    return true;
0531:                }
0532:
0533:                int itemCount = dataset.getItemCount();
0534:                if (itemCount == 0) {
0535:                    return true;
0536:                }
0537:
0538:                for (int item = 0; item < itemCount; item++) {
0539:                    Number y = dataset.getValue(item);
0540:                    if (y != null) {
0541:                        double yy = y.doubleValue();
0542:                        if (yy > 0.0) {
0543:                            return false;
0544:                        }
0545:                    }
0546:                }
0547:
0548:                return true;
0549:
0550:            }
0551:
0552:            /**
0553:             * Returns <code>true</code> if the dataset is empty (or <code>null</code>),
0554:             * and <code>false</code> otherwise.
0555:             *
0556:             * @param dataset  the dataset (<code>null</code> permitted).
0557:             *
0558:             * @return A boolean.
0559:             */
0560:            public static boolean isEmptyOrNull(CategoryDataset dataset) {
0561:
0562:                if (dataset == null) {
0563:                    return true;
0564:                }
0565:
0566:                int rowCount = dataset.getRowCount();
0567:                int columnCount = dataset.getColumnCount();
0568:                if (rowCount == 0 || columnCount == 0) {
0569:                    return true;
0570:                }
0571:
0572:                for (int r = 0; r < rowCount; r++) {
0573:                    for (int c = 0; c < columnCount; c++) {
0574:                        if (dataset.getValue(r, c) != null) {
0575:                            return false;
0576:                        }
0577:
0578:                    }
0579:                }
0580:
0581:                return true;
0582:
0583:            }
0584:
0585:            /**
0586:             * Returns <code>true</code> if the dataset is empty (or <code>null</code>),
0587:             * and <code>false</code> otherwise.
0588:             *
0589:             * @param dataset  the dataset (<code>null</code> permitted).
0590:             *
0591:             * @return A boolean.
0592:             */
0593:            public static boolean isEmptyOrNull(XYDataset dataset) {
0594:
0595:                boolean result = true;
0596:
0597:                if (dataset != null) {
0598:                    for (int s = 0; s < dataset.getSeriesCount(); s++) {
0599:                        if (dataset.getItemCount(s) > 0) {
0600:                            result = false;
0601:                            continue;
0602:                        }
0603:                    }
0604:                }
0605:
0606:                return result;
0607:
0608:            }
0609:
0610:            /**
0611:             * Returns the range of values in the domain (x-values) of a dataset.
0612:             *
0613:             * @param dataset  the dataset (<code>null</code> not permitted).
0614:             *
0615:             * @return The range of values (possibly <code>null</code>).
0616:             */
0617:            public static Range findDomainBounds(XYDataset dataset) {
0618:                return findDomainBounds(dataset, true);
0619:            }
0620:
0621:            /**
0622:             * Returns the range of values in the domain (x-values) of a dataset.
0623:             *
0624:             * @param dataset  the dataset (<code>null</code> not permitted).
0625:             * @param includeInterval  determines whether or not the x-interval is taken
0626:             *                         into account (only applies if the dataset is an
0627:             *                         {@link IntervalXYDataset}).
0628:             *
0629:             * @return The range of values (possibly <code>null</code>).
0630:             */
0631:            public static Range findDomainBounds(XYDataset dataset,
0632:                    boolean includeInterval) {
0633:
0634:                if (dataset == null) {
0635:                    throw new IllegalArgumentException(
0636:                            "Null 'dataset' argument.");
0637:                }
0638:
0639:                Range result = null;
0640:                // if the dataset implements DomainInfo, life is easier
0641:                if (dataset instanceof  DomainInfo) {
0642:                    DomainInfo info = (DomainInfo) dataset;
0643:                    result = info.getDomainBounds(includeInterval);
0644:                } else {
0645:                    result = iterateDomainBounds(dataset, includeInterval);
0646:                }
0647:                return result;
0648:
0649:            }
0650:
0651:            /**
0652:             * Iterates over the items in an {@link XYDataset} to find
0653:             * the range of x-values. 
0654:             *  
0655:             * @param dataset  the dataset (<code>null</code> not permitted).
0656:             * 
0657:             * @return The range (possibly <code>null</code>).
0658:             */
0659:            public static Range iterateDomainBounds(XYDataset dataset) {
0660:                return iterateDomainBounds(dataset, true);
0661:            }
0662:
0663:            /**
0664:             * Iterates over the items in an {@link XYDataset} to find
0665:             * the range of x-values. 
0666:             *  
0667:             * @param dataset  the dataset (<code>null</code> not permitted).
0668:             * @param includeInterval  a flag that determines, for an IntervalXYDataset,
0669:             *                         whether the x-interval or just the x-value is 
0670:             *                         used to determine the overall range.
0671:             *   
0672:             * @return The range (possibly <code>null</code>).
0673:             */
0674:            public static Range iterateDomainBounds(XYDataset dataset,
0675:                    boolean includeInterval) {
0676:                if (dataset == null) {
0677:                    throw new IllegalArgumentException(
0678:                            "Null 'dataset' argument.");
0679:                }
0680:                double minimum = Double.POSITIVE_INFINITY;
0681:                double maximum = Double.NEGATIVE_INFINITY;
0682:                int seriesCount = dataset.getSeriesCount();
0683:                double lvalue;
0684:                double uvalue;
0685:                if (includeInterval && dataset instanceof  IntervalXYDataset) {
0686:                    IntervalXYDataset intervalXYData = (IntervalXYDataset) dataset;
0687:                    for (int series = 0; series < seriesCount; series++) {
0688:                        int itemCount = dataset.getItemCount(series);
0689:                        for (int item = 0; item < itemCount; item++) {
0690:                            lvalue = intervalXYData
0691:                                    .getStartXValue(series, item);
0692:                            uvalue = intervalXYData.getEndXValue(series, item);
0693:                            minimum = Math.min(minimum, lvalue);
0694:                            maximum = Math.max(maximum, uvalue);
0695:                        }
0696:                    }
0697:                } else {
0698:                    for (int series = 0; series < seriesCount; series++) {
0699:                        int itemCount = dataset.getItemCount(series);
0700:                        for (int item = 0; item < itemCount; item++) {
0701:                            lvalue = dataset.getXValue(series, item);
0702:                            uvalue = lvalue;
0703:                            minimum = Math.min(minimum, lvalue);
0704:                            maximum = Math.max(maximum, uvalue);
0705:                        }
0706:                    }
0707:                }
0708:                if (minimum > maximum) {
0709:                    return null;
0710:                } else {
0711:                    return new Range(minimum, maximum);
0712:                }
0713:            }
0714:
0715:            /**
0716:             * Returns the range of values in the range for the dataset.
0717:             *
0718:             * @param dataset  the dataset (<code>null</code> not permitted).
0719:             *
0720:             * @return The range (possibly <code>null</code>).
0721:             */
0722:            public static Range findRangeBounds(CategoryDataset dataset) {
0723:                return findRangeBounds(dataset, true);
0724:            }
0725:
0726:            /**
0727:             * Returns the range of values in the range for the dataset.
0728:             *
0729:             * @param dataset  the dataset (<code>null</code> not permitted).
0730:             * @param includeInterval  a flag that determines whether or not the
0731:             *                         y-interval is taken into account.
0732:             * 
0733:             * @return The range (possibly <code>null</code>).
0734:             */
0735:            public static Range findRangeBounds(CategoryDataset dataset,
0736:                    boolean includeInterval) {
0737:                if (dataset == null) {
0738:                    throw new IllegalArgumentException(
0739:                            "Null 'dataset' argument.");
0740:                }
0741:                Range result = null;
0742:                if (dataset instanceof  RangeInfo) {
0743:                    RangeInfo info = (RangeInfo) dataset;
0744:                    result = info.getRangeBounds(includeInterval);
0745:                } else {
0746:                    result = iterateCategoryRangeBounds(dataset,
0747:                            includeInterval);
0748:                }
0749:                return result;
0750:            }
0751:
0752:            /**
0753:             * Returns the range of values in the range for the dataset.  This method
0754:             * is the partner for the {@link #findDomainBounds(XYDataset)} method.
0755:             *
0756:             * @param dataset  the dataset (<code>null</code> not permitted).
0757:             *
0758:             * @return The range (possibly <code>null</code>).
0759:             */
0760:            public static Range findRangeBounds(XYDataset dataset) {
0761:                return findRangeBounds(dataset, true);
0762:            }
0763:
0764:            /**
0765:             * Returns the range of values in the range for the dataset.  This method
0766:             * is the partner for the {@link #findDomainBounds(XYDataset)} method.
0767:             *
0768:             * @param dataset  the dataset (<code>null</code> not permitted).
0769:             * @param includeInterval  a flag that determines whether or not the
0770:             *                         y-interval is taken into account.
0771:             * 
0772:             *
0773:             * @return The range (possibly <code>null</code>).
0774:             */
0775:            public static Range findRangeBounds(XYDataset dataset,
0776:                    boolean includeInterval) {
0777:                if (dataset == null) {
0778:                    throw new IllegalArgumentException(
0779:                            "Null 'dataset' argument.");
0780:                }
0781:                Range result = null;
0782:                if (dataset instanceof  RangeInfo) {
0783:                    RangeInfo info = (RangeInfo) dataset;
0784:                    result = info.getRangeBounds(includeInterval);
0785:                } else {
0786:                    result = iterateXYRangeBounds(dataset);
0787:                }
0788:                return result;
0789:            }
0790:
0791:            /**
0792:             * Iterates over the data item of the category dataset to find
0793:             * the range bounds.
0794:             * 
0795:             * @param dataset  the dataset (<code>null</code> not permitted).
0796:             * @param includeInterval  a flag that determines whether or not the
0797:             *                         y-interval is taken into account.
0798:             * 
0799:             * @return The range (possibly <code>null</code>).
0800:             */
0801:            public static Range iterateCategoryRangeBounds(
0802:                    CategoryDataset dataset, boolean includeInterval) {
0803:                double minimum = Double.POSITIVE_INFINITY;
0804:                double maximum = Double.NEGATIVE_INFINITY;
0805:                boolean interval = includeInterval
0806:                        && dataset instanceof  IntervalCategoryDataset;
0807:                int rowCount = dataset.getRowCount();
0808:                int columnCount = dataset.getColumnCount();
0809:                for (int row = 0; row < rowCount; row++) {
0810:                    for (int column = 0; column < columnCount; column++) {
0811:                        Number lvalue;
0812:                        Number uvalue;
0813:                        if (interval) {
0814:                            IntervalCategoryDataset icd = (IntervalCategoryDataset) dataset;
0815:                            lvalue = icd.getStartValue(row, column);
0816:                            uvalue = icd.getEndValue(row, column);
0817:                        } else {
0818:                            lvalue = dataset.getValue(row, column);
0819:                            uvalue = lvalue;
0820:                        }
0821:                        if (lvalue != null) {
0822:                            minimum = Math.min(minimum, lvalue.doubleValue());
0823:                        }
0824:                        if (uvalue != null) {
0825:                            maximum = Math.max(maximum, uvalue.doubleValue());
0826:                        }
0827:                    }
0828:                }
0829:                if (minimum == Double.POSITIVE_INFINITY) {
0830:                    return null;
0831:                } else {
0832:                    return new Range(minimum, maximum);
0833:                }
0834:            }
0835:
0836:            /**
0837:             * Iterates over the data item of the xy dataset to find
0838:             * the range bounds.
0839:             * 
0840:             * @param dataset  the dataset (<code>null</code> not permitted).
0841:             * 
0842:             * @return The range (possibly <code>null</code>).
0843:             */
0844:            public static Range iterateXYRangeBounds(XYDataset dataset) {
0845:                double minimum = Double.POSITIVE_INFINITY;
0846:                double maximum = Double.NEGATIVE_INFINITY;
0847:                int seriesCount = dataset.getSeriesCount();
0848:                for (int series = 0; series < seriesCount; series++) {
0849:                    int itemCount = dataset.getItemCount(series);
0850:                    for (int item = 0; item < itemCount; item++) {
0851:                        double lvalue;
0852:                        double uvalue;
0853:                        if (dataset instanceof  IntervalXYDataset) {
0854:                            IntervalXYDataset intervalXYData = (IntervalXYDataset) dataset;
0855:                            lvalue = intervalXYData
0856:                                    .getStartYValue(series, item);
0857:                            uvalue = intervalXYData.getEndYValue(series, item);
0858:                        } else if (dataset instanceof  OHLCDataset) {
0859:                            OHLCDataset highLowData = (OHLCDataset) dataset;
0860:                            lvalue = highLowData.getLowValue(series, item);
0861:                            uvalue = highLowData.getHighValue(series, item);
0862:                        } else {
0863:                            lvalue = dataset.getYValue(series, item);
0864:                            uvalue = lvalue;
0865:                        }
0866:                        if (!Double.isNaN(lvalue)) {
0867:                            minimum = Math.min(minimum, lvalue);
0868:                        }
0869:                        if (!Double.isNaN(uvalue)) {
0870:                            maximum = Math.max(maximum, uvalue);
0871:                        }
0872:                    }
0873:                }
0874:                if (minimum == Double.POSITIVE_INFINITY) {
0875:                    return null;
0876:                } else {
0877:                    return new Range(minimum, maximum);
0878:                }
0879:            }
0880:
0881:            /**
0882:             * Finds the minimum domain (or X) value for the specified dataset.  This 
0883:             * is easy if the dataset implements the {@link DomainInfo} interface (a 
0884:             * good idea if there is an efficient way to determine the minimum value).
0885:             * Otherwise, it involves iterating over the entire data-set.
0886:             * <p>
0887:             * Returns <code>null</code> if all the data values in the dataset are 
0888:             * <code>null</code>.
0889:             *
0890:             * @param dataset  the dataset (<code>null</code> not permitted).
0891:             *
0892:             * @return The minimum value (possibly <code>null</code>).
0893:             */
0894:            public static Number findMinimumDomainValue(XYDataset dataset) {
0895:                if (dataset == null) {
0896:                    throw new IllegalArgumentException(
0897:                            "Null 'dataset' argument.");
0898:                }
0899:                Number result = null;
0900:                // if the dataset implements DomainInfo, life is easy
0901:                if (dataset instanceof  DomainInfo) {
0902:                    DomainInfo info = (DomainInfo) dataset;
0903:                    return new Double(info.getDomainLowerBound(true));
0904:                } else {
0905:                    double minimum = Double.POSITIVE_INFINITY;
0906:                    int seriesCount = dataset.getSeriesCount();
0907:                    for (int series = 0; series < seriesCount; series++) {
0908:                        int itemCount = dataset.getItemCount(series);
0909:                        for (int item = 0; item < itemCount; item++) {
0910:
0911:                            double value;
0912:                            if (dataset instanceof  IntervalXYDataset) {
0913:                                IntervalXYDataset intervalXYData = (IntervalXYDataset) dataset;
0914:                                value = intervalXYData.getStartXValue(series,
0915:                                        item);
0916:                            } else {
0917:                                value = dataset.getXValue(series, item);
0918:                            }
0919:                            if (!Double.isNaN(value)) {
0920:                                minimum = Math.min(minimum, value);
0921:                            }
0922:
0923:                        }
0924:                    }
0925:                    if (minimum == Double.POSITIVE_INFINITY) {
0926:                        result = null;
0927:                    } else {
0928:                        result = new Double(minimum);
0929:                    }
0930:                }
0931:
0932:                return result;
0933:            }
0934:
0935:            /**
0936:             * Returns the maximum domain value for the specified dataset.  This is 
0937:             * easy if the dataset implements the {@link DomainInfo} interface (a good 
0938:             * idea if there is an efficient way to determine the maximum value).  
0939:             * Otherwise, it involves iterating over the entire data-set.  Returns 
0940:             * <code>null</code> if all the data values in the dataset are 
0941:             * <code>null</code>.
0942:             *
0943:             * @param dataset  the dataset (<code>null</code> not permitted).
0944:             *
0945:             * @return The maximum value (possibly <code>null</code>).
0946:             */
0947:            public static Number findMaximumDomainValue(XYDataset dataset) {
0948:                if (dataset == null) {
0949:                    throw new IllegalArgumentException(
0950:                            "Null 'dataset' argument.");
0951:                }
0952:                Number result = null;
0953:                // if the dataset implements DomainInfo, life is easy
0954:                if (dataset instanceof  DomainInfo) {
0955:                    DomainInfo info = (DomainInfo) dataset;
0956:                    return new Double(info.getDomainUpperBound(true));
0957:                }
0958:
0959:                // hasn't implemented DomainInfo, so iterate...
0960:                else {
0961:                    double maximum = Double.NEGATIVE_INFINITY;
0962:                    int seriesCount = dataset.getSeriesCount();
0963:                    for (int series = 0; series < seriesCount; series++) {
0964:                        int itemCount = dataset.getItemCount(series);
0965:                        for (int item = 0; item < itemCount; item++) {
0966:
0967:                            double value;
0968:                            if (dataset instanceof  IntervalXYDataset) {
0969:                                IntervalXYDataset intervalXYData = (IntervalXYDataset) dataset;
0970:                                value = intervalXYData.getEndXValue(series,
0971:                                        item);
0972:                            } else {
0973:                                value = dataset.getXValue(series, item);
0974:                            }
0975:                            if (!Double.isNaN(value)) {
0976:                                maximum = Math.max(maximum, value);
0977:                            }
0978:                        }
0979:                    }
0980:                    if (maximum == Double.NEGATIVE_INFINITY) {
0981:                        result = null;
0982:                    } else {
0983:                        result = new Double(maximum);
0984:                    }
0985:
0986:                }
0987:
0988:                return result;
0989:            }
0990:
0991:            /**
0992:             * Returns the minimum range value for the specified dataset.  This is 
0993:             * easy if the dataset implements the {@link RangeInfo} interface (a good
0994:             * idea if there is an efficient way to determine the minimum value).  
0995:             * Otherwise, it involves iterating over the entire data-set.  Returns 
0996:             * <code>null</code> if all the data values in the dataset are 
0997:             * <code>null</code>.
0998:             *
0999:             * @param dataset  the dataset (<code>null</code> not permitted).
1000:             *
1001:             * @return The minimum value (possibly <code>null</code>).
1002:             */
1003:            public static Number findMinimumRangeValue(CategoryDataset dataset) {
1004:
1005:                // check parameters...
1006:                if (dataset == null) {
1007:                    throw new IllegalArgumentException(
1008:                            "Null 'dataset' argument.");
1009:                }
1010:
1011:                // work out the minimum value...
1012:                if (dataset instanceof  RangeInfo) {
1013:                    RangeInfo info = (RangeInfo) dataset;
1014:                    return new Double(info.getRangeLowerBound(true));
1015:                }
1016:
1017:                // hasn't implemented RangeInfo, so we'll have to iterate...
1018:                else {
1019:                    double minimum = Double.POSITIVE_INFINITY;
1020:                    int seriesCount = dataset.getRowCount();
1021:                    int itemCount = dataset.getColumnCount();
1022:                    for (int series = 0; series < seriesCount; series++) {
1023:                        for (int item = 0; item < itemCount; item++) {
1024:                            Number value;
1025:                            if (dataset instanceof  IntervalCategoryDataset) {
1026:                                IntervalCategoryDataset icd = (IntervalCategoryDataset) dataset;
1027:                                value = icd.getStartValue(series, item);
1028:                            } else {
1029:                                value = dataset.getValue(series, item);
1030:                            }
1031:                            if (value != null) {
1032:                                minimum = Math
1033:                                        .min(minimum, value.doubleValue());
1034:                            }
1035:                        }
1036:                    }
1037:                    if (minimum == Double.POSITIVE_INFINITY) {
1038:                        return null;
1039:                    } else {
1040:                        return new Double(minimum);
1041:                    }
1042:
1043:                }
1044:
1045:            }
1046:
1047:            /**
1048:             * Returns the minimum range value for the specified dataset.  This is 
1049:             * easy if the dataset implements the {@link RangeInfo} interface (a good
1050:             * idea if there is an efficient way to determine the minimum value).  
1051:             * Otherwise, it involves iterating over the entire data-set.  Returns 
1052:             * <code>null</code> if all the data values in the dataset are 
1053:             * <code>null</code>.
1054:             *
1055:             * @param dataset  the dataset (<code>null</code> not permitted).
1056:             *
1057:             * @return The minimum value (possibly <code>null</code>).
1058:             */
1059:            public static Number findMinimumRangeValue(XYDataset dataset) {
1060:
1061:                if (dataset == null) {
1062:                    throw new IllegalArgumentException(
1063:                            "Null 'dataset' argument.");
1064:                }
1065:
1066:                // work out the minimum value...
1067:                if (dataset instanceof  RangeInfo) {
1068:                    RangeInfo info = (RangeInfo) dataset;
1069:                    return new Double(info.getRangeLowerBound(true));
1070:                }
1071:
1072:                // hasn't implemented RangeInfo, so we'll have to iterate...
1073:                else {
1074:                    double minimum = Double.POSITIVE_INFINITY;
1075:                    int seriesCount = dataset.getSeriesCount();
1076:                    for (int series = 0; series < seriesCount; series++) {
1077:                        int itemCount = dataset.getItemCount(series);
1078:                        for (int item = 0; item < itemCount; item++) {
1079:
1080:                            double value;
1081:                            if (dataset instanceof  IntervalXYDataset) {
1082:                                IntervalXYDataset intervalXYData = (IntervalXYDataset) dataset;
1083:                                value = intervalXYData.getStartYValue(series,
1084:                                        item);
1085:                            } else if (dataset instanceof  OHLCDataset) {
1086:                                OHLCDataset highLowData = (OHLCDataset) dataset;
1087:                                value = highLowData.getLowValue(series, item);
1088:                            } else {
1089:                                value = dataset.getYValue(series, item);
1090:                            }
1091:                            if (!Double.isNaN(value)) {
1092:                                minimum = Math.min(minimum, value);
1093:                            }
1094:
1095:                        }
1096:                    }
1097:                    if (minimum == Double.POSITIVE_INFINITY) {
1098:                        return null;
1099:                    } else {
1100:                        return new Double(minimum);
1101:                    }
1102:
1103:                }
1104:
1105:            }
1106:
1107:            /**
1108:             * Returns the maximum range value for the specified dataset.  This is easy
1109:             * if the dataset implements the {@link RangeInfo} interface (a good idea 
1110:             * if there is an efficient way to determine the maximum value).  
1111:             * Otherwise, it involves iterating over the entire data-set.  Returns 
1112:             * <code>null</code> if all the data values are <code>null</code>.
1113:             *
1114:             * @param dataset  the dataset (<code>null</code> not permitted).
1115:             *
1116:             * @return The maximum value (possibly <code>null</code>).
1117:             */
1118:            public static Number findMaximumRangeValue(CategoryDataset dataset) {
1119:
1120:                if (dataset == null) {
1121:                    throw new IllegalArgumentException(
1122:                            "Null 'dataset' argument.");
1123:                }
1124:
1125:                // work out the minimum value...
1126:                if (dataset instanceof  RangeInfo) {
1127:                    RangeInfo info = (RangeInfo) dataset;
1128:                    return new Double(info.getRangeUpperBound(true));
1129:                }
1130:
1131:                // hasn't implemented RangeInfo, so we'll have to iterate...
1132:                else {
1133:
1134:                    double maximum = Double.NEGATIVE_INFINITY;
1135:                    int seriesCount = dataset.getRowCount();
1136:                    int itemCount = dataset.getColumnCount();
1137:                    for (int series = 0; series < seriesCount; series++) {
1138:                        for (int item = 0; item < itemCount; item++) {
1139:                            Number value;
1140:                            if (dataset instanceof  IntervalCategoryDataset) {
1141:                                IntervalCategoryDataset icd = (IntervalCategoryDataset) dataset;
1142:                                value = icd.getEndValue(series, item);
1143:                            } else {
1144:                                value = dataset.getValue(series, item);
1145:                            }
1146:                            if (value != null) {
1147:                                maximum = Math
1148:                                        .max(maximum, value.doubleValue());
1149:                            }
1150:                        }
1151:                    }
1152:                    if (maximum == Double.NEGATIVE_INFINITY) {
1153:                        return null;
1154:                    } else {
1155:                        return new Double(maximum);
1156:                    }
1157:
1158:                }
1159:
1160:            }
1161:
1162:            /**
1163:             * Returns the maximum range value for the specified dataset.  This is 
1164:             * easy if the dataset implements the {@link RangeInfo} interface (a good 
1165:             * idea if there is an efficient way to determine the maximum value).  
1166:             * Otherwise, it involves iterating over the entire data-set.  Returns 
1167:             * <code>null</code> if all the data values are <code>null</code>.
1168:             *
1169:             * @param dataset  the dataset (<code>null</code> not permitted).
1170:             *
1171:             * @return The maximum value (possibly <code>null</code>).
1172:             */
1173:            public static Number findMaximumRangeValue(XYDataset dataset) {
1174:
1175:                if (dataset == null) {
1176:                    throw new IllegalArgumentException(
1177:                            "Null 'dataset' argument.");
1178:                }
1179:
1180:                // work out the minimum value...
1181:                if (dataset instanceof  RangeInfo) {
1182:                    RangeInfo info = (RangeInfo) dataset;
1183:                    return new Double(info.getRangeUpperBound(true));
1184:                }
1185:
1186:                // hasn't implemented RangeInfo, so we'll have to iterate...
1187:                else {
1188:
1189:                    double maximum = Double.NEGATIVE_INFINITY;
1190:                    int seriesCount = dataset.getSeriesCount();
1191:                    for (int series = 0; series < seriesCount; series++) {
1192:                        int itemCount = dataset.getItemCount(series);
1193:                        for (int item = 0; item < itemCount; item++) {
1194:                            double value;
1195:                            if (dataset instanceof  IntervalXYDataset) {
1196:                                IntervalXYDataset intervalXYData = (IntervalXYDataset) dataset;
1197:                                value = intervalXYData.getEndYValue(series,
1198:                                        item);
1199:                            } else if (dataset instanceof  OHLCDataset) {
1200:                                OHLCDataset highLowData = (OHLCDataset) dataset;
1201:                                value = highLowData.getHighValue(series, item);
1202:                            } else {
1203:                                value = dataset.getYValue(series, item);
1204:                            }
1205:                            if (!Double.isNaN(value)) {
1206:                                maximum = Math.max(maximum, value);
1207:                            }
1208:                        }
1209:                    }
1210:                    if (maximum == Double.NEGATIVE_INFINITY) {
1211:                        return null;
1212:                    } else {
1213:                        return new Double(maximum);
1214:                    }
1215:
1216:                }
1217:
1218:            }
1219:
1220:            /**
1221:             * Returns the minimum and maximum values for the dataset's range 
1222:             * (y-values), assuming that the series in one category are stacked.
1223:             *
1224:             * @param dataset  the dataset (<code>null</code> not permitted).
1225:             *
1226:             * @return The range (<code>null</code> if the dataset contains no values).
1227:             */
1228:            public static Range findStackedRangeBounds(CategoryDataset dataset) {
1229:                return findStackedRangeBounds(dataset, 0.0);
1230:            }
1231:
1232:            /**
1233:             * Returns the minimum and maximum values for the dataset's range 
1234:             * (y-values), assuming that the series in one category are stacked.
1235:             *
1236:             * @param dataset  the dataset (<code>null</code> not permitted).
1237:             * @param base  the base value for the bars.
1238:             *
1239:             * @return The range (<code>null</code> if the dataset contains no values).
1240:             */
1241:            public static Range findStackedRangeBounds(CategoryDataset dataset,
1242:                    double base) {
1243:                if (dataset == null) {
1244:                    throw new IllegalArgumentException(
1245:                            "Null 'dataset' argument.");
1246:                }
1247:                Range result = null;
1248:                double minimum = Double.POSITIVE_INFINITY;
1249:                double maximum = Double.NEGATIVE_INFINITY;
1250:                int categoryCount = dataset.getColumnCount();
1251:                for (int item = 0; item < categoryCount; item++) {
1252:                    double positive = base;
1253:                    double negative = base;
1254:                    int seriesCount = dataset.getRowCount();
1255:                    for (int series = 0; series < seriesCount; series++) {
1256:                        Number number = dataset.getValue(series, item);
1257:                        if (number != null) {
1258:                            double value = number.doubleValue();
1259:                            if (value > 0.0) {
1260:                                positive = positive + value;
1261:                            }
1262:                            if (value < 0.0) {
1263:                                negative = negative + value;
1264:                                // '+', remember value is negative
1265:                            }
1266:                        }
1267:                    }
1268:                    minimum = Math.min(minimum, negative);
1269:                    maximum = Math.max(maximum, positive);
1270:                }
1271:                if (minimum <= maximum) {
1272:                    result = new Range(minimum, maximum);
1273:                }
1274:                return result;
1275:
1276:            }
1277:
1278:            /**
1279:             * Returns the minimum and maximum values for the dataset's range 
1280:             * (y-values), assuming that the series in one category are stacked.
1281:             *
1282:             * @param dataset  the dataset.
1283:             * @param map  a structure that maps series to groups.
1284:             *
1285:             * @return The value range (<code>null</code> if the dataset contains no 
1286:             *         values).
1287:             */
1288:            public static Range findStackedRangeBounds(CategoryDataset dataset,
1289:                    KeyToGroupMap map) {
1290:
1291:                Range result = null;
1292:                if (dataset != null) {
1293:
1294:                    // create an array holding the group indices...
1295:                    int[] groupIndex = new int[dataset.getRowCount()];
1296:                    for (int i = 0; i < dataset.getRowCount(); i++) {
1297:                        groupIndex[i] = map.getGroupIndex(map.getGroup(dataset
1298:                                .getRowKey(i)));
1299:                    }
1300:
1301:                    // minimum and maximum for each group...
1302:                    int groupCount = map.getGroupCount();
1303:                    double[] minimum = new double[groupCount];
1304:                    double[] maximum = new double[groupCount];
1305:
1306:                    int categoryCount = dataset.getColumnCount();
1307:                    for (int item = 0; item < categoryCount; item++) {
1308:                        double[] positive = new double[groupCount];
1309:                        double[] negative = new double[groupCount];
1310:                        int seriesCount = dataset.getRowCount();
1311:                        for (int series = 0; series < seriesCount; series++) {
1312:                            Number number = dataset.getValue(series, item);
1313:                            if (number != null) {
1314:                                double value = number.doubleValue();
1315:                                if (value > 0.0) {
1316:                                    positive[groupIndex[series]] = positive[groupIndex[series]]
1317:                                            + value;
1318:                                }
1319:                                if (value < 0.0) {
1320:                                    negative[groupIndex[series]] = negative[groupIndex[series]]
1321:                                            + value;
1322:                                    // '+', remember value is negative
1323:                                }
1324:                            }
1325:                        }
1326:                        for (int g = 0; g < groupCount; g++) {
1327:                            minimum[g] = Math.min(minimum[g], negative[g]);
1328:                            maximum[g] = Math.max(maximum[g], positive[g]);
1329:                        }
1330:                    }
1331:                    for (int j = 0; j < groupCount; j++) {
1332:                        result = Range.combine(result, new Range(minimum[j],
1333:                                maximum[j]));
1334:                    }
1335:                }
1336:                return result;
1337:
1338:            }
1339:
1340:            /**
1341:             * Returns the minimum value in the dataset range, assuming that values in
1342:             * each category are "stacked".
1343:             *
1344:             * @param dataset  the dataset.
1345:             *
1346:             * @return The minimum value.
1347:             */
1348:            public static Number findMinimumStackedRangeValue(
1349:                    CategoryDataset dataset) {
1350:
1351:                Number result = null;
1352:                if (dataset != null) {
1353:                    double minimum = 0.0;
1354:                    int categoryCount = dataset.getRowCount();
1355:                    for (int item = 0; item < categoryCount; item++) {
1356:                        double total = 0.0;
1357:
1358:                        int seriesCount = dataset.getColumnCount();
1359:                        for (int series = 0; series < seriesCount; series++) {
1360:                            Number number = dataset.getValue(series, item);
1361:                            if (number != null) {
1362:                                double value = number.doubleValue();
1363:                                if (value < 0.0) {
1364:                                    total = total + value;
1365:                                    // '+', remember value is negative
1366:                                }
1367:                            }
1368:                        }
1369:                        minimum = Math.min(minimum, total);
1370:
1371:                    }
1372:                    result = new Double(minimum);
1373:                }
1374:                return result;
1375:
1376:            }
1377:
1378:            /**
1379:             * Returns the maximum value in the dataset range, assuming that values in
1380:             * each category are "stacked".
1381:             *
1382:             * @param dataset  the dataset (<code>null</code> permitted).
1383:             *
1384:             * @return The maximum value (possibly <code>null</code>).
1385:             */
1386:            public static Number findMaximumStackedRangeValue(
1387:                    CategoryDataset dataset) {
1388:
1389:                Number result = null;
1390:
1391:                if (dataset != null) {
1392:                    double maximum = 0.0;
1393:                    int categoryCount = dataset.getColumnCount();
1394:                    for (int item = 0; item < categoryCount; item++) {
1395:                        double total = 0.0;
1396:                        int seriesCount = dataset.getRowCount();
1397:                        for (int series = 0; series < seriesCount; series++) {
1398:                            Number number = dataset.getValue(series, item);
1399:                            if (number != null) {
1400:                                double value = number.doubleValue();
1401:                                if (value > 0.0) {
1402:                                    total = total + value;
1403:                                }
1404:                            }
1405:                        }
1406:                        maximum = Math.max(maximum, total);
1407:                    }
1408:                    result = new Double(maximum);
1409:                }
1410:
1411:                return result;
1412:
1413:            }
1414:
1415:            /**
1416:             * Returns the minimum and maximum values for the dataset's range,
1417:             * assuming that the series are stacked.
1418:             *
1419:             * @param dataset  the dataset (<code>null</code> not permitted).
1420:             * 
1421:             * @return The range ([0.0, 0.0] if the dataset contains no values).
1422:             */
1423:            public static Range findStackedRangeBounds(TableXYDataset dataset) {
1424:                return findStackedRangeBounds(dataset, 0.0);
1425:            }
1426:
1427:            /**
1428:             * Returns the minimum and maximum values for the dataset's range,
1429:             * assuming that the series are stacked, using the specified base value.
1430:             *
1431:             * @param dataset  the dataset (<code>null</code> not permitted).
1432:             * @param base  the base value.
1433:             * 
1434:             * @return The range (<code>null</code> if the dataset contains no values).
1435:             */
1436:            public static Range findStackedRangeBounds(TableXYDataset dataset,
1437:                    double base) {
1438:                if (dataset == null) {
1439:                    throw new IllegalArgumentException(
1440:                            "Null 'dataset' argument.");
1441:                }
1442:                double minimum = base;
1443:                double maximum = base;
1444:                for (int itemNo = 0; itemNo < dataset.getItemCount(); itemNo++) {
1445:                    double positive = base;
1446:                    double negative = base;
1447:                    int seriesCount = dataset.getSeriesCount();
1448:                    for (int seriesNo = 0; seriesNo < seriesCount; seriesNo++) {
1449:                        double y = dataset.getYValue(seriesNo, itemNo);
1450:                        if (!Double.isNaN(y)) {
1451:                            if (y > 0.0) {
1452:                                positive += y;
1453:                            } else {
1454:                                negative += y;
1455:                            }
1456:                        }
1457:                    }
1458:                    if (positive > maximum) {
1459:                        maximum = positive;
1460:                    }
1461:                    if (negative < minimum) {
1462:                        minimum = negative;
1463:                    }
1464:                }
1465:                if (minimum <= maximum) {
1466:                    return new Range(minimum, maximum);
1467:                } else {
1468:                    return null;
1469:                }
1470:            }
1471:
1472:            /**
1473:             * Calculates the total for the y-values in all series for a given item
1474:             * index.
1475:             * 
1476:             * @param dataset  the dataset.
1477:             * @param item  the item index.
1478:             * 
1479:             * @return The total.
1480:             * 
1481:             * @since 1.0.5
1482:             */
1483:            public static double calculateStackTotal(TableXYDataset dataset,
1484:                    int item) {
1485:                double total = 0.0;
1486:                int seriesCount = dataset.getSeriesCount();
1487:                for (int s = 0; s < seriesCount; s++) {
1488:                    double value = dataset.getYValue(s, item);
1489:                    if (!Double.isNaN(value)) {
1490:                        total = total + value;
1491:                    }
1492:                }
1493:                return total;
1494:            }
1495:
1496:            /**
1497:             * Calculates the range of values for a dataset where each item is the 
1498:             * running total of the items for the current series.
1499:             * 
1500:             * @param dataset  the dataset (<code>null</code> not permitted).
1501:             * 
1502:             * @return The range.
1503:             * 
1504:             * @see #findRangeBounds(CategoryDataset)
1505:             */
1506:            public static Range findCumulativeRangeBounds(
1507:                    CategoryDataset dataset) {
1508:
1509:                if (dataset == null) {
1510:                    throw new IllegalArgumentException(
1511:                            "Null 'dataset' argument.");
1512:                }
1513:
1514:                boolean allItemsNull = true; // we'll set this to false if there is at 
1515:                // least one non-null data item... 
1516:                double minimum = 0.0;
1517:                double maximum = 0.0;
1518:                for (int row = 0; row < dataset.getRowCount(); row++) {
1519:                    double runningTotal = 0.0;
1520:                    for (int column = 0; column < dataset.getColumnCount() - 1; column++) {
1521:                        Number n = dataset.getValue(row, column);
1522:                        if (n != null) {
1523:                            allItemsNull = false;
1524:                            double value = n.doubleValue();
1525:                            runningTotal = runningTotal + value;
1526:                            minimum = Math.min(minimum, runningTotal);
1527:                            maximum = Math.max(maximum, runningTotal);
1528:                        }
1529:                    }
1530:                }
1531:                if (!allItemsNull) {
1532:                    return new Range(minimum, maximum);
1533:                } else {
1534:                    return null;
1535:                }
1536:
1537:            }
1538:
1539:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.