1 22 23 24 package net.sourceforge.chart2d; 25 26 27 import java.awt.*; 28 import java.awt.geom.*; 29 import java.util.Date ; 30 31 32 46 final class PieArea extends Area { 47 48 49 private float[] dataset; 50 private Color[] colors; 51 private Paint[] paints; 52 53 private Arc2D.Float[] sectors; 54 private int numSectors; 55 private int[] numSectorsInQuarters; 56 private boolean outlineSectors; 57 private Color outlineSectorsColor; 58 59 private float sectorPointDepthRatio; 60 private Point[] pointsInSectors; 61 private float sectorGapPointRatio; 62 private Point[] pointsOutSectors; 63 64 private int piePrefSpaceSize; 65 private boolean customSizing; 66 private Dimension customSpaceSize; 67 68 private int lightSource; 69 70 private boolean needsUpdate; 71 72 73 76 PieArea() { 77 78 setAutoSizes (false, false); 79 setAutoJustifys (false, false); 80 setBackgroundExistence (false); 81 setBorderExistence (false); 82 setGapExistence (true); 83 setGapThicknessModel (0); 84 setOutlineSectors (true); 85 setOutlineSectorsColor (Color.black); 86 setPiePrefSizeModel (100); 87 setSectorPointDepthRatio (.25f); setSectorGapPointRatio (.25f); 89 setDataset (new float[0]); 90 setColors (new Color[0]); 91 setCustomSpaceSize (false, new Dimension()); 92 setLightSource (TOP); 93 resetPieAreaModel (true); 94 needsUpdate = true; 95 numSectorsInQuarters = new int[4]; 96 } 97 98 99 103 final void setLightSource (int source) { 104 105 needsUpdate = true; 106 lightSource = source; 107 } 108 109 110 114 final void setOutlineSectors (boolean outline) { 115 116 needsUpdate = true; 117 outlineSectors = outline; 118 } 119 120 121 125 final void setOutlineSectorsColor (Color color) { 126 127 needsUpdate = true; 128 outlineSectorsColor = color; 129 } 130 131 132 137 final void setSectorPointDepthRatio (float ratio) { 138 needsUpdate = true; 139 sectorPointDepthRatio = ratio; 140 } 141 142 143 148 final void setSectorGapPointRatio (float ratio) { 149 needsUpdate = true; 150 sectorGapPointRatio = ratio; 151 } 152 153 154 159 final void setDataset (float[] values) { 160 161 needsUpdate = true; 162 dataset = values; 163 } 164 165 166 171 final void setColors (Color[] colors) { 172 173 needsUpdate = true; 174 this.colors = colors; 175 } 176 177 178 185 final void setPiePrefSizeModel (int size) { 186 187 needsUpdate = true; 188 piePrefSpaceSize = size; 189 } 190 191 192 197 final void setCustomSpaceSize (boolean customize, Dimension size) { 198 199 needsUpdate = true; 200 customSizing = customize; 201 customSpaceSize = size; 202 } 203 204 205 209 final int getLightSource() { 210 return lightSource; 211 } 212 213 214 218 final boolean getOutlineSectors() { 219 220 return outlineSectors; 221 } 222 223 224 228 final Color getOutlineSectorsColor() { 229 230 return outlineSectorsColor; 231 } 232 233 234 238 final float[] getDataset() { 239 240 return dataset; 241 } 242 243 244 248 final Color[] getColors() { 249 250 return colors; 251 } 252 253 254 258 final int getNumSectors () { 259 260 updatePieArea(); 261 return numSectors; 262 } 263 264 265 277 final int[] getNumSectorsInQuarters() { 278 279 updatePieArea(); 280 return numSectorsInQuarters; 281 } 282 283 284 289 final float getSectorPointDepthRatio() { 290 291 return sectorPointDepthRatio; 292 } 293 294 295 300 final Point[] getPointsInSectors() { 301 302 updatePieArea(); 303 return pointsInSectors; 304 } 305 306 307 312 final Point[] getPointsOutSectors() { 313 updatePieArea(); 314 return pointsOutSectors; 315 } 316 317 318 330 final void resetPieAreaModel (boolean reset) { 331 332 needsUpdate = true; 333 resetAreaModel (reset); 334 } 335 336 337 341 final boolean getPieAreaNeedsUpdate() { 342 343 return (needsUpdate || getAreaNeedsUpdate()); 344 } 345 346 347 350 final void updatePieArea () { 351 352 if (getPieAreaNeedsUpdate()) { 353 updateArea(); 354 update(); 355 } 356 needsUpdate = false; 357 } 358 359 360 364 final void paintComponent (Graphics2D g2D) { 365 366 updatePieArea(); 367 super.paintComponent (g2D); 368 369 for (int i = 0; i < numSectors; ++i) { 370 g2D.setPaint (paints[i]); 371 g2D.fill (sectors[i]); 372 } 373 374 if (outlineSectors) { 375 for (int i = 0; i < numSectors; ++i) { 376 g2D.setColor (outlineSectorsColor); 377 g2D.draw (sectors[i]); 378 } 379 } 380 } 381 382 383 private void update() { 384 385 if (!getAutoSize (MIN) && !customSizing) { 386 piePrefSpaceSize = applyRatio (piePrefSpaceSize, getRatio (LESSER)); 387 int tempPrefSize = piePrefSpaceSize < getSpaceSize (MAX).width ? 388 piePrefSpaceSize : getSpaceSize (MAX).width; 389 tempPrefSize = piePrefSpaceSize < getSpaceSize (MAX).height ? 390 piePrefSpaceSize : getSpaceSize (MAX).height; 391 setSpaceSize (MIN, new Dimension (tempPrefSize, tempPrefSize)); 392 } 393 else if (!getAutoSize (MIN) && customSizing) { 394 setSpaceSize (MIN, customSpaceSize); 395 } 396 397 int width = getSpaceSize (MIN).width; 398 int height = getSpaceSize (MIN).height; 399 int minSpaceSizeSide = width < height ? width : height; 400 401 Point location = getSpaceSizeLocation (MIN); 402 int locationX = location.x + (int)((width - minSpaceSizeSide) / 2f); 403 int locationY = location.y + (int)((height - minSpaceSizeSide) / 2f); 404 405 numSectors = dataset.length; 406 sectors = new Arc2D.Float[numSectors]; 407 408 float total = 0f; 409 for (int i = 0; i < numSectors; ++i) { 410 total = total + dataset[i]; 411 } 412 413 if (total != 0f) { 414 float end = 135f; 415 float begin = 135f; 416 float extent = 0f; 417 for (int i = 0; i < (numSectors - 1); ++i) { 418 extent = (dataset[i] / total) * 360f; 419 begin = end - extent; 420 sectors[i] = new Arc2D.Float (locationX, locationY, 421 minSpaceSizeSide, minSpaceSizeSide, begin, extent, Arc2D.PIE); 422 end = begin; 423 } 424 extent = (dataset[numSectors - 1] / total) * 360f; 425 begin = 135f; 426 sectors[numSectors - 1] = new Arc2D.Float (locationX, locationY, 427 minSpaceSizeSide, minSpaceSizeSide, begin, extent, Arc2D.PIE); 428 } 429 else if (numSectors != 0) { 430 float end = 135f; 431 float begin = 135f; 432 float extent = (1f / numSectors) * 360f; 433 for (int i = 0; i < (numSectors - 1); ++i) { 434 begin = end - extent; 435 sectors[i] = new Arc2D.Float (locationX, locationY, 436 minSpaceSizeSide, minSpaceSizeSide, begin, extent, Arc2D.PIE); 437 end = begin; 438 } 439 begin = 135f; 440 sectors[numSectors - 1] = new Arc2D.Float (locationX, locationY, 441 minSpaceSizeSide, minSpaceSizeSide, begin, extent, Arc2D.PIE); 442 } 443 444 pointsInSectors = new Point[numSectors]; 445 float radius = minSpaceSizeSide / 2f; 446 float centerX = locationX + radius; 447 float centerY = locationY + radius; 448 for (int i = 0; i < numSectors; ++i) { 449 float begin = sectors[i].start; 450 float extent = sectors[i].extent; 451 float theta = begin + extent / 2f; 452 float offsetX = (float)((1f - sectorPointDepthRatio) * radius * 453 Math.cos (Math.toRadians (theta))); 454 float offsetY = (float)((1f - sectorPointDepthRatio) * radius * 455 Math.sin (Math.toRadians (theta))); 456 float x = centerX + offsetX; 457 float y = centerY - offsetY; 458 pointsInSectors[i] = new Point (Math.round (x), Math.round (y)); 459 } 460 461 int gapThickness = getGapThickness(); 462 pointsOutSectors = new Point[numSectors]; 463 float outOffset = sectorGapPointRatio * gapThickness; 464 for (int i = 0; i < numSectors; ++i) { 465 466 float begin = sectors[i].start; 467 float extent = sectors[i].extent; 468 float theta = begin + extent / 2f; 469 float offsetX = (float)((radius + outOffset) * 470 Math.cos (Math.toRadians(theta))); 471 float offsetY = (float)((radius + outOffset) * 472 Math.sin (Math.toRadians(theta))); 473 float x = centerX + offsetX; 474 float y = centerY - offsetY; 475 pointsOutSectors[i] = new Point (Math.round (x), Math.round (y)); 476 } 477 478 numSectorsInQuarters[TOP] = 0; 479 numSectorsInQuarters[RIGHT] = 0; 480 numSectorsInQuarters[BOTTOM] = 0; 481 numSectorsInQuarters[LEFT] = 0; 482 483 boolean topDone = false; 484 485 for (int i = 0; i < numSectors; ++i) { 486 487 float begin = sectors[i].start; 488 float extent = sectors[i].extent; 489 begin = (begin + 720) % 360; 490 extent = (extent + 720) % 360; 491 float angle = begin + (extent / 2); 492 493 if (angle <= 135 && angle > 45){ 494 if (!topDone) ++numSectorsInQuarters[TOP]; 495 else ++numSectorsInQuarters[LEFT]; 496 } 497 else if (angle > 135 && angle <= 225){ 498 ++numSectorsInQuarters[LEFT]; 499 topDone = true; 500 } 501 else if (angle > 225 && angle <= 315){ 502 ++numSectorsInQuarters[BOTTOM]; 503 topDone = true; 504 } 505 else { 506 ++numSectorsInQuarters[RIGHT]; 507 topDone = true; 508 } 509 } 510 511 paints = new Paint[colors.length]; 512 for (int i = 0; i < paints.length; ++i) { 513 if (lightSource == TOP) { 514 paints[i] = new GradientPaint (locationX, locationY, colors[i].brighter(), 515 locationX, locationY + height, colors[i]); 516 } 517 else if (lightSource == BOTTOM) { 518 paints[i] = new GradientPaint (locationX, locationY, colors[i], 519 locationX, locationY + height, colors[i].brighter()); 520 } 521 else if (lightSource == LEFT) { 522 paints[i] = new GradientPaint (locationX, locationY, colors[i].brighter(), 523 locationX + width, locationY, colors[i]); 524 } 525 else if (lightSource == RIGHT) { 526 paints[i] = new GradientPaint (locationX, locationY, colors[i], 527 locationX + width, locationY, colors[i].brighter()); 528 } 529 else { 530 paints[i] = colors[i]; 531 } 532 } 533 } 534 } | Popular Tags |