| 1 105 106 package org.jfree.data.general; 107 108 import java.util.ArrayList ; 109 import java.util.Iterator ; 110 import java.util.List ; 111 112 import org.jfree.data.DomainInfo; 113 import org.jfree.data.KeyToGroupMap; 114 import org.jfree.data.KeyedValues; 115 import org.jfree.data.Range; 116 import org.jfree.data.RangeInfo; 117 import org.jfree.data.category.CategoryDataset; 118 import org.jfree.data.category.DefaultCategoryDataset; 119 import org.jfree.data.category.IntervalCategoryDataset; 120 import org.jfree.data.function.Function2D; 121 import org.jfree.data.xy.OHLCDataset; 122 import org.jfree.data.xy.IntervalXYDataset; 123 import org.jfree.data.xy.TableXYDataset; 124 import org.jfree.data.xy.XYDataset; 125 import org.jfree.data.xy.XYSeries; 126 import org.jfree.data.xy.XYSeriesCollection; 127 import org.jfree.util.ArrayUtilities; 128 129 132 public final class DatasetUtilities { 133 134 137 private DatasetUtilities() { 138 } 140 141 150 public static double calculatePieDatasetTotal(PieDataset dataset) { 151 if (dataset == null) { 152 throw new IllegalArgumentException ("Null 'dataset' argument."); 153 } 154 List keys = dataset.getKeys(); 155 double totalValue = 0; 156 Iterator iterator = keys.iterator(); 157 while (iterator.hasNext()) { 158 Comparable current = (Comparable ) iterator.next(); 159 if (current != null) { 160 Number value = dataset.getValue(current); 161 double v = 0.0; 162 if (value != null) { 163 v = value.doubleValue(); 164 } 165 if (v > 0) { 166 totalValue = totalValue + v; 167 } 168 } 169 } 170 return totalValue; 171 } 172 173 182 public static PieDataset createPieDatasetForRow(CategoryDataset dataset, 183 Comparable rowKey) { 184 int row = dataset.getRowIndex(rowKey); 185 return createPieDatasetForRow(dataset, row); 186 } 187 188 197 public static PieDataset createPieDatasetForRow(CategoryDataset dataset, 198 int row) { 199 DefaultPieDataset result = new DefaultPieDataset(); 200 int columnCount = dataset.getColumnCount(); 201 for (int current = 0; current < columnCount; current++) { 202 Comparable columnKey = dataset.getColumnKey(current); 203 result.setValue(columnKey, dataset.getValue(row, current)); 204 } 205 return result; 206 } 207 208 217 public static PieDataset createPieDatasetForColumn(CategoryDataset dataset, 218 Comparable columnKey) { 219 int column = dataset.getColumnIndex(columnKey); 220 return createPieDatasetForColumn(dataset, column); 221 } 222 223 232 public static PieDataset createPieDatasetForColumn(CategoryDataset dataset, 233 int column) { 234 DefaultPieDataset result = new DefaultPieDataset(); 235 int rowCount = dataset.getRowCount(); 236 for (int i = 0; i < rowCount; i++) { 237 Comparable rowKey = dataset.getRowKey(i); 238 result.setValue(rowKey, dataset.getValue(i, column)); 239 } 240 return result; 241 } 242 243 256 public static PieDataset createConsolidatedPieDataset(PieDataset source, 257 Comparable key, 258 double minimumPercent) 259 { 260 return DatasetUtilities.createConsolidatedPieDataset( 261 source, key, minimumPercent, 2 262 ); 263 } 264 265 280 public static PieDataset createConsolidatedPieDataset(PieDataset source, 281 Comparable key, 282 double minimumPercent, 283 int minItems) { 284 285 DefaultPieDataset result = new DefaultPieDataset(); 286 double total = DatasetUtilities.calculatePieDatasetTotal(source); 287 288 List keys = source.getKeys(); 290 ArrayList otherKeys = new ArrayList (); 291 Iterator iterator = keys.iterator(); 292 while (iterator.hasNext()) { 293 Comparable currentKey = (Comparable ) iterator.next(); 294 Number dataValue = source.getValue(currentKey); 295 if (dataValue != null) { 296 double value = dataValue.doubleValue(); 297 if (value / total < minimumPercent) { 298 otherKeys.add(currentKey); 299 } 300 } 301 } 302 303 iterator = keys.iterator(); 305 double otherValue = 0; 306 while (iterator.hasNext()) { 307 Comparable currentKey = (Comparable ) iterator.next(); 308 Number dataValue = source.getValue(currentKey); 309 if (dataValue != null) { 310 if (otherKeys.contains(currentKey) 311 && otherKeys.size() >= minItems) { 312 otherValue += dataValue.doubleValue(); 314 } 315 else { 316 result.setValue(currentKey, dataValue); 318 } 319 } 320 } 321 if (otherKeys.size() >= minItems) { 323 result.setValue(key, otherValue); 324 } 325 return result; 326 } 327 328 342 public static CategoryDataset createCategoryDataset(String rowKeyPrefix, 343 String columnKeyPrefix, 344 double[][] data) { 345 346 DefaultCategoryDataset result = new DefaultCategoryDataset(); 347 for (int r = 0; r < data.length; r++) { 348 String rowKey = rowKeyPrefix + (r + 1); 349 for (int c = 0; c < data[r].length; c++) { 350 String columnKey = columnKeyPrefix + (c + 1); 351 result.addValue(new Double (data[r][c]), rowKey, columnKey); 352 } 353 } 354 return result; 355 356 } 357 358 371 public static CategoryDataset createCategoryDataset(String rowKeyPrefix, 372 String columnKeyPrefix, 373 Number [][] data) { 374 375 DefaultCategoryDataset result = new DefaultCategoryDataset(); 376 for (int r = 0; r < data.length; r++) { 377 String rowKey = rowKeyPrefix + (r + 1); 378 for (int c = 0; c < data[r].length; c++) { 379 String columnKey = columnKeyPrefix + (c + 1); 380 result.addValue(data[r][c], rowKey, columnKey); 381 } 382 } 383 return result; 384 385 } 386 387 400 public static CategoryDataset createCategoryDataset(Comparable [] rowKeys, 401 Comparable [] columnKeys, 402 double[][] data) { 403 404 if (rowKeys == null) { 406 throw new IllegalArgumentException ("Null 'rowKeys' argument."); 407 } 408 if (columnKeys == null) { 409 throw new IllegalArgumentException ("Null 'columnKeys' argument."); 410 } 411 if (ArrayUtilities.hasDuplicateItems(rowKeys)) { 412 throw new IllegalArgumentException ("Duplicate items in 'rowKeys'."); 413 } 414 if (ArrayUtilities.hasDuplicateItems(columnKeys)) { 415 throw new IllegalArgumentException ( 416 "Duplicate items in 'columnKeys'." 417 ); 418 } 419 if (rowKeys.length != data.length) { 420 throw new IllegalArgumentException ( 421 "The number of row keys does not match the number of rows in " 422 + "the data array." 423 ); 424 } 425 int columnCount = 0; 426 for (int r = 0; r < data.length; r++) { 427 columnCount = Math.max(columnCount, data[r].length); 428 } 429 if (columnKeys.length != columnCount) { 430 throw new IllegalArgumentException ( 431 "The number of column keys does not match the number of " 432 + "columns in the data array." 433 ); 434 } 435 436 DefaultCategoryDataset result = new DefaultCategoryDataset(); 438 for (int r = 0; r < data.length; r++) { 439 Comparable rowKey = rowKeys[r]; 440 for (int c = 0; c < data[r].length; c++) { 441 Comparable columnKey = columnKeys[c]; 442 result.addValue(new Double (data[r][c]), rowKey, columnKey); 443 } 444 } 445 return result; 446 447 } 448 449 458 public static CategoryDataset createCategoryDataset(Comparable rowKey, 459 KeyedValues rowData) { 460 461 if (rowKey == null) { 462 throw new IllegalArgumentException ("Null 'rowKey' argument."); 463 } 464 if (rowData == null) { 465 throw new IllegalArgumentException ("Null 'rowData' argument."); 466 } 467 DefaultCategoryDataset result = new DefaultCategoryDataset(); 468 for (int i = 0; i < rowData.getItemCount(); i++) { 469 result.addValue(rowData.getValue(i), rowKey, rowData.getKey(i)); 470 } 471 return result; 472 473 } 474 475 488 public static XYDataset sampleFunction2D(Function2D f, 489 double start, 490 double end, 491 int samples, 492 Comparable seriesKey) { 493 494 if (f == null) { 495 throw new IllegalArgumentException ("Null 'f' argument."); 496 } 497 if (seriesKey == null) { 498 throw new IllegalArgumentException ("Null 'seriesKey' argument."); 499 } 500 if (start >= end) { 501 throw new IllegalArgumentException ("Requires 'start' < 'end'."); 502 } 503 if (samples < 2) { 504 throw new IllegalArgumentException ("Requires 'samples' > 1"); 505 } 506 507 XYSeries series = new XYSeries(seriesKey); 508 double step = (end - start) / samples; 509 for (int i = 0; i <= samples; i++) { 510 double x = start + (step * i); 511 series.add(x, f.getValue(x)); 512 } 513 XYSeriesCollection collection = new XYSeriesCollection(series); 514 return collection; 515 516 } 517 518 526 public static boolean isEmptyOrNull(PieDataset dataset) { 527 528 if (dataset == null) { 529 return true; 530 } 531 532 int itemCount = dataset.getItemCount(); 533 if (itemCount == 0) { 534 return true; 535 } 536 537 for (int item = 0; item < itemCount; item++) { 538 Number y = dataset.getValue(item); 539 if (y != null) { 540 double yy = y.doubleValue(); 541 if (yy > 0.0) { 542 return false; 543 } 544 } 545 } 546 547 return true; 548 549 } 550 551 559 public static boolean isEmptyOrNull(CategoryDataset dataset) { 560 561 if (dataset == null) { 562 return true; 563 } 564 565 int rowCount = dataset.getRowCount(); 566 int columnCount = dataset.getColumnCount(); 567 if (rowCount == 0 || columnCount == 0) { 568 return true; 569 } 570 571 for (int r = 0; r < rowCount; r++) { 572 for (int c = 0; c < columnCount; c++) { 573 if (dataset.getValue(r, c) != null) { 574 return false; 575 } 576 577 } 578 } 579 580 return true; 581 582 } 583 584 592 public static boolean isEmptyOrNull(XYDataset dataset) { 593 594 boolean result = true; 595 596 if (dataset != null) { 597 for (int s = 0; s < dataset.getSeriesCount(); s++) { 598 if (dataset.getItemCount(s) > 0) { 599 result = false; 600 continue; 601 } 602 } 603 } 604 605 return result; 606 607 } 608 609 616 public static Range findDomainBounds(XYDataset dataset) { 617 return findDomainBounds(dataset, true); 618 } 619 620 630 public static Range findDomainBounds(XYDataset dataset, 631 boolean includeInterval) { 632 633 if (dataset == null) { 634 throw new IllegalArgumentException ("Null 'dataset' argument."); 635 } 636 637 Range result = null; 638 if (dataset instanceof DomainInfo) { 640 DomainInfo info = (DomainInfo) dataset; 641 result = info.getDomainBounds(includeInterval); 642 } 643 else { 644 result = iterateDomainBounds(dataset, includeInterval); 645 } 646 return result; 647 648 } 649 650 658 public static Range iterateDomainBounds(XYDataset dataset) { 659 return iterateDomainBounds(dataset, true); 660 } 661 662 673 public static Range iterateDomainBounds(XYDataset dataset, 674 boolean includeInterval) { 675 if (dataset == null) { 676 throw new IllegalArgumentException ("Null 'dataset' argument."); 677 } 678 double minimum = Double.POSITIVE_INFINITY; 679 double maximum = Double.NEGATIVE_INFINITY; 680 int seriesCount = dataset.getSeriesCount(); 681 double lvalue; 682 double uvalue; 683 if (includeInterval && dataset instanceof IntervalXYDataset) { 684 IntervalXYDataset intervalXYData = (IntervalXYDataset) dataset; 685 for (int series = 0; series < seriesCount; series++) { 686 int itemCount = dataset.getItemCount(series); 687 for (int item = 0; item < itemCount; item++) { 688 lvalue = intervalXYData.getStartXValue(series, item); 689 uvalue = intervalXYData.getEndXValue(series, item); 690 minimum = Math.min(minimum, lvalue); 691 maximum = Math.max(maximum, uvalue); 692 } 693 } 694 } 695 else { 696 for (int series = 0; series < seriesCount; series++) { 697 int itemCount = dataset.getItemCount(series); 698 for (int item = 0; item < itemCount; item++) { 699 lvalue = dataset.getXValue(series, item); 700 uvalue = lvalue; 701 minimum = Math.min(minimum, lvalue); 702 maximum = Math.max(maximum, uvalue); 703 } 704 } 705 } 706 if (minimum > maximum) { 707 return null; 708 } 709 else { 710 return new Range(minimum, maximum); 711 } 712 } 713 714 722 public static Range findRangeBounds(CategoryDataset dataset) { 723 return findRangeBounds(dataset, true); 724 } 725 726 736 public static Range findRangeBounds(CategoryDataset dataset, 737 boolean includeInterval) { 738 if (dataset == null) { 739 throw new IllegalArgumentException ("Null 'dataset' argument."); 740 } 741 Range result = null; 742 if (dataset instanceof RangeInfo) { 743 RangeInfo info = (RangeInfo) dataset; 744 result = info.getRangeBounds(includeInterval); 745 } 746 else { 747 result = iterateCategoryRangeBounds(dataset, includeInterval); 748 } 749 return result; 750 } 751 752 760 public static Range findRangeBounds(XYDataset dataset) { 761 return findRangeBounds(dataset, true); 762 } 763 764 775 public static Range findRangeBounds(XYDataset dataset, 776 boolean includeInterval) { 777 if (dataset == null) { 778 throw new IllegalArgumentException ("Null 'dataset' argument."); 779 } 780 Range result = null; 781 if (dataset instanceof RangeInfo) { 782 RangeInfo info = (RangeInfo) dataset; 783 result = info.getRangeBounds(includeInterval); 784 } 785 else { 786 result = iterateXYRangeBounds(dataset); 787 } 788 return result; 789 } 790 791 801 public static Range iterateCategoryRangeBounds(CategoryDataset dataset, 802 boolean includeInterval) { 803 double minimum = Double.POSITIVE_INFINITY; 804 double maximum = Double.NEGATIVE_INFINITY; 805 boolean interval = includeInterval 806 && dataset instanceof IntervalCategoryDataset; 807 int rowCount = dataset.getRowCount(); 808 int columnCount = dataset.getColumnCount(); 809 for (int row = 0; row < rowCount; row++) { 810 for (int column = 0; column < columnCount; column++) { 811 Number lvalue; 812 Number uvalue; 813 if (interval) { 814 IntervalCategoryDataset icd 815 &
|