Update of /cvsroot/jrobin/src/jrobin/graph2 In directory sc8-pr-cvs1:/tmp/cvs-serv2871/src/jrobin/graph2 Added Files: FetchSource.java RpnCalculator.java ValueAxisUnit.java Title.java Area.java ChartGraphics.java RrdGraphDef.java Gprint.java RrdGraph.java Comment.java Cdef.java Source.java GridRange.java TimeMarker.java ValueScaler.java Stack.java TimeAxisUnit.java Legend.java ValueMarker.java ValueExtractor.java LegendMarker.java Grapher.java Def.java PlotDef.java ValueFormatter.java Log Message: Experimental graph2 package major update, but very unfinished --- NEW FILE: FetchSource.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...) * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * (C) Copyright 2003, by Sasa Markovic. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package jrobin.graph2; import java.util.Vector; import java.io.IOException; import jrobin.core.RrdDb; import jrobin.core.FetchPoint; import jrobin.core.FetchRequest; import jrobin.core.RrdException; /** * <p>Class used to group datasources per RRD db, for faster fetching.</p> * * @author Arne Vandamme (arn...@jr...) */ class FetchSource { static final int AVG = 0; static final int MAX = 1; static final int MIN = 2; static final int LAST = 3; static final int MAX_CF = 4; static final String[] cfNames = new String[] { "AVERAGE", "MAX", "MIN", "LAST" }; private String rrdFile; // Holds the name of the RRD file private int numSources = 0; private Vector[] datasources = new Vector[MAX_CF]; FetchSource( String rrdFile ) { this.rrdFile = rrdFile; // Initialization for (int i = 0; i < datasources.length; i++) datasources[i] = new Vector(); } FetchSource( String rrdFile, String consolFunc, String dsName, String name ) throws RrdException { this( rrdFile ); addSource( consolFunc, dsName, name ); } void addSource( String consolFunc, String dsName, String name ) throws RrdException { if ( consolFunc.equalsIgnoreCase("AVERAGE") || consolFunc.equalsIgnoreCase("AVG") ) datasources[AVG].add( new String[] { dsName, name } ); else if ( consolFunc.equalsIgnoreCase("MAX") || consolFunc.equalsIgnoreCase("MAXIMUM") ) datasources[MAX].add( new String[] { dsName, name } ); else if ( consolFunc.equalsIgnoreCase("MIN") || consolFunc.equalsIgnoreCase("MINIMUM") ) datasources[MIN].add( new String[] { dsName, name } ); else if ( consolFunc.equalsIgnoreCase("LAST") ) datasources[LAST].add( new String[] { dsName, name } ); else throw new RrdException( "Invalid consolidation function specified." ); numSources++; } String getRrdFile() { return rrdFile; } ValueExtractor fetch( RrdDb rrd, long startTime, long endTime ) throws IOException, RrdException { long rrdStep = rrd.getRrdDef().getStep(); FetchPoint[][] result = new FetchPoint[datasources.length][]; int[][] indices = new int[MAX_CF][]; for (int i = 0; i < datasources.length; i++) { if ( datasources[i].size() > 0 ) { // Fetch datasources FetchRequest request = rrd.createFetchRequest( cfNames[i], startTime, endTime + rrdStep); FetchPoint[] fetchPoints = request.fetch(); result[i] = fetchPoints; indices[i] = new int[datasources[i].size()]; } else indices[i] = new int[0]; } String[] names = new String[numSources]; int tblPos = 0; for (int i = 0; i < datasources.length; i++) { for (int j = 0; j < datasources[i].size(); j++) { String[] spair = (String[])datasources[i].elementAt(j); indices[i][j] = rrd.getDsIndex(spair[0]); names[tblPos++] = spair[1]; } } return new ValueExtractor( names, indices, result ); } } --- NEW FILE: RpnCalculator.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...) * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * (C) Copyright 2003, by Sasa Markovic. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package jrobin.graph2; import java.util.ArrayList; import jrobin.core.Util; import jrobin.core.RrdException; /** * <p>Used to calculate result of an RPN expression.</p> * * @author Arne Vandamme (arn...@jr...) * @author Sasa Markovic (sa...@jr...) */ public class RpnCalculator { // Token definitions public static final byte TKN_CONSTANT = 0; public static final byte TKN_DATASOURCE = 1; public static final byte TKN_PLUS = 2; public static final byte TKN_MINUS = 3; public static final byte TKN_MULTIPLY = 4; public static final byte TKN_DIVIDE = 5; public static final byte TKN_MOD = 6; public static final byte TKN_SIN = 7; public static final byte TKN_COS = 8; public static final byte TKN_LOG = 9; public static final byte TKN_EXP = 10; public static final byte TKN_FLOOR = 11; public static final byte TKN_CEIL = 12; public static final byte TKN_ROUND = 13; public static final byte TKN_POW = 14; public static final byte TKN_ABS = 15; public static final byte TKN_SQRT = 16; public static final byte TKN_RANDOM = 17; public static final byte TKN_LT = 18; public static final byte TKN_LE = 19; public static final byte TKN_GT = 20; public static final byte TKN_GE = 21; public static final byte TKN_EQ = 22; public static final byte TKN_IF = 23; public static final byte TKN_MIN = 24; public static final byte TKN_MAX = 25; public static final byte TKN_LIMIT = 26; public static final byte TKN_DUP = 27; public static final byte TKN_EXC = 28; public static final byte TKN_POP = 29; public static final byte TKN_UN = 30; public static final byte TKN_UNKN = 31; public static final byte TKN_NOW = 32; public static final byte TKN_TIME = 33; public static final byte TKN_PI = 34; public static final byte TKN_E = 35; public static final byte TKN_AND = 36; public static final byte TKN_OR = 37; public static final byte TKN_XOR = 38; private Source[] sources; ArrayList stack = new ArrayList(); RpnCalculator( Source[] sources ) { this.sources = sources; } double evaluate( Cdef cdef, int row, long timestamp ) throws RrdException { stack.clear(); byte[] tokens = cdef.tokens; int[] dsIndices = cdef.dsIndices; double[] constants = cdef.constants; double x1, x2, x3; for ( int i = 0; i < tokens.length; i++ ) { switch ( tokens[i] ) { case TKN_CONSTANT: push( constants[i] ); break; case TKN_DATASOURCE: push( sources[ dsIndices[i] ].get(row) ); break; case TKN_PLUS: push(pop() + pop()); break; case TKN_MINUS: x2 = pop(); x1 = pop(); push(x1 - x2); break; case TKN_MULTIPLY: push(pop() * pop()); break; case TKN_DIVIDE: x2 = pop(); x1 = pop(); push(x1 / x2); break; case TKN_MOD: x2 = pop(); x1 = pop(); push(x1 % x2); break; case TKN_SIN: push(Math.sin(pop())); break; case TKN_COS: push(Math.cos(pop())); break; case TKN_LOG: push(Math.log(pop())); break; case TKN_EXP: push(Math.exp(pop())); break; case TKN_FLOOR: push(Math.floor(pop())); break; case TKN_CEIL: push(Math.ceil(pop())); break; case TKN_ROUND: push(Math.round(pop())); break; case TKN_POW: x2 = pop(); x1 = pop(); push(Math.pow(x1, x2)); break; case TKN_ABS: push(Math.abs(pop())); break; case TKN_SQRT: push(Math.sqrt(pop())); break; case TKN_RANDOM: push(Math.random()); break; case TKN_LT: x2 = pop(); x1 = pop(); push(x1 < x2? 1: 0); break; case TKN_LE: x2 = pop(); x1 = pop(); push(x1 <= x2? 1: 0); break; case TKN_GT: x2 = pop(); x1 = pop(); push(x1 > x2? 1: 0); break; case TKN_GE: x2 = pop(); x1 = pop(); push(x1 >= x2? 1: 0); break; case TKN_EQ: x2 = pop(); x1 = pop(); push(x1 == x2? 1: 0); break; case TKN_IF: x3 = pop(); x2 = pop(); x1 = pop(); push(x1 != 0 ? x2: x3); break; case TKN_MIN: push(Math.min(pop(), pop())); break; case TKN_MAX: push(Math.max(pop(), pop())); break; case TKN_LIMIT: double high = pop(), low = pop(), value = pop(); push(value < low || value > high? Double.NaN: value); break; case TKN_DUP: double x = pop(); push(x); push(x); break; case TKN_EXC: x2 = pop(); x1 = pop(); push(x2); push(x1); break; case TKN_POP: pop(); break; case TKN_UN: push(Double.isNaN(pop())? 1: 0); break; case TKN_UNKN: push(Double.NaN); break; case TKN_NOW: push(Util.getTime()); break; case TKN_TIME: push(timestamp); break; case TKN_PI: push(Math.PI); break; case TKN_E: push(Math.E); break; case TKN_AND: x2 = pop(); x1 = pop(); push((x1 != 0 && x2 != 0)? 1: 0); break; case TKN_OR: x2 = pop(); x1 = pop(); push((x1 != 0 || x2 != 0)? 1: 0); break; case TKN_XOR: x2 = pop(); x1 = pop(); push(((x1 != 0 && x2 == 0) || (x1 == 0 && x2 != 0))? 1: 0); break; } } if (stack.size() != 1) throw new RrdException("RPN error, invalid stack length"); return pop(); } private void push( double value ) { stack.add( new Double(value) ); } private double pop() throws RrdException { int last = stack.size() - 1; if ( last < 0 ) throw new RrdException("POP failed, stack empty"); Double lastValue = (Double) stack.get(last); stack.remove(last); return lastValue.doubleValue(); } } --- NEW FILE: ValueAxisUnit.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.sourceforge.net/projects/jrobin * Project Lead: Sasa Markovic (sa...@eu...); * * (C) Copyright 2003, by Sasa Markovic. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ /* * Created on 29-aug-2003 * * To change the template for this generated file go to * Window - Preferences - Java - Code Generation - Code and Comments */ package jrobin.graph2; import java.util.*; /** * @author cbld * * To change the template for this generated type comment go to * Window - Preferences - Java - Code Generation - Code and Comments */ public class ValueAxisUnit { private double labelStep = 2; private double markStep = 1; private int roundStep = 2; private int gridUnit = 1; // minor grid private double gridParts = 2d; private int mGridUnit = 10; // major grid private double mGridParts = 1d; private double gridStep = 2; private double mGridStep = 10; ValueAxisUnit( double labelStep, double markStep, int roundStep ) { this.labelStep = labelStep; this.markStep = markStep; this.roundStep = roundStep; } ValueAxisUnit( int gridUnit, double gridParts, int mGridUnit, double mGridParts ) { this.gridUnit = gridUnit; this.gridParts = gridParts; this.mGridUnit = mGridUnit; this.mGridParts = mGridParts; gridStep = gridUnit * gridParts; mGridStep = mGridUnit * mGridParts; } private double round( double value ) { return round( value, 14 ); // Big precision } private double round( double value, int numDecs ) { return new java.math.BigDecimal(value).setScale(numDecs , java.math.BigDecimal.ROUND_HALF_EVEN).doubleValue(); } public ValueMarker[] getValueMarkers( double lower, double upper, double base, int scaleIndex ) { double minPoint = 0.0d; double majPoint = 0.0d; // Find the first visible gridpoint if ( lower > 0 ) { while ( minPoint < lower ) minPoint += gridStep; while ( majPoint < lower ) majPoint += mGridStep; } else { while ( minPoint > lower ) minPoint -= gridStep; while ( majPoint > lower ) majPoint -= mGridStep; // Go one up to make it visible if (minPoint != lower ) minPoint += gridStep; if (majPoint != lower ) majPoint += mGridStep; } // Now get all time markers. // Again we choose to use a series of loops as to avoid unnecessary drawing. ArrayList markerList = new ArrayList(); while ( minPoint <= upper && majPoint <= upper ) { if ( minPoint < majPoint ) { markerList.add( new ValueMarker(minPoint, "", false) ); minPoint = round( minPoint + gridStep ); } else { String str; ValueScaler vs = new ValueScaler( majPoint, scaleIndex, base); int ival = new Double(vs.getScaledValue()).intValue(); if ( ival == vs.getScaledValue() ) str = (ival + vs.getPrefix()).trim(); else str = (round(vs.getScaledValue(), 2) + vs.getPrefix()).trim(); if ( minPoint == majPoint ) // Special case, but will happen most of the time { markerList.add( new ValueMarker(majPoint, str, true) ); minPoint = round( minPoint + gridStep ); majPoint = round( majPoint + mGridStep ); } else { markerList.add( new ValueMarker(majPoint, str, true) ); majPoint = round( majPoint + mGridStep ); } } } while ( minPoint <= upper ) { markerList.add( new ValueMarker(minPoint, "", false) ); minPoint = round( minPoint + gridStep ); } while ( majPoint <= upper ) { String str; ValueScaler vs = new ValueScaler( majPoint, scaleIndex, base); int ival = new Double(vs.getScaledValue()).intValue(); if ( ival == vs.getScaledValue() ) str = (ival + vs.getPrefix()).trim(); else str = (vs.getScaledValue() + vs.getPrefix()).trim(); markerList.add( new ValueMarker(majPoint, str, true) ); majPoint = round( majPoint + mGridStep ); } return (ValueMarker[]) markerList.toArray( new ValueMarker[0] ); } public double getNiceLower( double ovalue ) { // Add some checks double gridParts = this.gridParts; double mGridParts = this.mGridParts; double gridFactor = 1.0; double mGridFactor = 1.0; if ( gridUnit * gridParts < 1.0 ) { gridParts *= 100; gridFactor = 100; } if ( mGridUnit * mGridParts < 1.0 ) { mGridParts *= 100; mGridFactor = 100; } double value = ovalue * gridFactor; int valueInt = new Double(value).intValue(); int roundStep = new Double(gridUnit * gridParts).intValue(); if ( roundStep == 0 ) roundStep = 1; int num = valueInt / roundStep; int mod = valueInt % roundStep; double gridValue = (roundStep * num) * 1.0d; if ( gridValue > value ) gridValue -= roundStep; if ( num == 0 && value >= 0 ) gridValue = 0.0; else if ( Math.abs(gridValue - value) < (gridParts * gridUnit) / 16 ) gridValue -= roundStep; value = ovalue * mGridFactor; roundStep = new Double(mGridUnit * mGridParts).intValue(); if ( roundStep == 0 ) roundStep = 1; num = valueInt / roundStep; mod = valueInt % roundStep; double mGridValue = (roundStep * num) * 1.0d; if ( mGridValue > value ) mGridValue -= roundStep; if ( value != 0.0d ) { if ( Math.abs(mGridValue - gridValue) < (mGridParts * mGridUnit) / 2) return mGridValue / mGridFactor; else return gridValue / gridFactor; } return ovalue; } public double getNiceHigher( double ovalue ) { // Add some checks double gridParts = this.gridParts; double mGridParts = this.mGridParts; double gridFactor = 1.0; double mGridFactor = 1.0; if ( gridUnit * gridParts < 1.0 ) { gridParts *= 100; gridFactor = 100; } if ( mGridUnit * mGridParts < 1.0 ) { mGridParts *= 100; mGridFactor = 100; } double value = ovalue * gridFactor; int valueInt = new Double(value).intValue(); int roundStep = new Double(gridUnit * gridParts).intValue(); if ( roundStep == 0 ) roundStep = 1; int num = valueInt / roundStep; int mod = valueInt % roundStep; double gridValue = (roundStep * (num + 1)) * 1.0d; if ( gridValue - value < (gridParts * gridUnit) / 8 ) gridValue += roundStep; value = ovalue * mGridFactor; roundStep = new Double(mGridUnit * mGridParts).intValue(); if ( roundStep == 0 ) roundStep = 1; num = valueInt / roundStep; mod = valueInt % roundStep; double mGridValue = (roundStep * (num + 1)) * 1.0d; if ( value != 0.0d ) { if ( Math.abs(mGridValue - gridValue) < (mGridParts * mGridUnit) / 2) return mGridValue / mGridFactor; else return gridValue / gridFactor; } return ovalue; } } --- NEW FILE: Title.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...) * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * (C) Copyright 2003, by Sasa Markovic. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package jrobin.graph2; import jrobin.core.RrdException; /** * <p>description</p> * * @author Arne Vandamme (arn...@jr...) * @author Sasa Markovic (sa...@jr...) */ class Title extends Comment { Title( String text ) throws RrdException { this.text = text; lfToken = Comment.TKN_ACF; super.parseComment(); } } --- NEW FILE: Area.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...) * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * (C) Copyright 2003, by Sasa Markovic. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package jrobin.graph2; import java.awt.Color; /** * <p>description</p> * * @author Arne Vandamme (arn...@jr...) */ class Area extends PlotDef { Area( String sourceName, Color c ) { super( sourceName, c ); this.plotType = PlotDef.PLOT_AREA; } Area( Source source, Color c, boolean stacked ) { super( source, c, stacked ); } void draw( ChartGraphics g, int[] xValues, int[] stackValues, int lastPlotType ) { g.setColor( color ); int ax = 0, ay = 0, py; int nx = 0, ny = 0, last = -1; for (int i = 0; i < xValues.length; i++) { py = 0; nx = xValues[i]; ny = g.getY( source.values[i] ); if ( stacked ) { py = stackValues[i]; ny += stackValues[i]; } if (nx > ax + 1) // More than one pixel hop, draw intermediate pixels too { // For each pixel between nx and ax, calculate the y, plot the line int co = (ny - ay) / (nx - ax); int j = (ax > 0 ? ax : 1 ); // Skip 0 for (j = ax; j <= nx; j++) g.drawLine( j, py, j, ( co * (j - ax) + ay) ); } else if ( nx != 0 && py != Integer.MIN_VALUE && ny != Integer.MIN_VALUE ) g.drawLine( nx, py, nx, ny ); stackValues[i] = ny; ax = nx; ay = ny; } } } --- NEW FILE: ChartGraphics.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...) * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * (C) Copyright 2003, by Sasa Markovic. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package jrobin.graph2; import java.awt.Color; import java.awt.Stroke; import java.awt.Graphics2D; /** * <p>description</p> * * @author Arne Vandamme (arn...@jr...) */ public class ChartGraphics { Graphics2D g; private int width, height; private long xStart, xEnd; private double yStart, yEnd; double widthDelta = 1.0d, heightDelta = 3.0d; ChartGraphics( Graphics2D graphics ) { g = graphics; } void drawLine(int x1, int y1, int x2, int y2) { g.drawLine( x1, -y1, x2, -y2 ); } // Contrary to Graphics2D fillRect, this method uses boundary points void fillRect(int x1, int y1, int x2, int y2) { g.fillRect( x1, -y2, x2 - x1, y2 - y1 ); } void setColor( Color c ) { g.setColor( c ); } void setMeasurements( int width, int height ) { this.width = width; this.height = height; } void setXRange( long start, long end ) { xStart = start; xEnd = end; if ( xEnd != xStart ) widthDelta = width * 1.0d / (( xEnd - xStart) * 1.0d); else widthDelta = 1.0d; } void setYRange( double lower, double upper ) { yStart = lower; yEnd = upper; if ( yEnd != yStart ) heightDelta = height * 1.0d / (( yEnd - yStart) * 1.0d); else heightDelta = 1.0d; } int getX( long timestamp ) { return new Double((timestamp - xStart) * widthDelta).intValue(); } int getY( double value ) { if ( Double.isNaN(value) ) return Integer.MIN_VALUE; int tmp = new Double( (value - ( yStart < 0 ? 0 : Math.abs(yStart) ) ) * heightDelta).intValue(); return ( tmp > value * heightDelta ? tmp - 1 : tmp ); } void setStroke( Stroke s ) { g.setStroke( s ); } } --- NEW FILE: RrdGraphDef.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...) * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * (C) Copyright 2003, by Sasa Markovic. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package jrobin.graph2; import java.io.File; import java.io.Serializable; import java.awt.Font; import java.awt.Color; import java.awt.BasicStroke; import java.util.Date; import java.util.Vector; import java.util.HashMap; import java.util.GregorianCalendar; import jrobin.core.Util; import jrobin.core.RrdException; /** * <p>Class used to collect information for the new JRobin graph. JRobin graphs have many * options and this class has methods and properties to set them.</p> * * <p>At this moment, JRobin graphs are quite good looking, but RRDTool is still better. * However, JRobin graphs have almost the same potential as RRDTool's graph command. To learn * more about RRDTool's graphs see RRDTool's * <a href="../../../man/rrdgraph.html" target="man">rrdgraph man page</a>.</p> This man page * is important: JRobin uses the same concept of graph sources definition (DEF directives) * and supports RPN extensions in complex datasource definitions (RRDTool's CDEF directives).</p> * * <p><code>RrdGraphDef</code> class does not actually create any graph. It just collects necessary information. * Graph will be created when you pass <code>RrdGraphDef</code> object to the constructor * of {@link jrobin.graph.RrdGraph RrdGraph} object.</p> * * @author Arne Vandamme (arn...@jr...) * @author Sasa Markovic (sa...@jr...) */ public class RrdGraphDef implements Serializable { // ================================================================ // -- Members // ================================================================ long endTime = Util.getTime(); // default time spam of the last 24 hours long startTime = Util.getTime() - 86400L; Title title = null; // no title String valueAxisLabel = null; // no vertical label boolean gridX = true; // hide entire X axis grid (default: no) boolean gridY = true; // hide entire Y axis grid (default: no) boolean minorGridX = true; // hide minor X axis grid (default: no) boolean minorGridY = true; // hide minor Y axis grid (default: no) boolean majorGridX = true; // hide major X axis grid with labels (default: no) boolean majorGridY = true; // hide major Y axis grid with labels (default: no) boolean rigidGrid = false; // disable auto scaling of grid range (default: no) boolean frontGrid = true; // show grid in front of the chart (default: yes) boolean antiAliasing = true; // use anti-aliasing for the chart (default: yes) boolean showLegend = true; // show legend and comments (default: yes) Color backColor = new Color( 245, 245, 245 ); // variation of light gray Color canvasColor = Color.WHITE; // white Color borderColor = Color.LIGHT_GRAY; // light gray, only applicable with a borderStroke Color normalFontColor = Color.BLACK; // black Color titleFontColor = Color.BLACK; // black Color majorGridColor = new Color(130,30,30); // variation of dark red Color minorGridColor = new Color(140,140,140); // variation of gray Color axisColor = new Color(130,30,30); // variation of dark red Color arrowColor = Color.RED; // red Color frameColor = Color.LIGHT_GRAY; // light gray Font titleFont = null; // use default 'grapher' font Font normalFont = null; // use default 'grapher' font File background = null; // no background image by default File overlay = null; // no overlay image by default int chart_lpadding = Grapher.CHART_LPADDING; BasicStroke borderStroke = null; // defaults to standard beveled border double baseValue = 1000; int scaleIndex = -1; // NO_SCALE GridRange gridRange = null; int numDefs = 0; int commentLines = 0; int commentLineShift = 0; HashMap fetchSources = new HashMap(); Vector cdefList = new Vector(); Vector plotDefs = new Vector(); Vector comments = new Vector(); // ================================================================ // -- Constructors // ================================================================ /** * Constructs a new JRobin graph object. */ public RrdGraphDef() { // Default constructor } /** * Constructs a new JRobin graph object, with a specified time span to be presented on the graph. * Using timestamps defined as number of seconds since the epoch. * @param startTime Starting timestamp in seconds. * @param endTime Ending timestamp in secons. * @throws RrdException Thrown if invalid parameters are supplied. */ public RrdGraphDef( long startTime, long endTime ) throws RrdException { setTimePeriod( startTime, endTime ); } /** * Constructs a new JRobin graph object, with a specified time span to be presented on the graph. * Time spam defined using <code>java.util.Date</code> objects. * @param start Starting time. * @param end Ending time. * @throws RrdException Thrown in case of invalid parameters. */ public RrdGraphDef( Date start, Date end) throws RrdException { setTimePeriod( start, end ); } /** * Constructs a new JRobin graph object, with a specified time span to be presented on the graph. * Time spam defined using <code>java.util.GregorianCalendar</code> objects. * @param start Starting time. * @param end Ending time. * @throws RrdException Thrown in case of invalid parameters. */ public RrdGraphDef( GregorianCalendar start, GregorianCalendar end ) throws RrdException { setTimePeriod( start, end ); } // ================================================================ // -- Public methods // ================================================================ /** * Sets time span to be presented on the graph using timestamps. * @param startTime Starting timestamp in seconds. * @param endTime Ending timestamp in secons. * @throws RrdException Thrown if invalid parameters are supplied. */ public void setTimePeriod( long startTime, long endTime ) throws RrdException { if ( startTime < 0 || endTime <= startTime ) throw new RrdException( "Invalid graph start/end time: " + startTime + "/" + endTime ); this.startTime = startTime; this.endTime = endTime; } /** * Sets time span to be presented on the graph using <code>java.util.Date</code> objects. * @param start Starting time. * @param end Ending time. * @throws RrdException Thrown in case of invalid parameters. */ public void setTimePeriod( Date start, Date end ) throws RrdException { setTimePeriod( start.getTime() / 1000L, end.getTime() / 1000L ); } /** * Sets time span to be presented on the graph using <code>java.util.GregorianCalendar</code> objects. * @param start Starting time. * @param end Ending time * @throws RrdException Thrown if invalid parameters are supplied. */ public void setTimePeriod( GregorianCalendar start, GregorianCalendar end ) throws RrdException { setTimePeriod( start.getTime(), end.getTime() ); } /** * Sets graph title. * @param title Graph title. */ public void setTitle( String title ) throws RrdException { this.title = new Title( title ); } /** * Sets vertical (value) axis label. * @param valueAxisLabel Axis label. */ public void setVerticalLabel( String valueAxisLabel) { this.valueAxisLabel = valueAxisLabel; } /** * Sets image background color. If not set, back color defaults to a very light gray. * @param backColor Graph background color. */ public void setBackColor( Color backColor ) { this.backColor = backColor; } /** * Sets chart area background color. If not set, back color defaults to white. * @param backColor Chart area background color. */ public void setCanvasColor( Color canvasColor ) { this.canvasColor = canvasColor; } /** * Specifies the settings of the image border. * Default is sort of beveled border around the image. * @param c Bordercolor of the image. * @param w Pixel width of the image border. */ public void setImageBorder( Color c, int w ) { this.borderStroke = new BasicStroke( w ); if ( c != null ) this.borderColor = c; } /** * Sets the color of the title font used in the graph. * @param c The color to be used. */ public void setTitleFontColor( Color c ) { this.titleFontColor = c; } /** * Sets the color of the default font used in the graph. * @param c The color to be used. */ public void setDefaultFontColor( Color c ) { this.normalFontColor = c; } /** * Sets the font to be used for the graph title. * @param f The Font to be used. */ public void setTitleFont( Font f ) { this.titleFont = f; } /** * Sets the default font to be used in the graph. * @param f The Font to be used. */ public void setDefaultFont( Font f ) { this.normalFont = f; } /** * Determines the color of the major grid. * @param c Color to use. */ public void setMajorGridColor( Color c ) { this.majorGridColor = c; } /** * Determines the color of the minor grid. * @param c Color to use. */ public void setMinorGridColor( Color c ) { this.minorGridColor = c; } /** * Determines the color of chart area frame. * @param c Color to use. */ public void setFrameColor( Color c ) { this.frameColor = c; } /** * Determines the color of X axis. * @param c Color to use. */ public void setAxisColor( Color c ) { this.axisColor = c; } /** * Determines the color of the small axis arrow on the X axis. * @param c Color to use. */ public void setArrowColor( Color c ) { this.arrowColor = c; } /** * Determines if the minor grid for the X axis needs to be drawn. * @param visible True if minor grid needs to be drawn, false if not. */ public void setMinorGridX( boolean visible ) { this.minorGridX = visible; } /** * Determines if the minor grid for the Y axis needs to be drawn. * @param visible True if minor grid needs to be drawn, false if not. */ public void setMinorGridY( boolean visible ) { this.minorGridY = visible; } /** * Determines if the major grid with labels for the X axis needs to be drawn. * @param visible True if major grid needs to be drawn, false if not. */ public void setMajorGridX( boolean visible ) { this.majorGridX = visible; } /** * Determines if the major grid width labels for the Y axis needs to be drawn. * @param visible True if major grid needs to be drawn, false if not. */ public void setMajorGridY( boolean visible ) { this.majorGridY = visible; } /** * Determines if the X axis grid should be drawn. * This will not change the left padding of the drawing area. * @param visible True if grid needs to be drawn, false if not. */ public void setGridX( boolean visible ) { this.gridX = visible; } /** * Determines if the Y axis grid should be drawn. * This will not change the bottom padding of the drawing area. * @param visible True if grid needs to be drawn, false if not. */ public void setGridY( boolean visible ) { this.gridY = visible; } /** * Determines if the grid should have rigid upper and lower limits. * If so the upper and lower limit will not autoscale depending on the * graph values. Default uses grid autoscaling. * @param rigid True if the grid should have rigid limits. */ public void setRigidGrid( boolean rigid ) { this.rigidGrid = rigid; } /** * Determine if the graph grid is in front of the graphs itself, or behind it. * Default is in front of the graph itself. * @param frontGrid True if the grid is in front of the graphs. */ public void setFrontGrid( boolean frontGrid ) { this.frontGrid = frontGrid; } /** * Determine if the legend should be visible or not, default: visible. * @param showLegend True if the legend is visible. */ public void setShowLegend( boolean showLegend ) { this.showLegend = showLegend; } /** * Set the anti-aliasing option for the drawing area of the graph. * Default uses anti-aliasing. * @param aa True if anti-aliasing is on, false if off */ public void setAntiAliasing( boolean aa ) { this.antiAliasing = aa; } /** * Set the number of pixels on the left of the canvas area ( value marker space ). * @param lp Number of pixels used, defaults to 50. */ public void setChartLeftPadding( int lp ) { this.chart_lpadding = lp; } /** * <p>Adds simple graph source to graph definition. Graph source <code>name</code> * can be used:</p> * <ul> * <li>To specify sources for line, area and stack plots. * <li>To define complex graph sources * (see {@link #datasource(java.lang.String, java.lang.String) complex graph * source definition}). * <li>To specify graph data source for the * {@link #gprint(java.lang.String, java.lang.String, java.lang.String) gprint()} method. * @param name Graph source name. * @param file Path to RRD file. * @param dsName Data source name defined in the RRD file. * @param consolFun Consolidation function that will be used to extract data from the RRD * file ("AVERAGE", "MIN", "MAX" or "LAST"). */ public void datasource( String name, String file, String dsName, String consolFunc ) throws RrdException { if ( fetchSources.containsKey(file) ) { FetchSource rf = (FetchSource) fetchSources.get(file); rf.addSource( consolFunc, dsName, name ); } else fetchSources.put( file, new FetchSource(file, consolFunc, dsName, name) ); numDefs++; } /** * <p>Adds complex graph source with the given name to the graph definition. * Complex graph sources are evaluated using the supplied <code>rpn</code> expression. * * <p>Complex graph source <code>name</code> can be used:</p> * <ul> * <li>To specify sources for line, area and stack plots. * <li>To define other complex graph sources. * <li>To specify graph data source for the * {@link #gprint(java.lang.String, java.lang.String, java.lang.String) gprint()} method. * * <p>JRobin supports the following RPN functions, operators and constants: +, -, *, /, * %, SIN, COS, LOG, EXP, FLOOR, CEIL, ROUND, POW, ABS, SQRT, RANDOM, LT, LE, GT, GE, EQ, * IF, MIN, MAX, LIMIT, DUP, EXC, POP, UN, UNKN, NOW, TIME, PI and E. JRobin does not * force you to specify at least one simple graph source name as RRDTool.</p> * * <p>For more details on RPN see RRDTool's * <a href="../../../man/rrdgraph.html" target="man">rrdgraph man page</a>.</p> * @param name Graph source name. * @param rpn RPN expression containig comma delmited simple and complex graph * source names, RPN constants, functions and operators. */ public void datasource( String name, String rpn ) { cdefList.add( new Cdef(name, rpn) ); } /** * Adds line plot to the graph definition, using the specified color and legend. This method * takes exactly the same parameters as RRDTool's LINE1 directive (line width * is set to 1). There is only * one limitation: so far, legends in JRobin graphs are always centered (don't * try to specify alignment in the legend string). * * @param sourceName Graph source name. * @param color Line collor to be used. * @param legend Legend to be printed on the graph. * @throws RrdException Thrown if invalid graph source name is supplied. */ public void line( String sourceName, Color color, String legend ) throws RrdException { plotDefs.add( new PlotDef(sourceName, color) ); addLegend( legend, color ); } /** * Adds line plot to the graph definition, using the specified color, legend and line width. * This method takes exactly the same parameters as RRDTool's LINE directive. There is only * one limitation: so far, legends in JRobin graphs are always centered (don't * try to specify alignment in the legend string). * * @param sourceName Graph source name. * @param color Line collor to be used. * @param legend Legend to be printed on the graph. * @throws RrdException Thrown if invalid graph source name is supplied. */ public void line( String sourceName, Color color, String legend, int lineWidth ) throws RrdException { plotDefs.add( new PlotDef(sourceName, color, lineWidth) ); addLegend( legend, color ); } /** * Adds area plot to the graph definition, * using the specified color and legend. This method * takes exactly the same parameters as RRDTool's AREA directive. There is only * one limitation: so far, legends in JRobin graphs are always centered (don't * try to specify alignment in the legend string). * * @param sourceName Graph source name. * @param color Filling collor to be used for area plot. * @param legend Legend to be printed on the graph. * @throws RrdException Thrown if invalid graph source name is supplied. */ public void area( String sourceName, Color color, String legend ) throws RrdException { plotDefs.add( new Area(sourceName, color) ); addLegend( legend, color ); } /** * Adds stacked plot to the graph definition, * using the specified color and legend. This method * takes exactly the same parameters as RRDTool's STACK directive. There is only * one limitation: so far, legends in JRobin graphs are always centered (don't * try to specify alignment in the legend string). * * @param sourceName Graph source name. * @param color Collor to be used. * @param legend Legend to be printed on the graph. * @throws RrdException Thrown if invalid graph source name is supplied. */ public void stack( String sourceName, Color color, String legend ) throws RrdException { plotDefs.add( new Stack(sourceName, color) ); addLegend( legend, color ); } /** * Adds comment to the graph definition. Comments will be left, center or right aligned * if the comment ends with <code>@l</code>, <code>@c</code> or <code>@r</code>, * respectively. * @param text Comment * @throws RrdException Thrown in case of JRobin specific error. */ public void comment(String text) throws RrdException { addComment( new Comment(text) ); } /** * <p>Calculate the chosen consolidation function <code>consolFun</code> over * the graph <code>sourceName</code> and prints the result * on the graph using the specified <code>format</code> string.</p> * * <p>In the format string there should be a * <code>@n</code> marker (replace <code>n</code> with the desired number of decimals) * in the place where the number should be printed. If an additional <code>@s</code> is * found in the format, the value will be scaled and an appropriate SI magnitude * unit will be printed in place of the <code>@s</code> marker. If you specify * <code>@S</code> instead of <code>@s</code>, the value will be scaled with the scale * factor used in the last gprint directive (uniform value scaling).</p> * * <p>The text printed on the graph will be left, center or right aligned * if the format string ends with <code>@l</code>, <code>@c</code> or <code>@r</code>, * respectively.</p> * * @param sourceName Graph source name * @param consolFun Consolidation function to be used for calculation ("AVERAGE", * "MIN", "MAX" or "LAST") * @param format Format string. For example: "speed is @2 @sbits/sec@c", * "temperature = @0 degrees" * @throws RrdException Thrown in case of JRobin specific error */ public void gprint(String sourceName, String consolFun, String format) throws RrdException { addComment( new Gprint(sourceName, consolFun, format) ); } /** * Sets a background image to use for the graph. * The image can be any of the supported imageio formats, * default <i>.gif, .jpg or .png</i>. * @param fileName Filename of the image to use */ public void setBackground( String fileName ) { File bgFile = new File( fileName ); if ( bgFile.exists() ) this.background = bgFile; } /** * Sets a overlay image to use for the graph. * The image can be any of the supported imageio formats, * default <i>.gif, .jpg or .png</i>. All pixels with the color white * RGB (255, 255, 255) will be treated as transparent. * @param fileName Filename of the image to use */ public void setOverlay( String fileName ) { File ovFile = new File( fileName ); if ( ovFile.exists() ) this.overlay = ovFile; } /** * * @param base */ public void setBaseValue( double base ) { this.baseValue = base; } /** * * @param e */ public void setUnitsExponent( int e ) { this.scaleIndex = (6 - e / 3); // Index in the scale table } /** * Sets value range that will be presented in the graph. If not set, graph will be * autoscaled. * @param lower Lower limit. * @param upper Upper limit. * @param rigid Rigid grid, won't autoscale limits. */ public void setGridRange(double lower, double upper, boolean rigid) { gridRange = new GridRange( lower, upper, rigid ); } // ================================================================ // -- Protected (package) methods // ================================================================ PlotDef[] getPlotDefs() { return (PlotDef[]) plotDefs.toArray( new PlotDef[] {} ); } Comment[] getComments() { return (Comment[]) comments.toArray( new Comment[] {} ); } int getCommentLineCount() { return ( comments.size() > 0 ? commentLines + commentLineShift : 0 ); //return ( comments.size() > 0 ? (commentLines > 0 ? commentLines : 1) : 0 ); } private void addComment( Comment cmt ) { commentLines += cmt.getLineCount(); commentLineShift = (cmt.isCompleteLine() ? 0 : 1); comments.add( cmt ); } private void addLegend( String legend, Color color ) throws RrdException { if ( legend != null ) addComment( new Legend(legend, color) ); } } --- NEW FILE: Gprint.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...) * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * (C) Copyright 2003, by Sasa Markovic. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package jrobin.graph2; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import jrobin.core.RrdException; /** * <p>description</p> * * @author Arne Vandamme (arn...@jr...) */ class Gprint extends Comment { private static final String SCALE_MARKER = "@s"; private static final String UNIFORM_SCALE_MARKER = "@S"; private static final String VALUE_MARKER = "@([0-9]*\\.[0-9]{1}|[0-9]{1}|\\.[0-9]{1})"; private static final Pattern VALUE_PATTERN = Pattern.compile(VALUE_MARKER); private String sourceName; private int aggregate; private int numDec = 3; // Show 3 decimal values by default private int strLen = -1; private boolean normalScale = false; private boolean uniformScale = false; Gprint( String sourceName, String consolFunc, String text ) throws RrdException { this.text = text; checkValuePlacement(); // First see if this GPRINT is valid super.parseComment(); this.commentType = Comment.CMT_GPRINT; this.sourceName = sourceName; if ( consolFunc.equalsIgnoreCase("AVERAGE") || consolFunc.equalsIgnoreCase("AVG") ) aggregate = Source.AGG_AVERAGE; else if ( consolFunc.equalsIgnoreCase("MAX") || consolFunc.equalsIgnoreCase("MAXIMUM") ) aggregate = Source.AGG_MAXIMUM; else if ( consolFunc.equalsIgnoreCase("MIN") || consolFunc.equalsIgnoreCase("MINIMUM") ) aggregate = Source.AGG_MINIMUM; else if ( consolFunc.equalsIgnoreCase("LAST") ) aggregate = Source.AGG_LAST; else if ( consolFunc.equalsIgnoreCase("FIRST") ) aggregate = Source.AGG_FIRST; else throw new RrdException( "Invalid consolidation function specified." ); } void setValue( Source[] sources, HashMap sourceIndex, ValueFormatter vFormat ) throws RrdException { try { double value = sources[ ((Integer) sourceIndex.get(sourceName)).intValue() ].getAggregate( aggregate ); vFormat.setFormat( value, numDec, strLen ); vFormat.setScaling( normalScale, uniformScale ); String valueStr = vFormat.getFormattedValue(); String prefix = vFormat.getPrefix(); // Replace all values for (int i = 0; i < oList.size(); i += 2 ) { String str = (String) oList.elementAt(i); str = str.replaceAll(VALUE_MARKER, valueStr); if ( normalScale ) str = str.replaceAll(SCALE_MARKER, prefix); if ( uniformScale ) str = str.replaceAll(UNIFORM_SCALE_MARKER, prefix); oList.set( i, str ); } } catch (Exception e) { throw new RrdException( "Could not find datasource: " + sourceName ); } } /** * Check value placement by finding placeholder. * Check for uniform or regular scaling. * Check for the number of decimals and the complete value string length. * @throws RrdException */ protected void checkValuePlacement() throws RrdException { Matcher m = VALUE_PATTERN.matcher(text); if ( m.find() ) { normalScale = (text.indexOf(SCALE_MARKER) >= 0); uniformScale = (text.indexOf(UNIFORM_SCALE_MARKER) >= 0); if ( normalScale && uniformScale ) throw new RrdException( "Can't specify normal scaling and uniform scaling at the same time." ); String[] group = m.group(1).split("\\."); strLen = -1; numDec = 0; if ( group.length > 1 ) { if ( group[0].length() > 0 ) { strLen = Integer.parseInt(group[0]); numDec = Integer.parseInt(group[1]); } else numDec = Integer.parseInt(group[1]); } else numDec = Integer.parseInt(group[0]); } else throw new RrdException( "Could not find where to place value. No @ placeholder found." ); } } --- NEW FILE: RrdGraph.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...) * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * (C) Copyright 2003, by Sasa Markovic. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package jrobin.graph2; import javax.swing.JPanel; import java.util.ArrayList; import java.io.File; import java.io.IOException; import java.io.Serializable; import javax.imageio.ImageIO; import java.awt.image.RenderedImage; import java.awt.image.BufferedImage; import jrobin.core.RrdDb; import jrobin.core.Util; import jrobin.core.RrdException; /** * <p>Class to represent JRobin graphs. This class needs an appropriate RrdGraphDef to generate graphs.</p> * * @author Arne Vandamme (arn...@jr...) * @author Sasa Markovic (sa...@jr...) */ public class RrdGraph implements Serializable { // ================================================================ // -- Members // ================================================================ private static int DEFAULT_POOLSIZE = 15; private Grapher grapher; private BufferedImage img; private ArrayList rrdDbPool; private int maxPoolSize = DEFAULT_POOLSIZE; // ================================================================ // -- Constructors // ================================================================ /** * Constructs a new JRobin graph object. */ public RrdGraph() { this( DEFAULT_POOLSIZE ); } /** * Constructs a new JRobin graph object. * @param poolSize Maximum number of concurrent open rrd files in the RrdGraph object. */ public RrdGraph( int poolSize ) { maxPoolSize = poolSize; rrdDbPool = new ArrayList( poolSize ); } /** * Constructs a new JRobin graph object from the supplied definition. * @param graphDef Graph definition. * @throws IOException Thrown in case of I/O error. * @throws RrdException Thrown in case of JRobin specific error. */ public RrdGraph( RrdGraphDef graphDef ) throws IOException, RrdException { this( graphDef, DEFAULT_POOLSIZE ); } /** * Constructs a new JRobin graph from the supplied definition. * @param graphDef Graph definition. * @param poolSize Maximum number of concurrent open rrd files in the RrdGraph object. * @throws IOException Thrown in case of I/O error. * @throws RrdException Thrown in case of JRobin specific error. */ public RrdGraph( RrdGraphDef graphDef, int poolSize ) throws IOException, RrdException { maxPoolSize = poolSize; rrdDbPool = new ArrayList( poolSize ); grapher = new Grapher( graphDef, this ); } // ================================================================ // -- Public mehods // ================================================================ /** * Sets the graph definition to use for the graph construction. * @param graphDef Graph definition. */ public void setGraphDef( RrdGraphDef graphDef ) { img = null; grapher = new Grapher( graphDef, this ); } /** * Creates and saves a graph image with default dimensions as a PNG file. * By default the chart area is 400 by 100 pixels, the size of the entire image is dependant * on number of title/legend/comment lines and some other settings. * @param path Path to the PNG file to be created. * @throws IOException Thrown in case of I/O error. */ public void saveAsPNG( String path ) throws RrdException, IOException { saveAsPNG( path, 0, 0 ); } /** * Creates and saves a graph image with custom chart dimensions as a PNG file. * The resulting size of the entire image is also influenced by many other settings like number of comment lines. * @param path Path to the PNG file to be created. * @param width Width of the chart area in pixels. * @param height Height of the chart area in pixels. * @throws IOException Thrown in case of I/O error. */ public void saveAsPNG( String path, int width, int height ) throws RrdException, IOException { Util.time(); RenderedImage r =(RenderedImage) getBufferedImage(width, height); Util.time(); ImageIO.write( r, "png", new File(path) ); Util.time(5); } /** * Creates and saves a graph image with default dimensions as a JPEG file. * By default the chart area is 400 by 100 pixels, the size of the entire image is dependant * on number of title/legend/comment lines and some other settings. * @param path Path to the JPEG file to be created. * @param quality JPEG quality, between 0 (= low) and 1.0f (= high). * @throws IOException Thrown in case of I/O error. */ public void saveAsJPEG( String path, float quality ) throws IOException { saveAsJPEG( path, 0, 0, quality ); } /** * Creates and saves a graph image with custom chart dimensions as a JPEG file. * The resulting size of the entire image is also influenced by many other settings like number of comment lines. * @param path Path to the JPEG file to be created. * @param width Width of the chart area in pixels. * @param height Height of the chart area in pixels. * @param quality JPEG quality, between 0 (= low) and 1.0f (= high). * @throws IOException Thrown in case of I/O error. */ public void saveAsJPEG( String path, int width, int height, float quality ) throws IOException { System.err.println( "Method not implemented..." ); } /** * Returns graph width default chart dimensions (400 by 100) as an array of PNG bytes. * @param width Width of the chart area in pixels. * @param height Height of the chart area in pixels. * @return Array of PNG bytes. * @throws IOException Thrown in case of I/O error. ... [truncated message content] |