1 /* ============================================================ 2 * JRobin : Pure java implementation of RRDTool's functionality 3 * ============================================================ 4 * 5 * Project Info: http://www.jrobin.org 6 * Project Lead: Sasa Markovic (saxon@jrobin.org) 7 * 8 * Developers: Sasa Markovic (saxon@jrobin.org) 9 * 10 * 11 * (C) Copyright 2003-2005, by Sasa Markovic. 12 * 13 * This library is free software; you can redistribute it and/or modify it under the terms 14 * of the GNU Lesser General Public License as published by the Free Software Foundation; 15 * either version 2.1 of the License, or (at your option) any later version. 16 * 17 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 * See the GNU Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public License along with this 22 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 23 * Boston, MA 02111-1307, USA. 24 */ 25 package org.jrobin.graph; 26 27 import java.awt.Font; 28 import java.awt.Paint; 29 import java.io.File; 30 import java.io.InputStream; 31 import java.net.MalformedURLException; 32 import java.net.URL; 33 import java.util.ArrayList; 34 import java.util.List; 35 36 import org.jrobin.core.RrdException; 37 import org.jrobin.core.Util; 38 import org.jrobin.data.Plottable; 39 40 /** 41 * Class which should be used to define new JRobin graph. Once constructed and populated with data 42 * object of this class should be passed to the constructor of the {@link RrdGraph} class which 43 * will actually create the graph. 44 * <p/> 45 * The text printed below the actual graph can be formated by appending 46 * special escaped characters at the end of a text. When ever such a 47 * character occurs, all pending text is pushed onto the graph according to 48 * the character specified. 49 * <p/> 50 * Valid markers are: \j for justified, \l for left aligned, \r for right 51 * aligned and \c for centered. 52 * <p/> 53 * Normally there are two space characters inserted between every two 54 * items printed into the graph. The space following a string can be 55 * suppressed by putting a \g at the end of the string. The \g also squashes 56 * any space inside the string if it is at the very end of the string. 57 * This can be used in connection with %s to suppress empty unit strings. 58 * <p/> 59 * A special case is COMMENT:\s this inserts some additional vertical 60 * space before placing the next row of legends. 61 * <p/> 62 * When text has to be formated without special instructions from your 63 * side, RRDTool will automatically justify the text as soon as one string 64 * goes over the right edge. If you want to prevent the justification 65 * without forcing a newline, you can use the special tag \J at the end of 66 * the string to disable the auto justification. 67 */ 68 public class RrdGraphDef implements RrdGraphConstants { 69 boolean poolUsed = false; // ok 70 boolean antiAliasing = false; // ok 71 String filename = RrdGraphConstants.IN_MEMORY_IMAGE; // ok 72 long startTime, endTime; // ok 73 TimeAxisSetting timeAxisSetting = null; // ok 74 ValueAxisSetting valueAxisSetting = null; // ok 75 boolean altYGrid = false; // ok 76 boolean noMinorGrid = false; // ok 77 boolean altYMrtg = false; // ok 78 boolean altAutoscale = false; // ok 79 boolean altAutoscaleMax = false; // ok 80 int unitsExponent = Integer.MAX_VALUE; // ok 81 int unitsLength = DEFAULT_UNITS_LENGTH; // ok 82 String verticalLabel = null; // ok 83 int width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT; // ok 84 boolean interlaced = false; // ok 85 String imageInfo = null; // ok 86 String imageFormat = DEFAULT_IMAGE_FORMAT; // ok 87 float imageQuality = DEFAULT_IMAGE_QUALITY; // ok 88 String backgroundImage = null; // ok 89 String overlayImage = null; // ok 90 String unit = null; // ok 91 String signature = "Created with JRobin"; // ok 92 boolean lazy = false; // ok 93 double minValue = Double.NaN; // ok 94 double maxValue = Double.NaN; // ok 95 boolean rigid = false; // ok 96 double base = DEFAULT_BASE; // ok 97 boolean logarithmic = false; // ok 98 Paint[] colors = new Paint[] { 99 // ok 100 DEFAULT_CANVAS_COLOR, 101 DEFAULT_BACK_COLOR, 102 DEFAULT_SHADEA_COLOR, 103 DEFAULT_SHADEB_COLOR, 104 DEFAULT_GRID_COLOR, 105 DEFAULT_MGRID_COLOR, 106 DEFAULT_FONT_COLOR, 107 DEFAULT_FRAME_COLOR, 108 DEFAULT_ARROW_COLOR 109 }; 110 boolean noLegend = false; // ok 111 boolean onlyGraph = false; // ok 112 boolean forceRulesLegend = false; // ok 113 String title = null; // ok 114 long step = 0; // ok 115 protected Font smallFont; 116 protected Font largeFont; 117 boolean drawXGrid = true; // ok 118 boolean drawYGrid = true; // ok 119 int firstDayOfWeek = FIRST_DAY_OF_WEEK; // ok 120 boolean showSignature = true; 121 File fontDir = null; 122 123 List<Source> sources = new ArrayList<Source>(); 124 List<CommentText> comments = new ArrayList<CommentText>(); 125 List<PlotElement> plotElements = new ArrayList<PlotElement>(); 126 127 /** 128 * Creates RrdGraphDef object and sets default time span (default ending time is 'now', 129 * default starting time is 'end-1day'. 130 */ 131 public RrdGraphDef() { 132 try { 133 setTimeSpan(Util.getTimestamps(DEFAULT_START, DEFAULT_END)); 134 } catch (RrdException e) { 135 throw new RuntimeException(e); 136 } 137 138 String fontdirProperty = System.getProperty("jrobin.fontdir"); 139 if (fontdirProperty != null && fontdirProperty.length() != 0) { 140 fontDir = new File(fontdirProperty); 141 } 142 143 // smallFont = this.getFontFromResourceName(RrdGraphConstants.DEFAULT_MONOSPACE_FONT_FILE).deriveFont(10); 144 // largeFont = this.getFontFromResourceName(RrdGraphConstants.DEFAULT_MONOSPACE_FONT_FILE).deriveFont(12); 145 smallFont = new Font(DEFAULT_FONT_NAME, Font.PLAIN, 10); 146 largeFont = new Font(DEFAULT_FONT_NAME, Font.BOLD, 12); 147 } 148 149 protected Font getFontFromResourceName(String name) { 150 Font font = null; 151 Exception exception = null; 152 URL file = null; 153 154 if (fontDir != null) { 155 try { 156 file = new URL("file://" + new File(fontDir, name).getAbsolutePath()); 157 } catch (MalformedURLException e) { 158 // fall through to the jar 159 exception = e; 160 } 161 } 162 if (file == null) { 163 file = this.getClass().getResource(name); 164 } 165 166 if (file != null) { 167 // System.err.println("Found a font URL: " + file.toExternalForm()); 168 try { 169 InputStream fontStream = file.openStream(); 170 font = Font.createFont(Font.TRUETYPE_FONT, fontStream); 171 fontStream.close(); 172 } catch (Exception e) { 173 exception = e; 174 } 175 } else { 176 // we can't find our fonts, fall back to the system font 177 System.err.println("An error occurred loading the font '" + name + "'. Falling back to the default."); 178 if (exception != null) { 179 System.err.println(exception.getLocalizedMessage()); 180 } 181 font = new Font(DEFAULT_FONT_NAME, Font.PLAIN, 10); 182 } 183 184 if (font == null) { 185 font = new Font(null, Font.PLAIN, 10); 186 } 187 return font; 188 } 189 190 /** 191 * Sets the signature string that runs along the right-side of the graph. 192 * Defaults to "Created with JRobin". 193 * 194 * @param signature the string to print 195 */ 196 public void setSignature(String signature) { 197 this.signature = signature; 198 } 199 200 /** 201 * Gets the signature string that runs along the right-side of the graph. 202 * @return the signature string 203 */ 204 public String getSignature() { 205 return this.signature; 206 } 207 208 /** 209 * Sets the time when the graph should begin. Time in seconds since epoch 210 * (1970-01-01) is required. Negative numbers are relative to the current time. 211 * 212 * @param time Starting time for the graph in seconds since epoch 213 */ 214 public void setStartTime(long time) { 215 this.startTime = time; 216 if (time <= 0) { 217 this.startTime += Util.getTime(); 218 } 219 } 220 221 /** 222 * Sets the time when the graph should end. Time in seconds since epoch 223 * (1970-01-01) is required. Negative numbers are relative to the current time. 224 * 225 * @param time Ending time for the graph in seconds since epoch 226 */ 227 public void setEndTime(long time) { 228 this.endTime = time; 229 if (time <= 0) { 230 this.endTime += Util.getTime(); 231 } 232 } 233 234 /** 235 * Sets starting and ending time for the for the graph. Timestamps in seconds since epoch are 236 * required. Negative numbers are relative to the current time. 237 * 238 * @param startTime Starting time in seconds since epoch 239 * @param endTime Ending time in seconds since epoch 240 */ 241 public void setTimeSpan(long startTime, long endTime) { 242 setStartTime(startTime); 243 setEndTime(endTime); 244 } 245 246 /** 247 * Sets starting and ending time for the for the graph. Timestamps in seconds since epoch are 248 * required. 249 * 250 * @param timestamps Array of timestamps. The first array item will be chosen for the starting 251 * timestamp. The last array item will be chosen for the ending timestamp. 252 */ 253 public void setTimeSpan(long[] timestamps) { 254 setTimeSpan(timestamps[0], timestamps[timestamps.length - 1]); 255 } 256 257 /** 258 * Sets RrdDbPool usage policy (defaults to true). If set to true, 259 * {@link org.jrobin.core.RrdDbPool RrdDbPool} will be used to 260 * access individual RRD files. If set to false, RRD files will be accessed directly. 261 * 262 * @param poolUsed true, if RrdDbPool class should be used. False otherwise. 263 */ 264 public void setPoolUsed(boolean poolUsed) { 265 this.poolUsed = poolUsed; 266 } 267 268 /** 269 * Sets the name of the graph to generate. Since JRobin outputs GIFs, PNGs, 270 * and JPEGs it's recommended that the filename end in either .gif, 271 * .png or .jpg. JRobin does not enforce this, however. If the filename is 272 * set to '-' the image will be created only in memory (no file will be created). 273 * PNG and GIF formats are recommended but JPEGs should be avoided. 274 * 275 * @param filename Path to the image file 276 */ 277 public void setFilename(String filename) { 278 this.filename = filename; 279 } 280 281 /** 282 * Configures x-axis grid and labels. The x-axis label is quite complex to configure. 283 * So if you don't have very special needs, you can rely on the autoconfiguration to 284 * get this right. 285 * <p/> 286 * Otherwise, you have to configure three elements making up the x-axis labels 287 * and grid. The base grid, the major grid and the labels. 288 * The configuration is based on the idea that you first specify a well 289 * known amount of time and then say how many times 290 * it has to pass between each minor/major grid line or label. For the label 291 * you have to define two additional items: The precision of the label 292 * in seconds and the format used to generate the text 293 * of the label. 294 * <p/> 295 * For example, if you wanted a graph with a base grid every 10 minutes and a major 296 * one every hour, with labels every hour you would use the following 297 * x-axis definition. 298 * <p/> 299 * <pre> 300 * setTimeAxis(RrdGraphConstants.MINUTE, 10, 301 * RrdGraphConstants.HOUR, 1, 302 * RrdGraphConstants.HOUR, 1, 303 * 0, "%H:%M") 304 * </pre> 305 * <p/> 306 * The precision in this example is 0 because the %X format is exact. 307 * If the label was the name of the day, we would have had a precision 308 * of 24 hours, because when you say something like 'Monday' you mean 309 * the whole day and not Monday morning 00:00. Thus the label should 310 * be positioned at noon. By defining a precision of 24 hours or 311 * rather 86400 seconds, you make sure that this happens. 312 * 313 * @param minorUnit Minor grid unit. Minor grid, major grid and label units 314 * can be one of the following constants defined in 315 * {@link RrdGraphConstants}: {@link RrdGraphConstants#SECOND SECOND}, 316 * {@link RrdGraphConstants#MINUTE MINUTE}, {@link RrdGraphConstants#HOUR HOUR}, 317 * {@link RrdGraphConstants#DAY DAY}, {@link RrdGraphConstants#WEEK WEEK}, 318 * {@link RrdGraphConstants#MONTH MONTH}, {@link RrdGraphConstants#YEAR YEAR}. 319 * @param minorUnitCount Number of minor grid units between minor grid lines. 320 * @param majorUnit Major grid unit. 321 * @param majorUnitCount Number of major grid units between major grid lines. 322 * @param labelUnit Label unit. 323 * @param labelUnitCount Number of label units between labels. 324 * @param labelSpan Label precision 325 * @param simpleDateFormat Date format (SimpleDateFormat pattern of strftime-like pattern) 326 */ 327 public void setTimeAxis(int minorUnit, int minorUnitCount, int majorUnit, int majorUnitCount, 328 int labelUnit, int labelUnitCount, int labelSpan, String simpleDateFormat) { 329 timeAxisSetting = new TimeAxisSetting(minorUnit, minorUnitCount, majorUnit, majorUnitCount, 330 labelUnit, labelUnitCount, labelSpan, simpleDateFormat); 331 } 332 333 /** 334 * Sets vertical axis grid and labels. Makes vertical grid lines appear 335 * at gridStep interval. Every labelFactor*gridStep, a major grid line is printed, 336 * along with label showing the value of the grid line. 337 * 338 * @param gridStep Minor grid step 339 * @param labelFactor Specifies how many minor minor grid steps will appear between labels 340 * (major grid lines) 341 */ 342 public void setValueAxis(double gridStep, int labelFactor) { 343 valueAxisSetting = new ValueAxisSetting(gridStep, labelFactor); 344 } 345 346 /** 347 * Places Y grid dynamically based on graph Y range. Algorithm ensures 348 * that you always have grid, that there are enough but not too many 349 * grid lines and the grid is metric. That is grid lines are placed 350 * every 1, 2, 5 or 10 units. 351 * 352 * @param altYGrid true, if Y grid should be calculated dynamically (defaults to false) 353 */ 354 public void setAltYGrid(boolean altYGrid) { 355 this.altYGrid = altYGrid; 356 } 357 358 /** 359 * Use this method to turn off minor grid lines (printed by default) 360 * 361 * @param noMinorGrid true, to turn off, false to turn on (default) 362 */ 363 public void setNoMinorGrid(boolean noMinorGrid) { 364 this.noMinorGrid = noMinorGrid; 365 } 366 367 /** 368 * Use this method to request MRTG-like graph (false by default) 369 * 370 * @param altYMrtg true, to create MRTG-like graph, false otherwise (default) 371 */ 372 public void setAltYMrtg(boolean altYMrtg) { 373 this.altYMrtg = altYMrtg; 374 } 375 376 /** 377 * Computes Y range based on function absolute minimum and maximum 378 * values. Default algorithm uses predefined set of ranges. This is 379 * good in many cases but it fails miserably when you need to graph 380 * something like 260 + 0.001 * sin(x). Default algorithm will use Y 381 * range from 250 to 300 and on the graph you will see almost straight 382 * line. With --alt-autoscale Y range will be from slightly less the 383 * 260 - 0.001 to slightly more then 260 + 0.001 and periodic behavior 384 * will be seen. 385 * 386 * @param altAutoscale true to request alternative autoscaling, false otherwise 387 * (default). 388 */ 389 public void setAltAutoscale(boolean altAutoscale) { 390 this.altAutoscale = altAutoscale; 391 } 392 393 /** 394 * Computes Y range based on function absolute minimum and maximum 395 * values. Where setAltAutoscale(true) will modify both the absolute maximum AND 396 * minimum values, this option will only affect the maximum value. The 397 * minimum value, if not defined elsewhere, will be 0. This 398 * option can be useful when graphing router traffic when the WAN line 399 * uses compression, and thus the throughput may be higher than the 400 * WAN line speed. 401 * 402 * @param altAutoscaleMax true to request alternative autoscaling, false 403 * otherwise (default) 404 */ 405 public void setAltAutoscaleMax(boolean altAutoscaleMax) { 406 this.altAutoscaleMax = altAutoscaleMax; 407 } 408 409 /** 410 * Sets the 10**unitsExponent scaling of the y-axis values. Normally 411 * values will be scaled to the appropriate units (k, M, etc.). However 412 * you may wish to display units always in k (Kilo, 10e3) even if 413 * the data is in the M (Mega, 10e6) range for instance. Value should 414 * be an integer which is a multiple of 3 between -18 and 18, inclu- 415 * sive. It is the exponent on the units you which to use. For example, 416 * use 3 to display the y-axis values in k (Kilo, 10e3, thou- 417 * sands), use -6 to display the y-axis values in u (Micro, 10e-6, 418 * millionths). Use a value of 0 to prevent any scaling of the y-axis 419 * values. 420 * 421 * @param unitsExponent 422 */ 423 public void setUnitsExponent(int unitsExponent) { 424 this.unitsExponent = unitsExponent; 425 } 426 427 /** 428 * Sets the character width on the left side of the graph for 429 * y-axis values. 430 * 431 * @param unitsLength Number of characters on the left side of the graphs 432 * reserved for vertical axis labels. 433 */ 434 public void setUnitsLength(int unitsLength) { 435 this.unitsLength = unitsLength; 436 } 437 438 /** 439 * Sets vertical label on the left side of the graph. This is normally used 440 * to specify the units used. 441 * 442 * @param verticalLabel Vertical axis label 443 */ 444 public void setVerticalLabel(String verticalLabel) { 445 this.verticalLabel = verticalLabel; 446 } 447 448 /** 449 * Sets width of the drawing area within the graph. This affects the total 450 * size of the image. 451 * 452 * @param width Width of the drawing area. 453 */ 454 public void setWidth(int width) { 455 this.width = width; 456 } 457 458 /** 459 * Sets height of the drawing area within the graph. This affects the total 460 * size of the image. 461 * 462 * @param height Height of the drawing area. 463 */ 464 public void setHeight(int height) { 465 this.height = height; 466 } 467 468 /** 469 * Creates interlaced GIF image (currently not supported, 470 * method is present only for RRDTool comaptibility). 471 * 472 * @param interlaced true, if GIF image should be interlaced. 473 */ 474 public void setInterlaced(boolean interlaced) { 475 this.interlaced = interlaced; 476 } 477 478 /** 479 * Creates additional image information. 480 * After the image has been created, the graph function uses imageInfo 481 * format string (printf-like) to create output similar to 482 * the {@link #print(String, String, String)} function. 483 * The format string is supplied with the following parameters: 484 * filename, xsize and ysize (in that particular order). 485 * <p/> 486 * For example, in order to generate an IMG tag 487 * suitable for including the graph into a web page, the command 488 * would look like this: 489 * <pre> 490 * setImageInfo("<IMG SRC='/img/%s' WIDTH='%d' HEIGHT='%d' ALT='Demo'>"); 491 * </pre> 492 * 493 * @param imageInfo Image info format. Use %s placeholder for filename, %d placeholder for 494 * image width and height. 495 */ 496 public void setImageInfo(String imageInfo) { 497 this.imageInfo = imageInfo; 498 } 499 500 /** 501 * Sets image format. 502 * 503 * @param imageFormat "PNG", "GIF" or "JPG". 504 */ 505 public void setImageFormat(String imageFormat) { 506 this.imageFormat = imageFormat; 507 } 508 509 /** 510 * Sets background image - currently, only PNG images can be used as background. 511 * 512 * @param backgroundImage Path to background image 513 */ 514 public void setBackgroundImage(String backgroundImage) { 515 this.backgroundImage = backgroundImage; 516 } 517 518 /** 519 * Sets overlay image - currently, only PNG images can be used as overlay. Overlay image is 520 * printed on the top of the image, once it is completely created. 521 * 522 * @param overlayImage Path to overlay image 523 */ 524 public void setOverlayImage(String overlayImage) { 525 this.overlayImage = overlayImage; 526 } 527 528 /** 529 * Sets unit to be displayed on y axis. It is wise to use only short units on graph, however. 530 * 531 * @param unit Unit description 532 */ 533 public void setUnit(String unit) { 534 this.unit = unit; 535 } 536 537 /** 538 * Creates graph only if the current graph is out of date or not existent. 539 * 540 * @param lazy true, if graph should be 'lazy', false otherwise (defualt) 541 */ 542 public void setLazy(boolean lazy) { 543 this.lazy = lazy; 544 } 545 546 /** 547 * Sets the lower limit of a graph. But rather, this is the 548 * maximum lower bound of a graph. For example, the value -100 will 549 * result in a graph that has a lower limit of -100 or less. Use this 550 * method to expand graphs down. 551 * 552 * @param minValue Minimal value displayed on the graph 553 */ 554 public void setMinValue(double minValue) { 555 this.minValue = minValue; 556 } 557 558 /** 559 * Defines the value normally located at the upper border of the 560 * graph. If the graph contains higher values, the upper border will 561 * move upwards to accommodate these values as well. 562 * <p/> 563 * If you want to define an upper-limit which will not move in any 564 * event you have to use {@link #setRigid(boolean)} method as well. 565 * 566 * @param maxValue Maximal value displayed on the graph. 567 */ 568 public void setMaxValue(double maxValue) { 569 this.maxValue = maxValue; 570 } 571 572 /** 573 * Sets rigid boundaries mode. Normally JRObin will automatically expand 574 * the lower and upper limit if the graph contains a value outside the 575 * valid range. With the <code>true</code> argument you can disable this behavior. 576 * 577 * @param rigid true if uper and lower limits should not be expanded to accomodate 578 * values outside of the specified range. False otherwise (default). 579 */ 580 public void setRigid(boolean rigid) { 581 this.rigid = rigid; 582 } 583 584 /** 585 * Sets default base for magnitude scaling. If you are graphing memory 586 * (and NOT network traffic) this switch should be set to 1024 so that 1Kb is 1024 byte. 587 * For traffic measurement, 1 kb/s is 1000 b/s. 588 * 589 * @param base Base value (defaults to 1000.0) 590 */ 591 public void setBase(double base) { 592 this.base = base; 593 } 594 595 /** 596 * Sets logarithmic y-axis scaling. 597 * 598 * @param logarithmic true, for logarithmic scaling, false otherwise (default). 599 */ 600 public void setLogarithmic(boolean logarithmic) { 601 this.logarithmic = logarithmic; 602 } 603 604 /** 605 * Overrides the colors for the standard elements of the graph. The colorTag 606 * must be one of the following constants defined in the 607 * {@link RrdGraphConstants}: 608 * {@link RrdGraphConstants#COLOR_BACK COLOR_BACK} background, 609 * {@link RrdGraphConstants#COLOR_CANVAS COLOR_CANVAS} canvas, 610 * {@link RrdGraphConstants#COLOR_SHADEA COLOR_SHADEA} left/top border, 611 * {@link RrdGraphConstants#COLOR_SHADEB COLOR_SHADEB} right/bottom border, 612 * {@link RrdGraphConstants#COLOR_GRID COLOR_GRID} major grid, 613 * {@link RrdGraphConstants#COLOR_MGRID COLOR_MGRID} minor grid, 614 * {@link RrdGraphConstants#COLOR_FONT COLOR_FONT} font, 615 * {@link RrdGraphConstants#COLOR_FRAME COLOR_FRAME} axis of the graph, 616 * {@link RrdGraphConstants#COLOR_ARROW COLOR_ARROW} arrow. This method can 617 * be called multiple times to set several colors. 618 * 619 * @param colorTag 620 * Color tag, as explained above. 621 * @param color 622 * Any color (paint) you like 623 * @throws RrdException 624 * Thrown if invalid colorTag is supplied. 625 */ 626 public void setColor(int colorTag, Paint color) throws RrdException { 627 if (colorTag >= 0 && colorTag < colors.length) { 628 colors[colorTag] = color; 629 } else { 630 throw new RrdException("Invalid color index specified: " + colorTag); 631 } 632 } 633 634 /** 635 * Overrides the colors for the standard elements of the graph by element name. 636 * See {@link #setColor(int, java.awt.Paint)} for full explanation. 637 * 638 * @param colorName One of the following strings: "BACK", "CANVAS", "SHADEA", "SHADEB", 639 * "GRID", "MGRID", "FONT", "FRAME", "ARROW" 640 * @param color Any color (paint) you like 641 * @throws RrdException Thrown if invalid element name is supplied. 642 */ 643 public void setColor(String colorName, Paint color) throws RrdException { 644 setColor(getColorTagByName(colorName), color); 645 } 646 647 private static int getColorTagByName(String colorName) throws RrdException { 648 for (int i = 0; i < COLOR_NAMES.length; i++) { 649 if (COLOR_NAMES[i].equalsIgnoreCase(colorName)) { 650 return i; 651 } 652 } 653 throw new RrdException("Unknown color name specified: " + colorName); 654 } 655 656 /** 657 * Suppress generation of legend, only render the graph. 658 * 659 * @param noLegend true if graph legend should be omitted. False otherwise (default). 660 */ 661 public void setNoLegend(boolean noLegend) { 662 this.noLegend = noLegend; 663 } 664 665 /** 666 * Suppresses anything but the graph, works only for height < 64. 667 * 668 * @param onlyGraph true if only graph should be created, false otherwise (default). 669 */ 670 public void setOnlyGraph(boolean onlyGraph) { 671 this.onlyGraph = onlyGraph; 672 } 673 674 /** 675 * Force the generation of HRULE and VRULE legend even if those HRULE 676 * or VRULE will not be drawn because out of graph boundaries. 677 * 678 * @param forceRulesLegend true if rule legend should be always printed, 679 * false otherwise (default). 680 */ 681 public void setForceRulesLegend(boolean forceRulesLegend) { 682 this.forceRulesLegend = forceRulesLegend; 683 } 684 685 /** 686 * Defines a title to be written into the graph. 687 * 688 * @param title Graph title. 689 */ 690 public void setTitle(String title) { 691 this.title = title; 692 } 693 694 /** 695 * Suggests which time step should be used by JRobin while processing data from RRD files. 696 * 697 * @param step Desired time step (don't use this method if you don't know what you're doing). 698 */ 699 public void setStep(long step) { 700 this.step = step; 701 } 702 703 /** 704 * Get the default small font for graphing. 705 * @return the font 706 */ 707 public Font getSmallFont() { 708 return this.smallFont; 709 } 710 711 /** 712 * Get the default large font for graphing. 713 * @return the font 714 */ 715 public Font getLargeFont() { 716 return this.largeFont; 717 } 718 719 720 /** 721 * Sets default font for graphing. Note that JRobin will behave unpredictably if proportional 722 * font is selected. 723 * 724 * @param smallFont Default font for graphing. Use only monospaced fonts. 725 */ 726 public void setSmallFont(Font smallFont) { 727 this.smallFont = smallFont; 728 } 729 730 /** 731 * Sets title font. 732 * 733 * @param largeFont Font to be used for graph title. 734 */ 735 public void setLargeFont(Font largeFont) { 736 this.largeFont = largeFont; 737 } 738 739 /** 740 * Defines virtual datasource. This datasource can then be used 741 * in other methods like {@link #datasource(String, String)} or 742 * {@link #gprint(String, String, String)}. 743 * 744 * @param name Source name 745 * @param rrdPath Path to RRD file 746 * @param dsName Datasource name in the specified RRD file 747 * @param consolFun Consolidation function (AVERAGE, MIN, MAX, LAST) 748 */ 749 public void datasource(String name, String rrdPath, String dsName, String consolFun) { 750 sources.add(new Def(name, rrdPath, dsName, consolFun)); 751 } 752 753 /** 754 * Defines virtual datasource. This datasource can then be used 755 * in other methods like {@link #datasource(String, String)} or 756 * {@link #gprint(String, String, String)}. 757 * 758 * @param name Source name 759 * @param rrdPath Path to RRD file 760 * @param dsName Datasource name in the specified RRD file 761 * @param consolFun Consolidation function (AVERAGE, MIN, MAX, LAST) 762 * @param backend Backend to be used while fetching data from a RRD file. 763 */ 764 public void datasource(String name, String rrdPath, String dsName, String consolFun, String backend) { 765 sources.add(new Def(name, rrdPath, dsName, consolFun, backend)); 766 } 767 768 /** 769 * Create a new virtual datasource by evaluating a mathematical 770 * expression, specified in Reverse Polish Notation (RPN). 771 * 772 * @param name Source name 773 * @param rpnExpression RPN expression. 774 */ 775 public void datasource(String name, String rpnExpression) { 776 sources.add(new CDef(name, rpnExpression)); 777 } 778 779 /** 780 * Creates a new (static) virtual datasource. The value of the datasource is constant. This value is 781 * evaluated by applying the given consolidation function to another virtual datasource. 782 * 783 * @param name Source name 784 * @param defName Other source name 785 * @param consolFun Consolidation function to be applied to other datasource. 786 */ 787 public void datasource(String name, String defName, String consolFun) { 788 sources.add(new SDef(name, defName, consolFun)); 789 } 790 791 /** 792 * Creates a new (plottable) datasource. Datasource values are obtained from the given plottable 793 * object. 794 * 795 * @param name Source name. 796 * @param plottable Plottable object. 797 */ 798 public void datasource(String name, Plottable plottable) { 799 sources.add(new PDef(name, plottable)); 800 } 801 802 /** 803 * Calculates the chosen consolidation function CF over the given datasource 804 * and creates the result by using the given format string. In 805 * the format string there should be a '%[l]f', '%[l]g' or '%[l]e' marker in 806 * the place where the number should be printed. 807 * <p/> 808 * If an additional '%s' is found AFTER the marker, the value will be 809 * scaled and an appropriate SI magnitude unit will be printed in 810 * place of the '%s' marker. The scaling will take the '--base' argument 811 * into consideration! 812 * <p/> 813 * If a '%S' is used instead of a '%s', then instead of calculating 814 * the appropriate SI magnitude unit for this value, the previously 815 * calculated SI magnitude unit will be used. This is useful if you 816 * want all the values in a print statement to have the same SI magnitude 817 * unit. If there was no previous SI magnitude calculation made, 818 * then '%S' behaves like a '%s', unless the value is 0, in which case 819 * it does not remember a SI magnitude unit and a SI magnitude unit 820 * will only be calculated when the next '%s' is seen or the next '%S' 821 * for a non-zero value. 822 * <p/> 823 * Print results are collected in the {@link RrdGraphInfo} object which is retrieved 824 * from the {@link RrdGraph object} once the graph is created. 825 * 826 * @param srcName Virtual source name 827 * @param consolFun Consolidation function to be applied to the source 828 * @param format Format string (like "average = %10.3f %s") 829 */ 830 public void print(String srcName, String consolFun, String format) { 831 comments.add(new PrintText(srcName, consolFun, format, false)); 832 } 833 834 /** 835 * This method does basically the same thing as {@link #print(String, String, String)}, 836 * but the result is printed on the graph itself, below the chart area. 837 * 838 * @param srcName Virtual source name 839 * @param consolFun Consolidation function to be applied to the source 840 * @param format Format string (like "average = %10.3f %s") 841 */ 842 public void gprint(String srcName, String consolFun, String format) { 843 comments.add(new PrintText(srcName, consolFun, format, true)); 844 } 845 846 /** 847 * Comment to be printed on the graph. 848 * 849 * @param text Comment text 850 */ 851 public void comment(String text) { 852 comments.add(new CommentText(text)); 853 } 854 855 /** 856 * Draws a horizontal rule into the graph and optionally adds a legend 857 * 858 * @param value Position of the rule 859 * @param color Rule color 860 * @param legend Legend text. If null, legend text will be omitted. 861 */ 862 public void hrule(double value, Paint color, String legend) { 863 hrule(value, color, legend, 1.0F); 864 } 865 866 /** 867 * Draws a horizontal rule into the graph and optionally adds a legend 868 * 869 * @param value Position of the rule 870 * @param color Rule color 871 * @param legend Legend text. If null, legend text will be omitted. 872 * @param width Rule width 873 */ 874 public void hrule(double value, Paint color, String legend, float width) { 875 LegendText legendText = new LegendText(color, legend); 876 comments.add(legendText); 877 plotElements.add(new HRule(value, color, legendText, width)); 878 } 879 880 /** 881 * Draws a vertical rule into the graph and optionally adds a legend 882 * 883 * @param timestamp Position of the rule (seconds since epoch) 884 * @param color Rule color 885 * @param legend Legend text. Use null to omit the text. 886 */ 887 public void vrule(long timestamp, Paint color, String legend) { 888 vrule(timestamp, color, legend, 1.0F); 889 } 890 891 /** 892 * Draws a vertical rule into the graph and optionally adds a legend 893 * 894 * @param timestamp Position of the rule (seconds since epoch) 895 * @param color Rule color 896 * @param legend Legend text. Use null to omit the text. 897 * @param width Rule width 898 */ 899 public void vrule(long timestamp, Paint color, String legend, float width) { 900 LegendText legendText = new LegendText(color, legend); 901 comments.add(legendText); 902 plotElements.add(new VRule(timestamp, color, legendText, width)); 903 } 904 905 /** 906 * Plots requested data as a line, using the color and the line width specified. 907 * 908 * @param srcName Virtual source name 909 * @param color Line color 910 * @param legend Legend text 911 * @param width Line width (default: 1.0F) 912 */ 913 public void line(String srcName, Paint color, String legend, float width) { 914 LegendText legendText = new LegendText(color, legend); 915 comments.add(legendText); 916 plotElements.add(new Line(srcName, color, width)); 917 } 918 919 /** 920 * Plots requested data as a line, using the color specified. Line width is assumed to be 921 * 1.0F. 922 * 923 * @param srcName Virtual source name 924 * @param color Line color 925 * @param legend Legend text 926 */ 927 public void line(String srcName, Paint color, String legend) { 928 line(srcName, color, legend, 1F); 929 } 930 931 /** 932 * Plots requested data in the form of the filled area starting from zero, 933 * using the color specified. 934 * 935 * @param srcName 936 * Virtual source name. 937 * @param color 938 * Color of the filled area. 939 * @param legend 940 * Legend text. 941 */ 942 public void area(String srcName, Paint color, String legend) { 943 area(srcName, color); 944 if (legend.length() > 0) { 945 LegendText legendText = new LegendText(color, legend); 946 comments.add(legendText); 947 } 948 } 949 950 /** 951 * Plots requested data in the form of the filled area starting from zero, 952 * using the color specified. 953 * 954 * @param srcName 955 * Virtual source name. 956 * @param color 957 * Color of the filled area. 958 */ 959 public void area(String srcName, Paint color) { 960 plotElements.add(new Area(srcName, color)); 961 } 962 963 /** 964 * Does the same as {@link #line(String, java.awt.Paint, String)}, 965 * but the graph gets stacked on top of the 966 * previous LINE, AREA or STACK graph. Depending on the type of the 967 * previous graph, the STACK will be either a LINE or an AREA. This 968 * obviously implies that the first STACK must be preceded by an AREA 969 * or LINE. 970 * <p/> 971 * Note, that when you STACK onto *UNKNOWN* data, JRobin will not 972 * draw any graphics ... *UNKNOWN* is not zero. 973 * 974 * @param srcName Virtual source name 975 * @param color Stacked graph color 976 * @param legend Legend text 977 * @throws RrdException Thrown if this STACK has no previously defined AREA, STACK or LINE 978 * graph bellow it. 979 */ 980 public void stack(String srcName, Paint color, String legend) throws RrdException { 981 // find parent AREA or LINE 982 SourcedPlotElement parent = null; 983 for (int i = plotElements.size() - 1; i >= 0; i--) { 984 PlotElement plotElement = plotElements.get(i); 985 if (plotElement instanceof SourcedPlotElement) { 986 parent = (SourcedPlotElement) plotElement; 987 break; 988 } 989 } 990 if (parent == null) { 991 throw new RrdException("You have to stack graph onto something (line or area)"); 992 } 993 else { 994 LegendText legendText = new LegendText(color, legend); 995 comments.add(legendText); 996 plotElements.add(new Stack(parent, srcName, color)); 997 } 998 } 999 1000 /** 1001 * Sets visibility of the X-axis grid. 1002 * 1003 * @param drawXGrid True if X-axis grid should be created (default), false otherwise. 1004 */ 1005 public void setDrawXGrid(boolean drawXGrid) { 1006 this.drawXGrid = drawXGrid; 1007 } 1008 1009 /** 1010 * Sets visibility of the Y-axis grid. 1011 * 1012 * @param drawYGrid True if Y-axis grid should be created (default), false otherwise. 1013 */ 1014 public void setDrawYGrid(boolean drawYGrid) { 1015 this.drawYGrid = drawYGrid; 1016 } 1017 1018 /** 1019 * Sets image quality. Relevant only for JPEG images. 1020 * 1021 * @param imageQuality (0F=worst, 1F=best). 1022 */ 1023 public void setImageQuality(float imageQuality) { 1024 this.imageQuality = imageQuality; 1025 } 1026 1027 /** 1028 * Controls if the chart area of the image should be antialiased or not. 1029 * 1030 * @param antiAliasing use true to turn antialiasing on, false to turn it off (default) 1031 */ 1032 public void setAntiAliasing(boolean antiAliasing) { 1033 this.antiAliasing = antiAliasing; 1034 } 1035 1036 /** 1037 * Shows or hides graph signature (gator) in the top right corner of the graph 1038 * 1039 * @param showSignature true, if signature should be seen (default), false otherwise 1040 */ 1041 public void setShowSignature(boolean showSignature) { 1042 this.showSignature = showSignature; 1043 } 1044 1045 /** 1046 * Sets first day of the week. 1047 * 1048 * @param firstDayOfWeek One of the following constants: 1049 * {@link RrdGraphConstants#MONDAY MONDAY}, 1050 * {@link RrdGraphConstants#TUESDAY TUESDAY}, 1051 * {@link RrdGraphConstants#WEDNESDAY WEDNESDAY}, 1052 * {@link RrdGraphConstants#THURSDAY THURSDAY}, 1053 * {@link RrdGraphConstants#FRIDAY FRIDAY}, 1054 * {@link RrdGraphConstants#SATURDAY SATURDAY}, 1055 * {@link RrdGraphConstants#SUNDAY SUNDAY} 1056 */ 1057 public void setFirstDayOfWeek(int firstDayOfWeek) { 1058 this.firstDayOfWeek = firstDayOfWeek; 1059 } 1060 1061 // helper methods 1062 1063 int printStatementCount() { 1064 int count = 0; 1065 for (CommentText comment : comments) { 1066 if (comment instanceof PrintText) { 1067 if (comment.isPrint()) { 1068 count++; 1069 } 1070 } 1071 } 1072 return count; 1073 } 1074 1075 boolean shouldPlot() { 1076 if (plotElements.size() > 0) { 1077 return true; 1078 } 1079 for (CommentText comment : comments) { 1080 if (comment.isValidGraphElement()) { 1081 return true; 1082 } 1083 } 1084 return false; 1085 } 1086 }