1 42 43 package org.jfree.chart; 44 45 import java.awt.Color ; 46 import java.awt.FontMetrics ; 47 import java.awt.Graphics ; 48 import java.awt.Graphics2D ; 49 import java.awt.Paint ; 50 import java.awt.font.LineMetrics ; 51 import java.awt.geom.Point2D ; 52 import java.awt.geom.Rectangle2D ; 53 54 import org.jfree.chart.event.LegendChangeEvent; 55 import org.jfree.chart.plot.MeterPlot; 56 import org.jfree.chart.plot.Plot; 57 import org.jfree.data.MeterDataset; 58 import org.jfree.data.ValueDataset; 59 60 65 public class MeterLegend extends StandardLegend { 66 67 68 private String legendText; 69 70 71 private boolean showNormal = true; 72 73 74 private boolean showWarning = true; 75 76 77 private boolean showCritical = true; 78 79 80 87 public MeterLegend(JFreeChart chart, String legendText) { 88 89 super(chart); 90 this.legendText = legendText; 91 92 } 93 94 99 public String getLegendText() { 100 return this.legendText; 101 } 102 103 108 public void setLegendText(String text) { 109 this.legendText = text; 110 notifyListeners(new LegendChangeEvent(this)); 111 } 112 113 121 public Rectangle2D draw(Graphics2D g2, Rectangle2D available) { 122 123 return draw(g2, available, (getAnchor() & HORIZONTAL) != 0, (getAnchor() & INVERTED) != 0); 124 125 } 126 127 139 private boolean updateInformation(MeterPlot plot, ValueDataset data, int type, int index, 140 LegendItem[] legendItems, Paint [] legendItemColors) { 141 142 boolean ret = false; 143 String label = null; 144 Paint paint = null; 147 148 switch(type) { 149 case MeterDataset.NORMAL_DATA: 150 paint = plot.getNormalPaint(); 153 label = MeterPlot.NORMAL_TEXT; 154 break; 155 case MeterDataset.WARNING_DATA: 156 paint = plot.getWarningPaint(); 159 label = MeterPlot.WARNING_TEXT; 160 break; 161 case MeterDataset.CRITICAL_DATA: 162 paint = plot.getCriticalPaint(); 165 label = MeterPlot.CRITICAL_TEXT; 166 break; 167 case MeterDataset.FULL_DATA: 168 paint = MeterPlot.DEFAULT_BACKGROUND_PAINT; 171 label = "Meter Graph"; 172 break; 173 default: 174 return false; 175 } 176 177 label += " Range: "; 180 legendItems[index] = new LegendItem(label, label, null, null, null, null); 190 legendItemColors[index] = paint; 191 ret = true; 192 return ret; 194 } 195 196 207 protected Rectangle2D draw(Graphics2D g2, Rectangle2D available, 208 boolean horizontal, boolean inverted) { 209 210 int legendCount = 0; 211 Plot plot = getChart().getPlot(); 212 if (!(plot instanceof MeterPlot)) { 213 throw new IllegalArgumentException ("Plot must be MeterPlot"); 214 } 215 MeterPlot meterPlot = (MeterPlot) plot; 216 ValueDataset data = meterPlot.getDataset(); 217 218 legendCount = 1; legendCount++; if (showCritical) { 221 legendCount++; 222 } 223 if (showWarning) { 224 legendCount++; 225 } 226 if (showNormal) { 227 legendCount++; 228 } 229 230 LegendItem[] legendItems = new LegendItem[legendCount]; 231 Color [] legendItemColors = new Color [legendCount]; 232 233 int currentItem = 0; 234 String label = this.legendText 235 + (data.getValue() != null ? (" Current Value: " + data.getValue().toString()) : ""); 236 legendItems[currentItem] = new LegendItem(label, label, null, null, null, null); 237 legendItemColors[currentItem] = null; currentItem++; 239 if (updateInformation(meterPlot, data, MeterDataset.FULL_DATA, 240 currentItem, legendItems, legendItemColors)) { 241 currentItem++; 242 } 243 if (showCritical && updateInformation(meterPlot, data, 244 MeterDataset.CRITICAL_DATA, currentItem, legendItems, legendItemColors)) { 245 currentItem++; 246 } 247 if (showWarning && updateInformation(meterPlot, data, 248 MeterDataset.WARNING_DATA, currentItem, legendItems, legendItemColors)) { 249 currentItem++; 250 } 251 if (showNormal && updateInformation(meterPlot, data, 252 MeterDataset.NORMAL_DATA, currentItem, legendItems, legendItemColors)) { 253 currentItem++; 254 } 255 256 if (legendItems != null) { 257 258 Rectangle2D legendArea = new Rectangle2D.Double (); 259 double availableWidth = available.getWidth(); 260 double availableHeight = available.getHeight(); 261 262 Point2D translation = new Point2D.Double (); 264 265 DrawableLegendItem[] items = new DrawableLegendItem[legendItems.length]; 267 g2.setFont(getItemFont()); 268 269 if (horizontal) { 272 double xstart = available.getX() + getOuterGap().getLeftSpace(availableWidth); 273 double xlimit = available.getMaxX() 274 + getOuterGap().getRightSpace(availableWidth) - 1; 275 double maxRowWidth = 0; 276 double xoffset = 0; 277 double rowHeight = 0; 278 double totalHeight = 0; 279 boolean startingNewRow = true; 280 281 for (int i = 0; i < legendItems.length; i++) { 282 items[i] = createLegendItem(g2, legendItems[i], xoffset, totalHeight); 283 if ((!startingNewRow) 284 && (items[i].getX() + items[i].getWidth() + xstart > xlimit)) { 285 maxRowWidth = Math.max(maxRowWidth, xoffset); 286 xoffset = 0; 287 totalHeight += rowHeight; 288 i--; 289 startingNewRow = true; 290 } 291 else { 292 rowHeight = Math.max(rowHeight, items[i].getHeight()); 293 xoffset += items[i].getWidth(); 294 startingNewRow = false; 295 } 296 } 297 298 maxRowWidth = Math.max(maxRowWidth, xoffset); 299 totalHeight += rowHeight; 300 301 legendArea = new Rectangle2D.Double (0, 0, maxRowWidth, totalHeight); 303 304 double yloc = (inverted) 307 ? available.getMaxY() - totalHeight 308 - getOuterGap().getBottomSpace(availableHeight) 309 : available.getY() + getOuterGap().getTopSpace(availableHeight); 310 double xloc = available.getX() + available.getWidth() / 2 - maxRowWidth / 2; 311 312 translation = new Point2D.Double (xloc, yloc); 314 } 315 else { double totalHeight = 0; 317 double maxWidth = 0; 318 g2.setFont(getItemFont()); 319 for (int i = 0; i < items.length; i++) { 320 items[i] = createLegendItem(g2, legendItems[i], 0, totalHeight); 321 totalHeight += items[i].getHeight(); 322 maxWidth = Math.max(maxWidth, items[i].getWidth()); 323 } 324 325 legendArea = new Rectangle2D.Float (0, 0, (float) maxWidth, (float) totalHeight); 327 328 double xloc = (inverted) 331 ? available.getMaxX() - maxWidth - getOuterGap().getRightSpace(availableWidth) 332 : available.getX() + getOuterGap().getLeftSpace(availableWidth); 333 double yloc = available.getY() + (available.getHeight() / 2) - (totalHeight / 2); 334 335 translation = new Point2D.Double (xloc, yloc); 337 } 338 339 g2.translate(translation.getX(), translation.getY()); 341 342 g2.setPaint(getBackgroundPaint()); 344 g2.fill(legendArea); 345 g2.setPaint(getOutlinePaint()); 346 g2.setStroke(getOutlineStroke()); 347 g2.draw(legendArea); 348 349 for (int i = 0; i < items.length; i++) { 351 Color color = legendItemColors[i]; 352 if (color != null) { 353 g2.setPaint(color); 354 g2.fill(items[i].getMarker()); 355 } 356 g2.setPaint(getItemPaint()); 357 g2.drawString(items[i].getItem().getLabel(), 358 (float) items[i].getLabelPosition().getX(), 359 (float) items[i].getLabelPosition().getY()); 360 } 361 362 g2.translate(-translation.getX(), -translation.getY()); 365 366 if (horizontal) { 367 double yy = available.getY(); 374 double yloc = (inverted) ? yy 375 : yy + legendArea.getHeight() 376 + getOuterGap().getBottomSpace(availableHeight); 377 378 return new Rectangle2D.Double (available.getX(), yloc, availableWidth, 380 availableHeight - legendArea.getHeight() 381 - getOuterGap().getTopSpace(availableHeight) 382 - getOuterGap().getBottomSpace(availableHeight)); 383 } 384 else { 385 double xloc = (inverted) ? available.getX() 392 : available.getX() 393 + legendArea.getWidth() 394 + getOuterGap().getLeftSpace(availableWidth) 395 + getOuterGap().getRightSpace(availableWidth); 396 397 398 return new Rectangle2D.Double (xloc, available.getY(), 400 availableWidth - legendArea.getWidth() 401 - getOuterGap().getLeftSpace(availableWidth) 402 - getOuterGap().getRightSpace(availableWidth), 403 availableHeight); 404 } 405 } 406 else { 407 return available; 408 } 409 } 410 411 421 private DrawableLegendItem createLegendItem(Graphics graphics, 422 LegendItem item, double x, double y) { 423 424 int innerGap = 2; 425 FontMetrics fm = graphics.getFontMetrics(); 426 LineMetrics lm = fm.getLineMetrics(item.getLabel(), graphics); 427 float textHeight = lm.getHeight(); 428 429 DrawableLegendItem drawable = new DrawableLegendItem(item); 430 431 float xloc = (float) (x + innerGap + 1.15f * textHeight); 432 float yloc = (float) (y + innerGap + (textHeight - lm.getLeading() - lm.getDescent())); 433 434 drawable.setLabelPosition(new Point2D.Float (xloc, yloc)); 435 436 float boxDim = textHeight * 0.70f; 437 xloc = (float) (x + innerGap + 0.15f * textHeight); 438 yloc = (float) (y + innerGap + 0.15f * textHeight); 439 440 drawable.setMarker(new Rectangle2D.Float (xloc, yloc, boxDim, boxDim)); 441 442 float width = (float) (drawable.getLabelPosition().getX() - x 443 + fm.getStringBounds(item.getLabel(), graphics).getWidth() 444 + 0.5 * textHeight); 445 446 float height = 2 * innerGap + textHeight; 447 drawable.setBounds(x, y, width, height); 448 return drawable; 449 450 } 451 452 } 453 | Popular Tags |