1 22 23 24 package net.sourceforge.chart2d; 25 26 27 import java.awt.*; 28 import java.util.*; 29 import java.text.*; 30 31 32 35 class ChartArea extends TitledArea { 36 37 38 44 static final int MAX_INTEGER = 38; 45 46 47 53 static final int MAX_FLOAT = -38; 54 55 56 61 static final int DEFAULT_FLOAT = -2; 62 63 private Color[] datasetColors; 64 private boolean betweenChartAndLegendGapExistence; 65 private float betweenChartAndLegendGapToWidthRatio; 66 private int betweenChartAndLegendGapThicknessModel; 67 private LegendArea legend; 68 private boolean legendExistence; 69 private float legendToWidthRatio; 70 private float legendToHeightRatio; 71 private int labelsPrecisionNum; 72 73 private boolean autoSetLayoutRatios; 74 private boolean needsUpdate; 75 76 77 80 ChartArea() { 81 82 needsUpdate = true; 83 legend = new LegendArea(); 84 85 setAutoSizes (false, true); 86 setFontPointModel (16); 87 setLabelsPrecisionNum (MAX_INTEGER); 88 setTitleSqueeze (true); 89 setBetweenChartAndLegendGapExistence (true); 90 setBetweenChartAndLegendGapThicknessModel (5); 91 setLegendExistence (true); 92 setLegendToWidthRatio (.25f); 93 setLegendToHeightRatio (1f); 94 setAutoSetLayoutRatios (true); 95 96 setDatasetColors (new Color[0]); 97 98 resetChartAreaModel (true); 99 } 100 101 102 107 final void setBetweenChartAndLegendGapExistence (boolean existence) { 108 needsUpdate = true; 109 betweenChartAndLegendGapExistence = existence; 110 } 111 112 113 118 final void setBetweenChartAndLegendGapThicknessModel (int thickness) { 119 needsUpdate = true; 120 betweenChartAndLegendGapThicknessModel = thickness; 121 } 122 123 124 130 final void setAutoSetLayoutRatios (boolean auto) { 131 132 needsUpdate = true; 133 autoSetLayoutRatios = auto; 134 } 135 136 137 143 final void setTitleSqueeze (boolean squeeze) { 144 145 needsUpdate = true; 146 setTitleAutoLocate (!squeeze); 147 } 148 149 150 154 final void setDatasetColors (Color[] colors) { 155 156 needsUpdate = true; 157 datasetColors = colors; 158 } 159 160 161 165 final void setLegendExistence (boolean existence) { 166 167 needsUpdate = true; 168 legendExistence = existence; 169 } 170 171 172 177 final void setLegendToWidthRatio (float ratio) { 178 179 needsUpdate = true; 180 legendToWidthRatio = ratio; 181 } 182 183 184 189 final void setLegendToHeightRatio (float ratio) { 190 191 needsUpdate = true; 192 legendToHeightRatio = ratio; 193 } 194 195 196 204 final void setLabelsPrecisionNum (int num) { 205 206 needsUpdate = true; 207 labelsPrecisionNum = num; 208 } 209 210 211 217 final boolean getAutoSetLayoutRatios() { 218 219 return autoSetLayoutRatios; 220 } 221 222 223 228 final boolean getBetweenChartAndLegendGapExistence() { 229 return betweenChartAndLegendGapExistence; 230 } 231 232 233 238 final int getBetweenChartAndLegendGapThicknessModel() { 239 return betweenChartAndLegendGapThicknessModel; 240 } 241 242 243 248 final boolean getTitleSqueeze () { 249 250 return !getTitleAutoLocate(); 251 } 252 253 254 259 final static float getDatasetTotal (float[] dataset) { 260 261 float total = 0f; 262 for (int i = 0; i < dataset.length; ++i) total += dataset[i]; 263 return total; 264 } 265 266 267 272 final static float[] getDataCategoryTotals (float[][] datasets) { 273 274 if (datasets.length > 0 && datasets[0].length > 0) { 275 float[] totals = new float[datasets[0].length]; 276 for (int i = 0; i < datasets[0].length; ++i) { 277 totals[i] = 0; 278 for (int j = 0; j < datasets.length; ++j) { 279 totals[i] += datasets[j][i]; 280 } 281 } 282 return totals; 283 } 284 else return new float[0]; 285 } 286 287 288 292 final Color[] getDatasetColors() { 293 294 return datasetColors; 295 } 296 297 298 303 final Color[] getDatasetColors (int begin, int end) { 304 305 Color[] subColors = new Color[end - begin]; 306 int j = 0; 307 for (int i = begin; i < end && i < datasetColors.length; ++i) { 308 subColors[j] = datasetColors[i]; 309 ++j; 310 } 311 return subColors; 312 } 313 314 315 319 final LegendArea getLegend() { 320 321 return legend; 322 } 323 324 325 329 final boolean getLegendExistence() { 330 331 return legendExistence; 332 } 333 334 335 339 final float getLegendToWidthRatio() { 340 341 return legendToWidthRatio; 342 } 343 344 345 349 final float getLegendToHeightRatio() { 350 351 return legendToHeightRatio; 352 } 353 354 355 361 final int getLabelsPrecisionNum () { 362 363 return labelsPrecisionNum; 364 } 365 366 367 382 static final float getPrecisionCeil (float value, int precision) { 383 384 float sign = value < 0f ? -1f : 1f; 385 value = value == -0f ? 0f : sign * value; 386 if (precision > 0) { 387 DecimalFormat df = new DecimalFormat ("#0.0#"); 388 String valueS = df.format (value); 389 int decIndex = valueS.indexOf (df.getDecimalFormatSymbols().getDecimalSeparator()); 390 precision = precision < valueS.length() - (valueS.length() - decIndex) ? 391 precision : valueS.length() - (valueS.length() - decIndex) - 1; 392 String prefix = valueS.substring (0, decIndex - precision); 393 String postfix; 394 postfix = valueS.substring (decIndex - precision, decIndex) + 395 valueS.substring (decIndex + 1, valueS.length()); 396 String toCeil = prefix + "." + postfix; 397 int ceiled = (int)Math.ceil (sign * Float.parseFloat(toCeil)); 398 if (ceiled == 0f) return getPrecisionCeil (sign * value, --precision); 399 else { 400 String ceiledS = String.valueOf (ceiled); 401 int i = precision; 402 for (i = 0; i < precision; ++i) ceiledS += "0"; 403 return Float.parseFloat (ceiledS); 404 } 405 } 406 else if (precision < 0) { 407 DecimalFormat df = new DecimalFormat ("#.00#"); 408 String valueS = df.format (value); 409 precision = -precision; 410 int decIndex = valueS.indexOf (df.getDecimalFormatSymbols().getDecimalSeparator()); 411 precision = 412 precision < valueS.length() - decIndex ? precision : valueS.length() - decIndex - 1; 413 String prefix = 414 valueS.substring (0, decIndex) + valueS.substring (decIndex + 1, decIndex + precision); 415 String postfix = valueS.substring (decIndex + precision, valueS.length()); 416 String toCeil = 417 prefix.substring(0, prefix.length()) + 418 postfix.substring (0, 1)+ "." + postfix.substring (1, postfix.length()); 419 int ceiled = (int)Math.ceil (sign * Float.parseFloat (toCeil)); 420 String ceiledS = String.valueOf (ceiled); 421 decIndex = sign < 0f ? ++decIndex : decIndex; 422 prefix = ceiledS.substring (0, decIndex); 423 postfix = ceiledS.substring (decIndex, ceiledS.length()); 424 valueS = prefix + "." + postfix; 425 return Float.parseFloat (valueS); 426 } 427 else return (float)Math.ceil (sign * value); 428 } 429 430 431 446 static final float getPrecisionFloor (float value, int precision) { 447 448 float sign = value < 0f ? -1f : 1f; 449 value = value == -0f ? 0f : sign * value; 450 if (precision > 0) { 451 DecimalFormat df = 452 new DecimalFormat ("#0.0#"); 453 String valueS = df.format (value); 454 int decIndex = 455 valueS.indexOf (df.getDecimalFormatSymbols().getDecimalSeparator()); 456 precision = precision < valueS.length() - (valueS.length() - decIndex) ? 457 precision : valueS.length() - (valueS.length() - decIndex) - 1; 458 String prefix = valueS.substring (0, decIndex - precision); 459 String postfix; 460 postfix = valueS.substring (decIndex - precision, decIndex) + 461 valueS.substring (decIndex + 1, valueS.length()); 462 String toFloor = prefix + "." + postfix; 463 int floored = (int)Math.floor (sign * Float.parseFloat(toFloor)); 464 if (floored == 0f) return getPrecisionFloor (sign * value, --precision); 465 else { 466 String flooredS = String.valueOf (floored); 467 int i = precision; 468 for (i = 0; i < precision; ++i) flooredS += "0"; 469 return Float.parseFloat (flooredS); 470 } 471 } 472 else if (precision < 0) { 473 DecimalFormat df = 474 new DecimalFormat ("#.00#"); 475 String valueS = df.format (value); 476 precision = -precision; 477 int decIndex = 478 valueS.indexOf (df.getDecimalFormatSymbols().getDecimalSeparator()); 479 precision = 480 precision < valueS.length() - decIndex? 481 precision : valueS.length() - decIndex - 1; 482 String prefix = valueS.substring (0, decIndex) + 483 valueS.substring (decIndex + 1, decIndex + precision); 484 String postfix = valueS.substring (decIndex + precision, valueS.length()); 485 String toFloor = prefix.substring(0, prefix.length()) + 486 postfix.substring (0, 1)+ "." + postfix.substring (1, postfix.length()); 487 int floored = (int)Math.floor (sign * Float.parseFloat (toFloor)); 488 String flooredS = String.valueOf (floored); 489 decIndex = sign < 0f ? ++decIndex : decIndex; 490 prefix = flooredS.substring (0, decIndex); 491 postfix = flooredS.substring (decIndex, flooredS.length()); 492 valueS = prefix + "." + postfix; 493 return Float.parseFloat (valueS); 494 } 495 else return (float)Math.floor (sign * value); 496 497 } 498 499 500 515 static final float getPrecisionRound (float value, int precision) { 516 517 float sign = value < 0f ? -1f : 1f; 518 value = value == -0f ? 0f : sign * value; 519 if (precision > 0) { 520 DecimalFormat df = 521 new DecimalFormat ("#0.0#"); 522 String valueS = df.format (value); 523 int decIndex = 524 valueS.indexOf (df.getDecimalFormatSymbols().getDecimalSeparator()); 525 precision = precision < valueS.length() - (valueS.length() - decIndex) ? 526 precision : valueS.length() - (valueS.length() - decIndex) - 1; 527 String prefix = valueS.substring (0, decIndex - precision); 528 String postfix; 529 postfix = valueS.substring (decIndex - precision, decIndex) + 530 valueS.substring (decIndex + 1, valueS.length()); 531 String toRound = prefix + "." + postfix; 532 int rounded = (int)Math.round (sign * Float.parseFloat (toRound)); 533 if (rounded == 0f) return getPrecisionRound (sign * value, --precision); 534 else { 535 String roundedS = String.valueOf (rounded); 536 int i = precision; 537 for (i = 0; i < precision; ++i) roundedS += "0"; 538 return Float.parseFloat (roundedS); 539 } 540 } 541 else if (precision < 0) { 542 DecimalFormat df = 543 new DecimalFormat ("#.00#"); 544 String valueS = df.format (value); 545 precision = -precision; 546 int decIndex = 547 valueS.indexOf (df.getDecimalFormatSymbols().getDecimalSeparator()); 548 precision = 549 precision < valueS.length() - decIndex? 550 precision : valueS.length() - decIndex - 1; 551 String prefix = valueS.substring (0, decIndex) + 552 valueS.substring (decIndex + 1, decIndex + precision); 553 String postfix = valueS.substring (decIndex + precision, valueS.length()); 554 String toRound = prefix.substring (0, prefix.length()) + 555 postfix.substring (0, 1)+ "." + postfix.substring (1, postfix.length()); 556 int rounded = (int)Math.round (sign * Float.parseFloat (toRound)); 557 String roundedS = String.valueOf (rounded); 558 decIndex = sign < 0f ? ++decIndex : decIndex; 559 prefix = roundedS.substring (0, decIndex); 560 postfix = roundedS.substring (decIndex, roundedS.length()); 561 valueS = prefix + "." + postfix; 562 return Float.parseFloat (valueS); 563 } 564 else return (float)Math.round (sign * value); 565 } 566 567 568 577 static final String getFloatToString (float value, int places) { 578 579 String format; 580 value = value == -0f ? 0f : value; 581 if (places < 0) { 582 format = "0.0"; 583 for (int i = 1; i < -places; ++i) format += "0"; 584 } 585 else format = "#"; 586 DecimalFormat df = new DecimalFormat (format); 587 return df.format (value); 588 } 589 590 591 595 final boolean getChartAreaNeedsUpdate() { 596 597 return (needsUpdate || getTitledAreaNeedsUpdate() || legend.getLegendAreaNeedsUpdate()); 598 } 599 600 601 613 final void resetChartAreaModel (boolean reset) { 614 615 needsUpdate = true; 616 resetTitledAreaModel (reset); 617 legend.resetLegendAreaModel (reset); 618 } 619 620 621 625 final void updateChartArea (Graphics2D g2D) { 626 627 if (getChartAreaNeedsUpdate()) { 628 updateTitledArea (g2D); 629 update(); 630 legend.updateLegendArea (g2D); 631 } 632 needsUpdate = false; 633 } 634 635 636 640 void paintComponent (Graphics2D g2D) { 641 642 updateChartArea (g2D); 643 super.paintComponent (g2D); 644 legend.paintComponent (g2D); 645 } 646 647 648 private void update() { 649 legend.setColors (datasetColors); 650 } 651 } | Popular Tags |