Update of /cvsroot/jrobin/src/org/jrobin/graph In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18371/org/jrobin/graph Modified Files: Area.java Cdef.java ChartGraphics.java CustomArea.java CustomLine.java Def.java FetchSource.java Grapher.java Line.java Pdef.java PlotDef.java RrdGraph.java RrdGraphDef.java Sdef.java Source.java Stack.java ValueAxisUnit.java ValueExtractor.java ValueGrid.java Added Files: ExportData.java RrdExport.java RrdExportDef.java RrdExporter.java Log Message: JRobin 1.4.0 - Major graph datapoint calculation rewrite - Added elaborate Export support with RRDtool like functionality - New classes: RrdExport, RrdExporter, RrdExportDef, ExportData - New interface: RrdDataSet - Value grid tweaking - Several minor tweaks Index: CustomArea.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/CustomArea.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** CustomArea.java 4 Jul 2004 09:54:32 -0000 1.4 --- CustomArea.java 9 Jul 2004 12:22:15 -0000 1.5 *************** *** 142,146 **** stackValues[i] = g.getInverseY(ny); } ! /** * Retrieves the value for a specific point of the CustomArea. The CustomArea is always a rectangle, --- 142,146 ---- stackValues[i] = g.getInverseY(ny); } ! /** * Retrieves the value for a specific point of the CustomArea. The CustomArea is always a rectangle, *************** *** 169,173 **** void setSource( Source[] sources, HashMap sourceIndex ) throws RrdException { } ! void exportXmlTemplate( XmlWriter xml, String legend ) { xml.startTag("area"); --- 169,177 ---- void setSource( Source[] sources, HashMap sourceIndex ) throws RrdException { } ! ! // Stubbed, we don't need to set value for a Custom plotdef ! void setValue( int tableRow, long preciseTime, long[] reducedTimestamps ) { ! } ! void exportXmlTemplate( XmlWriter xml, String legend ) { xml.startTag("area"); Index: ValueExtractor.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/ValueExtractor.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ValueExtractor.java 30 May 2004 19:49:56 -0000 1.2 --- ValueExtractor.java 9 Jul 2004 12:22:15 -0000 1.3 *************** *** 27,30 **** --- 27,31 ---- import org.jrobin.core.FetchData; import org.jrobin.core.RrdException; + import org.jrobin.core.Util; /** *************** *** 40,48 **** private String[] varNames; // Name of the variable, NOT it's dsName in the file private int[] tPos; private long[][] timestamps; private double[][][] dsValues; ! ! // ================================================================ // -- Constructors --- 41,53 ---- private String[] varNames; // Name of the variable, NOT it's dsName in the file + private int reduceFactor = 1; + private int[] tPos; + private long[] steps; private long[][] timestamps; + private double[][][] dsValues; ! ! // ================================================================ // -- Constructors *************** *** 53,69 **** * @param values Array of FetchData objects holding all fetched datasources for a specific RRD file. */ ! ValueExtractor( String[] names, FetchData[] values ) { ! this.varNames = names; ! // Set timestamps ! tPos = new int[values.length]; ! timestamps = new long[values.length][]; ! dsValues = new double[values.length][][]; ! ! for (int i = 0; i < timestamps.length; i++) { ! if ( values[i] != null ) { timestamps[i] = values[i].getTimestamps(); dsValues[i] = values[i].getValues(); } } --- 58,82 ---- * @param values Array of FetchData objects holding all fetched datasources for a specific RRD file. */ ! ValueExtractor( String[] names, FetchData[] values, int reduceFactor ) { ! this.varNames = names; ! this.reduceFactor = reduceFactor; ! // Set timestamps ! tPos = new int[values.length]; ! steps = new long[values.length]; ! timestamps = new long[values.length][]; ! ! dsValues = new double[values.length][][]; ! ! for (int i = 0; i < timestamps.length; i++) ! { ! if ( values[i] != null ) ! { timestamps[i] = values[i].getTimestamps(); dsValues[i] = values[i].getValues(); + + if ( timestamps[i].length > 2 ) + steps[i] = (timestamps[i][1] - timestamps[i][0]); } } *************** *** 73,77 **** // ================================================================ // -- Protected methods ! // ================================================================ /** * Extracts a number of values out of the fetched values, and approximates them --- 86,106 ---- // ================================================================ // -- Protected methods ! // ================================================================ ! int prepareSources( Source[] sources, int offset ) ! { ! int tblPos = offset; ! ! for ( int i = 0; i < dsValues.length; i++ ) ! { ! if ( dsValues[i] != null ) ! { ! for (int x = 0; x < dsValues[i].length; x++) ! sources[tblPos++].setFetchedStep( steps[i] ); ! } ! } ! ! return tblPos; ! } ! /** * Extracts a number of values out of the fetched values, and approximates them *************** *** 87,119 **** { int tblPos = offset; ! ! for ( int i = 0; i < dsValues.length; i++ ) { if ( dsValues[i] == null ) continue; ! ! int tIndex = tPos[i]; ! ! if ( timestamp < timestamps[i][ tIndex ] ) ! throw new RrdException("Backward reading not allowed"); ! ! while ( tIndex < timestamps[i].length - 1 ) { ! if ( timestamps[i][ tIndex ] <= timestamp && timestamp < timestamps[i][ tIndex + 1] ) { ! for (int j = 0; j < dsValues[i].length; j++) ! sources[tblPos++].set( row, timestamp, dsValues[i][j][ tIndex + 1 ] ); ! break; } ! else { ! tIndex++; } } ! tPos[i] = tIndex; } ! return tblPos; } ! String[] getNames() { return varNames; --- 116,193 ---- { int tblPos = offset; ! ! for ( int i = 0; i < dsValues.length; i++ ) { if ( dsValues[i] == null ) continue; ! ! int tIndex = tPos[i]; ! ! double[] nValue = new double[ dsValues[i].length ]; ! int[] vValue = new int[ nValue.length ]; // Counts the actual valid values ! ! for ( int j = 0; j < nValue.length; j++ ) ! nValue[j] = Double.NaN; ! ! // Combine the rows ! int j; ! ! for ( j = 0; j < reduceFactor && timestamps[i][tIndex] <= timestamp; j++ ) { ! for (int x = 0; x < dsValues[i].length; x++) ! { ! if ( Double.isNaN(dsValues[i][x][tIndex]) ) ! continue; ! ! vValue[x]++; ! ! if ( Double.isNaN(nValue[x]) ) ! nValue[x] = dsValues[i][x][tIndex]; ! else ! { ! switch ( i ) ! { ! case FetchSource.AVG: ! nValue[x] += dsValues[i][x][tIndex]; ! break; ! case FetchSource.MAX: ! nValue[x] = Util.max( nValue[x], dsValues[i][x][tIndex] ); ! break; ! case FetchSource.MIN: ! nValue[x] = Util.min( nValue[x], dsValues[i][x][tIndex] ); ! break; ! case FetchSource.LAST: ! nValue[x] = dsValues[i][x][tIndex]; ! break; ! } ! } } ! ! tIndex++; ! } ! ! // See if we are using a stretched timespan ! if ( j == 0 && row > 0 ) ! { ! sources[tblPos++].set( row, timestamp, Double.POSITIVE_INFINITY ); ! } ! else ! { ! // Finalize ! for (int x = 0; x < dsValues[i].length; x++) ! { ! if ( i == FetchSource.AVG ) ! nValue[x] /= vValue[x]; ! ! sources[tblPos++].set( row, timestamp, nValue[x] ); } } ! tPos[i] = tIndex; } ! return tblPos; } ! String[] getNames() { return varNames; Index: Grapher.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/Grapher.java,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** Grapher.java 4 Jul 2004 09:54:32 -0000 1.15 --- Grapher.java 9 Jul 2004 12:22:15 -0000 1.16 *************** *** 37,41 **** import java.awt.image.BufferedImage; - import org.jrobin.core.RrdDb; import org.jrobin.core.RrdException; --- 37,40 ---- *************** *** 45,49 **** * @author Arne Vandamme (cob...@jr...) */ ! class Grapher { // ================================================================ --- 44,48 ---- * @author Arne Vandamme (cob...@jr...) */ ! class Grapher extends RrdExporter { // ================================================================ *************** *** 88,95 **** private RrdGraphDef graphDef; ! private long[] timestamps; ! private Source[] sources; ! private HashMap sourceIndex; ! private FetchSourceList fetchSources; private ValueFormatter valueFormat; --- 87,92 ---- private RrdGraphDef graphDef; ! private PlotDef[] plotDefs; ! private long[] tsChart; private ValueFormatter valueFormat; *************** *** 97,104 **** private ValueGrid vGrid; private TimeGrid tGrid; ! ! private long calculatedEndTime; ! ! // ================================================================ // -- Constructors --- 94,98 ---- private ValueGrid vGrid; private TimeGrid tGrid; ! // ================================================================ // -- Constructors *************** *** 112,115 **** --- 106,110 ---- Grapher( RrdGraphDef graphDef, RrdGraph rrdGraph ) { + super( graphDef, rrdGraph ); this.graphDef = graphDef; *************** *** 134,140 **** defaultStroke = new BasicStroke(); ! // Get the fetch sources list ! fetchSources = graphDef.getFetchSources(); ! fetchSources.setRrdOpener( rrdGraph ); // Set the RrdOpener } --- 129,134 ---- defaultStroke = new BasicStroke(); ! startTime = graphDef.getStartTime(); ! endTime = graphDef.getStartTime(); } *************** *** 316,320 **** { // Do the actual graphing ! calculateSeries(); // calculate all datasources plotImageBackground( graphics ); // draw the image background --- 310,317 ---- { // Do the actual graphing ! if ( graphDef.useExportData() ) ! calculateSeries( graphDef.getExportData() ); ! else ! calculateSeries(); // calculate all datasources plotImageBackground( graphics ); // draw the image background *************** *** 334,337 **** --- 331,335 ---- /** * Fetches and calculates all datasources used in the graph. + * * @throws RrdException Thrown in case of a JRobin specific error. * @throws IOException Thrown in case of a I/O related error. *************** *** 339,539 **** private void calculateSeries() throws RrdException, IOException { ! ValueExtractor ve; ! FetchSource src; ! RrdDb rrd; ! String[] varList; ! ! long finalEndTime = 0; ! boolean changingEndTime = false; ! ! long startTime = graphDef.getStartTime(); ! long endTime = graphDef.getEndTime(); ! changingEndTime = (endTime == 0); ! ! int numDefs = graphDef.getNumDefs(); ! int numSdefs = graphDef.getNumSdefs(); ! ! Cdef[] cdefList = graphDef.getCdefs(); ! int numCdefs = cdefList.length; ! ! Pdef[] pdefList = graphDef.getPdefs(); ! int numPdefs = pdefList.length; ! ! // Set up the array with all datasources (both Def, Cdef and Pdef) ! sources = new Source[ numDefs + numCdefs + numPdefs ]; ! sourceIndex = new HashMap( numDefs + numCdefs + numPdefs ); ! int tblPos = 0; ! int vePos = 0; ! ! ValueExtractor[] veList = new ValueExtractor[ fetchSources.size() ]; ! ! // Open all datasources ! try ! { ! fetchSources.openAll(); ! ! for ( int i = 0; i < fetchSources.size(); i++ ) ! { ! src = fetchSources.get( i ); ! ! if ( changingEndTime ) ! { ! endTime = src.getLastSampleTime( startTime, endTime, graphDef.getResolution() ); ! ! if ( endTime > finalEndTime ) ! finalEndTime = endTime; ! } ! ! // Fetch all required datasources ! ve = src.fetch( startTime, endTime, graphDef.getResolution() ); ! varList = ve.getNames(); ! for (int j= 0; j < varList.length; j++) { ! sources[tblPos] = new Def(varList[j], numPoints); ! sourceIndex.put( varList[j], new Integer(tblPos++) ); ! } ! veList[ vePos++ ] = ve; ! } ! } ! finally ! { ! // Release all datasources again ! fetchSources.releaseAll(); ! } ! // Add all Pdefs to the source table ! for ( int i = 0; i < pdefList.length; i++ ) { ! pdefList[i].prepare( numPoints ); ! ! sources[tblPos] = pdefList[i]; ! sourceIndex.put( pdefList[i].getName(), new Integer(tblPos++) ); } ! int cdefStart = tblPos; // First Cdef element, necessary for tree descend calculation ! ! // Add all Cdefs to the source table ! // Reparse all RPN datasources to use indices of the correct variables ! for ( int i = 0; i < cdefList.length; i++ ) { ! cdefList[i].prepare( sourceIndex, numPoints ); ! ! sources[tblPos] = cdefList[i]; ! sourceIndex.put( cdefList[i].getName(), new Integer(tblPos++) ); ! } ! // Fill the array for all datasources ! timestamps = new long[numPoints]; ! if ( changingEndTime ) { ! endTime = finalEndTime; ! calculatedEndTime = endTime; } ! // RPN calculator for the Cdefs ! RpnCalculator rpnCalc = new RpnCalculator( sources, (endTime - startTime) / (double) numPoints ); ! ! // **************************************************************************************** // ! // If there are Sdefs, we should determine a tree-descend order for calculation. // ! // An Sdef is completely dependant on another datasource and can only be calculated // ! // after the datasource it depends on has been calculated itself entirely. // ! // e.g. The Sdef giving the AVG of a Def should be one lower in the calculation tree // ! // than the corresponding Def. Lower = higher level. // ! // Since Sdefs can be nested and combined into new Cdefs and possibly resulting in new // ! // Sdefs, the worst case calculation could result in every datasource being calculated // ! // separately, resulting in more overhead. However the impact of this should remain fairly // ! // small in CPU time. // ! // **************************************************************************************** // ! if ( numSdefs > 0 ) ! { ! // Initalize level for each def on 0 ! int treeDepth = 0; ! int[] treeLevel = new int[ sources.length ]; ! ! // First level contains all fetched datasources, custom datasources and combined datasources that use other first levels ! for ( int i = cdefStart; i < sources.length; i++ ) ! { ! // Get the level of all defs needed, take the maximum level ! int level = ((Cdef) sources[i]).calculateLevel( treeLevel ); ! treeDepth = (level > treeDepth ? level : treeDepth); ! ! treeLevel[i] = level; ! } ! ! // Run through each level of the tree ! long t; ! int pos; ! ! for ( int l = 0; l <= treeDepth; l++ ) ! { ! for (int i = 0; i < numPoints; i++) ! { ! pos = cdefStart; ! // First level of the tree includes fetched datasources and pdefs, ! // since these values can never depend on others in the list. ! if ( l == 0 ) ! { ! // Calculate new timestamp ! pos = 0; ! t = (long) (startTime + i * ((endTime - startTime) / (double) (numPoints - 1))); ! // Get all fetched datasources ! for (int j = 0; j < veList.length; j++) ! pos = veList[j].extract( t, sources, i, pos ); ! // Get all custom datasources ! for (int j = pos; j < pos + numPdefs; j++) ! ((Pdef) sources[j]).set( i, t ); ! pos += numPdefs; ! timestamps[i] = t; ! } ! else ! t = timestamps[i]; ! // Calculate the cdefs of this level ! for ( int j = pos; j < sources.length; j++ ) ! { ! if ( treeLevel[j] == l ) ! { ! // This Cdef/Sdef can be calculated ! if ( sources[j] instanceof Sdef ) ! ((Sdef) sources[j]).set( sources ); ! else ! sources[j].set( i, t, rpnCalc.evaluate( (Cdef) sources[j], i, t ) ); ! } ! } ! } ! } ! } ! else { ! // Traditional way of calculating all datasources, slightly faster ! for (int i = 0; i < numPoints; i++) ! { ! long t = (long) (startTime + i * ((endTime - startTime) / (double) (numPoints - 1))); ! int pos = 0; ! ! // Get all fetched datasources ! for (int j = 0; j < veList.length; j++) ! pos = veList[j].extract( t, sources, i, pos ); ! // Get all custom datasources ! for (int j = pos; j < pos + numPdefs; j++) ! ((Pdef) sources[j]).set( i, t ); ! pos += numPdefs; ! // Get all combined datasources ! for (int j = pos; j < sources.length; j++) ! sources[j].set(i, t, rpnCalc.evaluate( (Cdef) sources[j], i, t ) ); ! timestamps[i] = t; ! } } ! // Clean up the fetched datasources forcibly ! veList = null; } --- 337,410 ---- private void calculateSeries() throws RrdException, IOException { ! // Calculate the reduced set of datasources ! super.calculateSeries( chartWidth ); ! numPoints = numRows; ! /** ! * Expand the reduced set back to a set matching the chart width, ! * this allows for much nicer graphing. ! */ ! tsChart = new long[ chartWidth ]; ! plotDefs = graphDef.getPlotDefs(); ! for ( int i = 0; i < plotDefs.length; i++ ) { ! plotDefs[i].setSource( sources, sourceIndex ); ! plotDefs[i].prepareValues( chartWidth ); } ! for ( int i = 0; i < chartWidth; i++ ) { ! long t = (long) (startTime + i * ((endTime - startTime) / (double) (chartWidth - 1))); ! for ( int j = 0; j < plotDefs.length; j++ ) ! plotDefs[j].setValue( i, t, timestamps ); ! tsChart[i] = t; } + } ! /** ! * Calculates graphing values based on a ExportData object. ! * ! * @param dataSet ExportData holding the values. ! * @throws RrdException Thrown in case of a JRobin specific error. ! * @throws IOException Thrown in case of a I/O related error. ! */ ! private void calculateSeries( ExportData dataSet ) throws RrdException, IOException ! { ! numPoints = dataSet.getRowCount(); ! startTime = graphDef.getStartTime(); ! endTime = graphDef.getEndTime(); ! tsChart = new long[ chartWidth ]; ! plotDefs = graphDef.getPlotDefs(); ! timestamps = dataSet.getTimestamps(); ! sources = dataSet.getSources(); ! sourceIndex = new HashMap( sources.length ); ! for ( int i = 0; i < sources.length; i++ ) ! sourceIndex.put( sources[i].getName(), new Integer(i) ); ! for ( int i = 0; i < plotDefs.length; i++ ) { ! plotDefs[i].setSource( sources, sourceIndex ); ! plotDefs[i].prepareValues( chartWidth ); ! } ! for ( int i = 0; i < chartWidth; i++ ) ! { ! long t = (long) (startTime + i * ((endTime - startTime) / (double) (chartWidth - 1))); ! for ( int j = 0; j < plotDefs.length; j++ ) ! plotDefs[j].setValue( i, t, timestamps ); ! tsChart[i] = t; } ! } *************** *** 630,637 **** // For autoscale, detect lower and upper limit of values - PlotDef[] plotDefs = graphDef.getPlotDefs(); for ( int i = 0; i < plotDefs.length; i++ ) { - plotDefs[i].setSource( sources, sourceIndex ); Source src = plotDefs[i].getSource(); --- 501,506 ---- *************** *** 641,645 **** double min = src.getAggregate( Source.AGG_MINIMUM ); double max = src.getAggregate( Source.AGG_MAXIMUM ); ! // If the plotdef is a stack, evaluate ALL previous values to find a possible max if ( plotDefs[i].plotType == PlotDef.PLOT_STACK && i >= 1 ) --- 510,514 ---- double min = src.getAggregate( Source.AGG_MINIMUM ); double max = src.getAggregate( Source.AGG_MAXIMUM ); ! // If the plotdef is a stack, evaluate ALL previous values to find a possible max if ( plotDefs[i].plotType == PlotDef.PLOT_STACK && i >= 1 ) *************** *** 681,685 **** vGrid = new ValueGrid( range, lowerValue, upperValue, graphDef.getValueAxis(), graphDef.getBaseValue() ); ! tGrid = new TimeGrid( graphDef.getStartTime(), ( graphDef.getEndTime() != 0 ? graphDef.getEndTime() : calculatedEndTime ), graphDef.getTimeAxis(), graphDef.getFirstDayOfWeek() ); lowerValue = vGrid.getLowerValue(); --- 550,554 ---- vGrid = new ValueGrid( range, lowerValue, upperValue, graphDef.getValueAxis(), graphDef.getBaseValue() ); ! tGrid = new TimeGrid( startTime, endTime, graphDef.getTimeAxis(), graphDef.getFirstDayOfWeek() ); lowerValue = vGrid.getLowerValue(); *************** *** 691,695 **** g.setXRange( tGrid.getStartTime(), tGrid.getEndTime() ); g.setYRange( lowerValue, upperValue ); ! // Set the chart origin point double diff = 1.0d; --- 560,564 ---- g.setXRange( tGrid.getStartTime(), tGrid.getEndTime() ); g.setYRange( lowerValue, upperValue ); ! // Set the chart origin point double diff = 1.0d; *************** *** 711,720 **** int lastPlotType = PlotDef.PLOT_LINE; ! double[] parentSeries = new double[numPoints]; // Pre calculate x positions of the corresponding timestamps ! int[] xValues = new int[timestamps.length]; ! for (int i = 0; i < timestamps.length; i++) ! xValues[i] = g.getX(timestamps[i]); // Draw all graphed values --- 580,589 ---- int lastPlotType = PlotDef.PLOT_LINE; ! double[] parentSeries = new double[chartWidth]; // Pre calculate x positions of the corresponding timestamps ! int[] xValues = new int[tsChart.length]; ! for (int i = 0; i < tsChart.length; i++) ! xValues[i] = g.getX(tsChart[i]); // Draw all graphed values --- NEW FILE: RrdExportDef.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 org.jrobin.graph; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.GregorianCalendar; import org.jrobin.core.Util; import org.jrobin.core.RrdException; /** * <p>Class used to collect information for a JRobin export.</p> * * <p>JRobin export works the same way as Rrdtool XPORT does, to learn * more about the XPORT functionality, see RRDTool's * <a href="../../../../man/rrdxport.html" target="man">rrdxport man page</a>.</p> * * @author Arne Vandamme (cob...@jr...) */ public class RrdExportDef implements Serializable { // ================================================================ // -- Members // ================================================================ public final static int STRICT_IMPLICIT_OFF = 0; public final static int STRICT_IMPLICIT_ON = 1; public final static int STRICT_EXPLICIT_OFF = 2; public final static int STRICT_EXPLICIT_ON = 3; private long endTime = Util.getTime(); // default time span of the last 24 hours private long startTime = Util.getTime() - 86400L; private long resolution = 1; // resolution to fetch from the RRD databases private int strict = STRICT_IMPLICIT_OFF; // -- Non-settable members private int numSdefs = 0; private int numDefs = 0; // number of Def datasources added protected FetchSourceList fetchSources = new FetchSourceList( 10 ); // holds the list of FetchSources protected ArrayList pdefList = new ArrayList( 10 ); // holds the list of Plottable datasources protected ArrayList cdefList = new ArrayList( 10 ); // holds the list of Cdef datasources protected ArrayList exportList = new ArrayList( 10 ); // holds the list of datasources to export // ================================================================ // -- Constructors // ================================================================ public RrdExportDef() { } /** * 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 seconds. * @throws org.jrobin.core.RrdException Thrown if invalid parameters are supplied. */ public RrdExportDef( 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 RrdExportDef( 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 RrdExportDef( GregorianCalendar start, GregorianCalendar end ) throws RrdException { setTimePeriod( start, end ); } // ================================================================ // -- Public methods // ================================================================ /** * Sets time span to be presented on the graph using timestamps in number of seconds. * An end time of 0 means JRobin will try to use the last available update time. * * @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 != 0 && endTime <= startTime ) ) throw new RrdException( "Invalid 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 the resolution with which data will be fetched from the RRD sources. * JRobin will try to match the requested resolution as closely as possible. * * @param resolution Resolution (data step) in seconds. */ public void setResolution( long resolution ) { this.resolution = resolution; } /** * <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> * <li>To define complex graph sources * (see {@link #datasource(java.lang.String, java.lang.String) complex graph * source definition}).</li> * </ul> * * @param name Graph source name. * @param file Path to RRD file. * @param dsName Data source name defined in the RRD file. * @param consolFunc 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 { fetchSources.add( name, file, dsName, consolFunc ); numDefs++; } /** * <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> * <li>To define complex graph sources * (see {@link #datasource(java.lang.String, java.lang.String) complex graph * source definition}).</li> * </ul> * * @param name Graph source name. * @param file Path to RRD file. * @param dsName Data source name defined in the RRD file. * @param consolFunc Consolidation function that will be used to extract data from the RRD * file ("AVERAGE", "MIN", "MAX" or "LAST"). * @param backend Name of the RrdBackendFactory that should be used for this RrdDb. */ public void datasource( String name, String file, String dsName, String consolFunc, String backend ) throws RrdException { fetchSources.add( name, file, dsName, consolFunc, backend ); numDefs++; } /** * <p>Clears the list of RRD datasources for this GraphDef and sets it to the FetchSourceList * passed as aparameter. This does not alter any Cdef, Sdef or Pdef definitions. The datasources * should be passed on as a FetchSourceList {@link FetchSourceList}.</p> * @param datasourceList FetchSourceList of the datasources to use. */ public void setDatasources( FetchSourceList datasourceList ) { fetchSources = datasourceList; numDefs = fetchSources.defCount(); } /** * <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> * <li>To define other complex graph sources.</li> * </ul> * * <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="http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/manual/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) ); } /** * <p>Adds static graph source with the given name to the graph definition. * Static graph sources are the result of a consolidation function applied * to *any* other graph source that has been defined previously.</p> * * @param name Graph source name. * @param defName Name of the datasource to calculate the value from. * @param consolFunc Consolidation function to use for value calculation */ public void datasource( String name, String defName, String consolFunc ) throws RrdException { cdefList.add( new Sdef(name, defName, consolFunc) ); numSdefs++; } /** * <p>Adds a custom graph source with the given name to the graph definition. * The datapoints should be made available by a class extending Plottable.</p> * * @param name Graph source name. * @param plottable Class that extends Plottable class and is suited for graphing. */ public void datasource( String name, Plottable plottable ) { pdefList.add( new Pdef(name, plottable) ); } /** * <p>Adds a custom graph source with the given name to the graph definition. * The datapoints should be made available by a class extending Plottable.</p> * * @param name Graph source name. * @param plottable Class that extends Plottable class and is suited for graphing. * @param index Integer referring to the datasource in the Plottable class. */ public void datasource( String name, Plottable plottable, int index ) { pdefList.add( new Pdef(name, plottable, index) ); } /** * <p>Adds a custom graph source with the given name to the graph definition. * The datapoints should be made available by a class extending Plottable.</p> * * @param name Graph source name. * @param plottable Class that extends Plottable class and is suited for graphing. * @param sourceName String name referring to the datasource in the Plottable class. */ public void datasource( String name, Plottable plottable, String sourceName ) { pdefList.add( new Pdef(name, plottable, sourceName) ); } /** * Sets a specific datasource to be exported (if export is strict). * The expor legend for this datasource will be empty. * * @param name Name of the datasource */ public void export( String name ) { export( name, "" ); } /** * Sets a specific datasource to be exported (if export is strict). * And maps an export legend to this datasource. * * @param name Name of the datasource * @param legend Legend text */ public void export( String name, String legend ) { if ( strict == STRICT_IMPLICIT_OFF ) strict = STRICT_IMPLICIT_ON; exportList.add( new String[] { name, legend } ); } /** * <p>Sets the strict flag for the export functionality. By default, the * export is in implicit not-strict, this means that by default, all * datasources specified in the RrdExportDef will be exported into * the ExportData.</p> * * <p>If the strict flag is not specified explicitly by calling this method, * the export will convert to implicitly strict as soon as a particular * export() mapping is defined. Explicit settings will override implicit.</p> * * <p>When explicit is off, the legend for datasources will by default be * the same as the datasource name, the legend can be overridden by setting * mappings using export() method.</p> * * <p>Strict export is the same behaviour as RRDtool's XPORT.</p> * * @param strict True if strict export should on, false if not. */ public void setStrictExport( boolean strict ) { this.strict = ( strict ? STRICT_EXPLICIT_ON : STRICT_EXPLICIT_OFF ); } // ================================================================ // -- Protected (package) methods // ================================================================ protected long getStartTime() { return startTime; } protected long getEndTime() { return endTime; } protected long getResolution() { return resolution; } protected int getNumDefs() { return numDefs; } protected Cdef[] getCdefs() { return (Cdef[]) cdefList.toArray( new Cdef[] {} ); } protected Pdef[] getPdefs() { return (Pdef[]) pdefList.toArray( new Pdef[] {} ); } protected int getNumSdefs() { return numSdefs; } protected FetchSourceList getFetchSources() { return fetchSources; } protected boolean isStrict() { return ( strict == STRICT_IMPLICIT_ON || strict == STRICT_EXPLICIT_ON ); } protected String[][] getExportDatasources() { return (String[][]) exportList.toArray( new String[0][2] ); } } Index: Area.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/Area.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Area.java 4 Jul 2004 09:54:32 -0000 1.5 --- Area.java 9 Jul 2004 12:22:14 -0000 1.6 *************** *** 27,31 **** import org.jrobin.core.XmlWriter; ! import java.awt.Color; /** --- 27,31 ---- import org.jrobin.core.XmlWriter; ! import java.awt.*; /** *************** *** 59,65 **** * @param visible True if this PlotDef should be graphed, false if not. */ ! Area( Source source, Color color, boolean stacked, boolean visible ) { ! super( source, color, stacked, visible ); } --- 59,65 ---- * @param visible True if this PlotDef should be graphed, false if not. */ ! Area( Source source, double[] values, Color color, boolean stacked, boolean visible ) { ! super( source, values, color, stacked, visible); } *************** *** 78,84 **** { g.setColor( color ); ! ! double[] values = source.getValues(); ! int len = xValues.length; double value; --- 78,83 ---- { g.setColor( color ); ! ! int len = values.length; double value; *************** *** 87,94 **** for ( int i = 0; i < len; i++ ) { value = values[i]; - py = 0; - - nx = xValues[i]; if ( !Double.isNaN(value) ) --- 86,92 ---- for ( int i = 0; i < len; i++ ) { + py = 0; + nx = xValues[i]; value = values[i]; if ( !Double.isNaN(value) ) *************** *** 117,124 **** g.drawLine( nx, py, nx, ny ); } - - } ! // Special case with NaN doubles stackValues[i] = value; --- 115,120 ---- g.drawLine( nx, py, nx, ny ); } } ! // Special case with NaN doubles stackValues[i] = value; *************** *** 127,131 **** } } ! void exportXmlTemplate( XmlWriter xml, String legend ) { --- 123,127 ---- } } ! void exportXmlTemplate( XmlWriter xml, String legend ) { Index: RrdGraph.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/RrdGraph.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** RrdGraph.java 29 Jun 2004 09:34:39 -0000 1.10 --- RrdGraph.java 9 Jul 2004 12:22:15 -0000 1.11 *************** *** 400,403 **** --- 400,443 ---- } + /** + * This retrieves the ExportData object associated with the reduced dataset of this Graph. + * This method assumes the graph or at least the dataset has already been calculated. + * + * @return ExportData object containing the reduced dataset. + * @throws RrdException Thrown in case of JRobin specific error. + */ + public ExportData getExportData() throws RrdException { + return grapher.createExportData(); + } + + /** + * This retrieves the ExportData object associated with the reduced dataset of this Graph, + * by calculating the dataset on the spot. Use this if you want to retrieve the associated + * ExportData without generating the actual graph. + * + * @return ExportData object containing the reduced dataset. + * @throws RrdException Thrown in case of JRobin specific error. + * @throws IOException Thrown in case of I/O error + */ + public ExportData fetchExportData() throws RrdException, IOException { + return grapher.fetch( Grapher.DEFAULT_WIDTH ); + } + + /** + * This retrieves the ExportData object associated with the reduced dataset of this Graph, + * by calculating the dataset on the spot. Use this if you want to retrieve the associated + * ExportData without generating the actual graph, or if you wish to re-calculate the + * associated dataset for a different number of rows. + * + * @param maxRows Ballpark figure 'maximum number of rows' that the dataset can contain. + * Note that this is not an absolute maximum and can be overruled in some cases. + * @return ExportData object containing the reduced dataset. + * @throws RrdException Thrown in case of JRobin specific error. + * @throws IOException Thrown in case of I/O error + */ + public ExportData fetchExportData( int maxRows ) throws RrdException, IOException { + return grapher.fetch( maxRows ); + } + // ================================================================ // -- Private methods Index: Def.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/Def.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Def.java 7 Nov 2003 09:53:35 -0000 1.2 --- Def.java 9 Jul 2004 12:22:15 -0000 1.3 *************** *** 41,48 **** * @param numPoints Number of points used as graph resolution (size of the value table). */ ! Def( String name, int numPoints ) { super(name); ! values = new double[ numPoints ]; } --- 41,49 ---- * @param numPoints Number of points used as graph resolution (size of the value table). */ ! Def( String name, int numPoints, int aggregatePoints ) { super(name); ! values = new double[ numPoints ]; ! this.aggregatePoints = aggregatePoints; } Index: PlotDef.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/PlotDef.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** PlotDef.java 4 Jul 2004 09:54:32 -0000 1.4 --- PlotDef.java 9 Jul 2004 12:22:15 -0000 1.5 *************** *** 55,60 **** protected Source source = null; protected Color color = Color.BLACK; // Default color is black ! ! // ================================================================ // -- Constructors --- 55,61 ---- protected Source source = null; protected Color color = Color.BLACK; // Default color is black ! ! protected double[] values = null; ! // ================================================================ // -- Constructors *************** *** 87,99 **** * @param visible True if this PlotDef should be graphed, false if not. */ ! PlotDef( Source source, Color color, boolean stacked, boolean visible ) { this.source = source; this.color = color; this.stacked = stacked; this.visible = visible; } ! ! // ================================================================ // -- Protected methods --- 88,100 ---- * @param visible True if this PlotDef should be graphed, false if not. */ ! PlotDef( Source source, double[] values, Color color, boolean stacked, boolean visible ) { this.source = source; + this.values = values; this.color = color; this.stacked = stacked; this.visible = visible; } ! // ================================================================ // -- Protected methods *************** *** 113,117 **** throw new RrdException( "Invalid DEF or CDEF: " + sourceName ); } ! /** * Retrieves the value for a specific datapoint of the PlotDef. --- 114,128 ---- throw new RrdException( "Invalid DEF or CDEF: " + sourceName ); } ! ! void prepareValues( int arraySize ) ! { ! values = new double[ arraySize ]; ! } ! ! void setValue( int tableRow, long preciseTime, long[] reducedTimestamps ) ! { ! values[ tableRow ] = source.get( preciseTime, reducedTimestamps ); ! } ! /** * Retrieves the value for a specific datapoint of the PlotDef. Index: CustomLine.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/CustomLine.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** CustomLine.java 4 Jul 2004 09:54:32 -0000 1.3 --- CustomLine.java 9 Jul 2004 12:22:15 -0000 1.4 *************** *** 73,77 **** this.yVal1 = startValue; this.yVal2 = endValue; ! try { --- 73,77 ---- this.yVal1 = startValue; this.yVal2 = endValue; ! try { *************** *** 119,123 **** int ax, ay, nx, ny; ! // Get X positions if ( xVal1 == Long.MIN_VALUE ) --- 119,123 ---- int ax, ay, nx, ny; ! // Get X positions if ( xVal1 == Long.MIN_VALUE ) *************** *** 171,175 **** g.setStroke( STROKE ); } ! /** * Retrieves the value for a specific point of the CustomLine. The corresponding value is calculated based --- 171,175 ---- g.setStroke( STROKE ); } ! /** * Retrieves the value for a specific point of the CustomLine. The corresponding value is calculated based *************** *** 207,210 **** --- 207,214 ---- } + // Stubbed, we don't need to set value for a Custom plotdef + void setValue( int tableRow, long preciseTime, long[] reducedTimestamps ) { + } + void exportXmlTemplate( XmlWriter xml, String legend ) { if(yVal1 == yVal2 && xVal1 != xVal2) { Index: ChartGraphics.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/ChartGraphics.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ChartGraphics.java 4 Jul 2004 09:54:32 -0000 1.3 --- ChartGraphics.java 9 Jul 2004 12:22:15 -0000 1.4 *************** *** 58,62 **** ChartGraphics( Graphics2D graphics ) { ! g = graphics; } --- 58,62 ---- ChartGraphics( Graphics2D graphics ) { ! g = graphics; } *************** *** 91,95 **** void fillRect(int x1, int y1, int x2, int y2) { ! g.fillRect( x1, -y2, x2 - x1, y2 - y1 ); } --- 91,95 ---- void fillRect(int x1, int y1, int x2, int y2) { ! g.fillRect( x1, -y2, x2 - x1, - (y2 - y1) ); } *************** *** 186,190 **** g.setStroke( s ); } ! /** * Retrieves the lowest X coordinate of the chart area. --- 186,190 ---- g.setStroke( s ); } ! /** * Retrieves the lowest X coordinate of the chart area. Index: ValueAxisUnit.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/ValueAxisUnit.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ValueAxisUnit.java 19 Apr 2004 22:35:00 -0000 1.5 --- ValueAxisUnit.java 9 Jul 2004 12:22:15 -0000 1.6 *************** *** 42,46 **** // -- Members // ================================================================ - private double gridStep = 2; private double labelStep = 10; --- 42,45 ---- *************** *** 85,89 **** double minPoint = 0.0d; double majPoint = 0.0d; ! // Find the first visible gridpoint if ( lower > 0 ) { --- 84,88 ---- double minPoint = 0.0d; double majPoint = 0.0d; ! // Find the first visible gridpoint if ( lower > 0 ) { *************** *** 151,201 **** double gridFactor = 1.0; double mGridFactor = 1.0; ! double gridStep = this.gridStep; double mGridStep = this.labelStep; ! ! if ( gridStep < 1.0 ) { ! gridStep *= 100; ! gridFactor = 100; } ! ! if ( mGridStep < 1.0 ) { ! mGridStep *= 100; ! mGridFactor = 100; } ! ! double value = ovalue * gridFactor; ! int valueInt = new Double(value).intValue(); ! int roundStep = new Double(gridStep).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) < (gridStep) / 16 ) ! gridValue -= roundStep; ! ! value = ovalue * mGridFactor; ! roundStep = new Double(mGridStep).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) < (mGridStep) / 2) - return mGridValue / mGridFactor; - else - return gridValue / gridFactor; - } ! return ovalue; } --- 150,191 ---- double gridFactor = 1.0; double mGridFactor = 1.0; ! double gridStep = this.gridStep; double mGridStep = this.labelStep; ! ! while ( gridStep < 10.0 ) { ! gridStep *= 10; ! gridFactor *= 10; } ! ! while ( mGridStep < 10.0 ) { ! mGridStep *= 10; ! mGridFactor *= 10; } ! ! int sign = ( ovalue > 0 ? 1 : -1 ); ! ! long lGridStep = new Double( gridStep ).longValue(); ! long lmGridStep = new Double( mGridStep ).longValue(); ! ! long lValue = new Double(sign * ovalue * gridFactor).longValue(); ! long lmValue = new Double(sign * ovalue * mGridFactor).longValue(); ! ! long lMod = lValue % lGridStep; ! long lmMod = lmValue % lmGridStep; ! ! /*if ( ovalue < 0 ) { ! } ! else ! {*/ ! if ( lmMod < ( mGridStep * 0.5 ) ) ! return ((double) (sign*lmValue - lmMod) / mGridFactor); ! else if ( lMod > 0 ) ! return ((double) (sign*lValue - lMod) / gridFactor); ! else ! return ((double) (sign*lValue) / gridFactor); ! //} } *************** *** 208,260 **** double getNiceHigher( double ovalue ) { - // Add some checks double gridFactor = 1.0; double mGridFactor = 1.0; ! double gridStep = this.gridStep; double mGridStep = this.labelStep; ! ! if ( gridStep < 1.0 ) { ! gridStep *= 100; ! gridFactor = 100; ! } ! ! if ( mGridStep < 1.0 ) { ! mGridStep *= 100; ! mGridFactor = 100; } ! ! double value = ovalue * gridFactor; ! long valueInt = new Double(value).longValue(); ! long roundStep = new Double(gridStep).longValue(); ! if ( roundStep == 0 ) roundStep = 1; ! long num = valueInt / roundStep; ! // int mod = valueInt % roundStep; ! double gridValue = (roundStep * (num + 1)) * 1.0d; ! if ( gridValue - value < (gridStep) / 8 ) ! gridValue += roundStep; ! ! value = ovalue * mGridFactor; ! roundStep = new Double(mGridStep).longValue(); ! 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) < (mGridStep) / 2) ! return mGridValue / mGridFactor; ! else ! return gridValue / gridFactor; } ! ! return ovalue; } ! ! // ================================================================ // -- Private methods ! // ================================================================ /** * Rounds a specific double value to 14 decimals. This is used to avoid strange double values due to the --- 198,238 ---- double getNiceHigher( double ovalue ) { double gridFactor = 1.0; double mGridFactor = 1.0; ! double gridStep = this.gridStep; double mGridStep = this.labelStep; ! ! while ( gridStep < 10.0 ) { ! gridStep *= 10; ! gridFactor *= 10; } ! ! while ( mGridStep < 10.0 ) { ! mGridStep *= 10; ! mGridFactor *= 10; } ! ! int sign = ( ovalue > 0 ? 1 : -1 ); ! ! long lGridStep = new Double( gridStep ).longValue(); ! long lmGridStep = new Double( mGridStep ).longValue(); ! ! long lValue = new Double(sign * ovalue * gridFactor).longValue(); ! long lmValue = new Double(sign * ovalue * mGridFactor).longValue(); ! ! long lMod = lValue % lGridStep; ! long lmMod = lmValue % lmGridStep; ! ! if ( lmMod > ( mGridStep * 0.5 ) ) ! return ((double) ( sign * lmValue - lmMod + lmGridStep) / mGridFactor); ! else ! return ((double) ( sign * lValue - lMod + lGridStep) / gridFactor); } ! ! // ================================================================ // -- Private methods ! // ================================================================ /** * Rounds a specific double value to 14 decimals. This is used to avoid strange double values due to the Index: Sdef.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/Sdef.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Sdef.java 30 May 2004 19:49:56 -0000 1.1 --- Sdef.java 9 Jul 2004 12:22:15 -0000 1.2 *************** *** 68,72 **** // ================================================================ /** ! * Prepares the Sef for faster value calculation by setting the internal * array and references. Override from Cdef parent class. * --- 68,72 ---- // ================================================================ /** ! * Prepares the Sdef for faster value calculation by setting the internal * array and references. Override from Cdef parent class. * *************** *** 75,79 **** * @throws RrdException Thrown in case of the requested datasource is not available in the sourceIndex */ ! void prepare( HashMap sourceIndex, int numPoints ) throws RrdException { if ( sourceIndex.containsKey( defName ) ) --- 75,79 ---- * @throws RrdException Thrown in case of the requested datasource is not available in the sourceIndex */ ! void prepare( HashMap sourceIndex, int numPoints, int aggregatePoints ) throws RrdException { if ( sourceIndex.containsKey( defName ) ) *************** *** 82,86 **** throw new RrdException( "Datasource not found: " + defName ); ! values = new double[ numPoints ]; } --- 82,87 ---- throw new RrdException( "Datasource not found: " + defName ); ! values = new double[ numPoints ]; ! this.aggregatePoints = aggregatePoints; } Index: Source.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/Source.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Source.java 4 Jul 2004 09:54:32 -0000 1.8 --- Source.java 9 Jul 2004 12:22:15 -0000 1.9 *************** *** 46,49 **** --- 46,51 ---- protected static final String[] aggregates = { "MINIMUM", "MAXIMUM", "AVERAGE", "FIRST", "LAST", "TOTAL" }; private String name; + + protected int aggregatePoints; protected double[] values; *************** *** 52,59 **** private double lastValue = Double.NaN; private double totalValue = 0; ! private long lastTime = 0; ! private long totalTime = 0; ! // ================================================================ // -- Constructors --- 54,65 ---- private double lastValue = Double.NaN; private double totalValue = 0; ! private double nextValue = Double.POSITIVE_INFINITY; ! ! private long step = 0; private long lastTime = 0; ! private long totalTime = 0; ! ! private int stPos = 0; ! // ================================================================ // -- Constructors *************** *** 81,89 **** void set( int pos, long time, double val ) { ! aggregate( time, val ); } ! /** * Get the double value of a datapoint. * @param pos Index in the value table of the datapoint. * @return The double value of the requested datapoint. --- 87,108 ---- void set( int pos, long time, double val ) { ! // The first sample is before the time range we want, and as such ! // should not be counted for data aggregation ! if ( pos > 0 && pos < aggregatePoints ) ! aggregate( time, val ); } ! ! void setFetchedStep( long step ) ! { ! this.step = step; ! } ! ! long getStep() { ! return step; ! } ! /** * Get the double value of a datapoint. + * * @param pos Index in the value table of the datapoint. * @return The double value of the requested datapoint. *************** *** 91,97 **** double get( int pos ) { return values[pos]; } ! /** * Gets a specific aggregate of this datasource. --- 110,164 ---- double get( int pos ) { + if ( pos < 0 ) return Double.NaN; + + double val = values[pos]; + + if ( Double.isInfinite(val) ) + { + // Return the next value if we fetched it before + if ( !Double.isInfinite(nextValue) ) + return nextValue; + + // Try to fetch the next value + for ( int i = pos + 1; i < values.length; i++ ) + { + if ( !Double.isInfinite(values[i]) ) + { + nextValue = values[i]; + + return nextValue; + } + } + + // No more next value + nextValue = Double.NaN; + + return nextValue; + } + else + nextValue = Double.POSITIVE_INFINITY; + return values[pos]; } ! ! double get( long preciseTime, long[] reducedTimestamps ) ! { ! long t = Util.normalize( preciseTime, step ); ! t = ( t < preciseTime ? t + step : t ); ! ! while ( stPos < reducedTimestamps.length - 1 ) ! { ! if ( reducedTimestamps[ stPos + 1 ] <= t ) ! stPos++; ! else ! return get( stPos ); ! } ! ! if ( stPos < reducedTimestamps.length && reducedTimestamps[stPos] <= t ) ! return get( stPos ); ! ! return Double.NaN; ! } ! /** * Gets a specific aggregate of this datasource. *************** *** 157,160 **** --- 224,230 ---- private void aggregate( long time, double value ) { + if ( Double.isInfinite(value) ) + return; + min = Util.min( min, value ); max = Util.max( max, value ); Index: FetchSource.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/graph/FetchSource.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** FetchSource.java 4 Jul 2004 09:54:32 -0000 1.8 --- FetchSource.java 9 Jul 2004 12:22:15 -0000 1.9 *************** *** 165,169 **** * @throws RrdException Thrown in case of a JRobin specific error. */ ! protected ValueExtractor fetch ( long startTime, long endTime, long resolution ) throws IOException, RrdException { if ( rrd == null ) --- 165,169 ---- * @throws RrdException Thrown in case of a JRobin specific error. */ ! protected ValueExtractor fetch ( long startTime, long endTime, long resolution, int reduceFactor ) throws IOException, RrdException { if ( rrd == null ) *************** *** 197,202 **** // Fetch datasources FetchRequest request = rrd.createFetchRequest( cfNames[i], startTime, endTime + rrdStep, resolution ); request.setFilter( dsNames ); ! FetchData data = request.fetchData(); --- 197,204 ---- // Fetch datasources FetchRequest request = rrd.createFetchRequest( cfNames[i], startTime, endTime + rrdStep, resolution ); + long arcStep = rrd.findMatchingArchive( request ).getArcStep(); + request = rrd.createFetchRequest( cfNames[i], startTime, endTime + arcStep, resolution ); request.setFilter( dsNames ); ! FetchData data = request.fetchData(); *************** *** 209,213 **** } ! return new ValueExtractor( names, result ); } --- 211,215 ---- } ! return new ValueExtractor( names, result, reduceFactor ); } *************** *** 296,300 **** openRrd(); ! long maxSampleTime = 0, sampleTime = 0; for ( int i = 0; i < datasources.length; i++ ) --- 298,302 ---- openRrd(); ! long minSampleTime = Long.MAX_VALUE, sampleTime = 0; for ( int i = 0; i < datasources.length; i++ ) *************** *** 303,313 **** { sampleTime = rrd.findStartMatchArchive( cfNames[i], startTime, resolution ).getEndTime(); ! if ( sampleTime > maxSampleTime ) ! maxSampleTime = sampleTime; } } ! // Remove a single sample step (we'll add it again later on) ! return maxSampleTime - rrdDef.getStep(); } --- 305,349 ---- { sampleTime = rrd.findStartMatchArchive( cfNames[i], startTime, resolution ).getEndTime(); ! ! if ( sampleTime < minSampleTime ) ! minSa... [truncated message content] |