📄 grapher.java
字号:
/* ============================================================
* JRobin : Pure java implementation of RRDTool's functionality
* ============================================================
*
* Project Info: http://www.jrobin.org
* Project Lead: Sasa Markovic (saxon@jrobin.org)
*
* Developers: Sasa Markovic (saxon@jrobin.org)
* Arne Vandamme (cobralord@jrobin.org)
*
* (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 net.jumperz.ext.org.jrobin.graph;
import java.io.File;
import java.io.IOException;
import java.util.*;
import javax.imageio.ImageIO;
import java.awt.Font;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.BasicStroke;
import java.awt.RenderingHints;
import java.awt.image.RenderedImage;
import java.awt.image.BufferedImage;
import net.jumperz.ext.org.jrobin.core.RrdException;
/**
* <p>Creates a BufferedImage of a graph, based on data from a GraphDef.</p>
*
* @author Arne Vandamme (cobralord@jrobin.org)
*/
class Grapher extends RrdExporter
{
// ================================================================
// -- Members
// ================================================================
protected static final String SPACER = " "; // default comment spacer (two blank spaces)
protected static final int GRAPH_RESOLUTION = 400; // default graph resolution
protected static final int DEFAULT_WIDTH = 400; // default width in pixels of the chart area
protected static final int DEFAULT_HEIGHT = 100; // default height in pixels of the chart area
// Border space definitions
protected static final int UBORDER_SPACE = 10; // padding from graph upper border
protected static final int BBORDER_SPACE = 10; // padding from graph lower border
protected static final int LBORDER_SPACE = 10; // padding from graph left border
protected static final int RBORDER_SPACE = 13; // padding from graph right border
protected static final int CHART_UPADDING = 5; // padding space above the chart area
protected static final int CHART_BPADDING = 25; // default padding space below the chart area
protected static final int CHART_RPADDING = 10; // padding space on the right of the chart area
protected static final int CHART_LPADDING = 50; // default padding space on the left of the chart area
protected static final int CHART_BPADDING_NM = 10; // default padding below chart if no legend markers
protected static final int CHART_LPADDING_NM = 10; // default padding left of chart if no legend markers
protected static final int LINE_PADDING = 4; // default padding between two consecutive text lines
// Default fonts
protected static final Font TITLE_FONT = new Font("Lucida Sans Typewriter", Font.BOLD, 12);
protected static final Font NORMAL_FONT = new Font("Lucida Sans Typewriter", Font.PLAIN, 10);
private Font title_font = TITLE_FONT; // font used for the title
private Font normal_font = NORMAL_FONT; // font used for all default text
private Color normalFontColor = null;
private int numPoints = GRAPH_RESOLUTION; // number of points used to calculate the graph
private int chart_lpadding, chart_bpadding; // calculated padding on the left and below the chart area
private int imgWidth, imgHeight; // dimensions of the entire image
private int chartWidth, chartHeight; // dimensions of the chart area within the image
private int nfont_width, nfont_height, tfont_width, tfont_height; // font dimennsion specs (approximated)
private int commentBlock; // size in pixels of the block below the chart itself
private int graphOriginX, graphOriginY, x_offset, y_offset;
private RrdGraphDef graphDef;
private PlotDef[] plotDefs;
private long[] tsChart;
private ValueFormatter valueFormat;
private BasicStroke defaultStroke;
private ValueGrid vGrid;
private TimeGrid tGrid;
// ================================================================
// -- Constructors
// ================================================================
/**
* Constructs a grapher object, used for creating a graph image based on a <code>RrdGraphDef</code> object.
* A reference to a <code>RrdGraph</code> object is kept for <code>RrdDb</code> pooling.
* @param graphDef Graph definition for the graph to be created.
* @param rrdGraph RrdGraph object that takes care of saving the images.
*/
Grapher( RrdGraphDef graphDef, RrdGraph rrdGraph )
{
super( graphDef, rrdGraph );
this.graphDef = graphDef;
// Set font dimension specifics
if ( graphDef.getDefaultFont() != null )
normal_font = graphDef.getDefaultFont();
if ( graphDef.getTitleFont() != null )
title_font = graphDef.getTitleFont();
normalFontColor = graphDef.getDefaultFontColor();
nfont_height = normal_font.getSize(); // Determine font dimensions for regular comment font
nfont_width = nfont_height / 2 + 1;
// Bold font is higher
tfont_height = ( title_font.isBold() ? title_font.getSize() + 2 : title_font.getSize() );
tfont_width = ( title_font.isBold() ? tfont_height / 2 : tfont_height / 2 + 1 );
// Create the shared valueformatter
valueFormat = new ValueFormatter( graphDef.getBaseValue(), graphDef.getScaleIndex() );
// Set default graph stroke
defaultStroke = new BasicStroke();
startTime = graphDef.getStartTime();
endTime = graphDef.getStartTime();
}
// ================================================================
// -- Protected (package) methods
// ================================================================
/**
* Calculates the graph and chart dimensions.
* @param cWidth Width of the chart area in pixels.
* @param cHeight Height of the chart area in pixels.
*/
private void calculateDimensions( int cWidth, int cHeight )
{
// Calculate chart dimensions
chartWidth = ( cWidth == 0 ? DEFAULT_WIDTH : cWidth );
chartHeight = ( cHeight == 0 ? DEFAULT_HEIGHT : cHeight );
if ( cWidth > 0 ) numPoints = cWidth;
// Padding depends on grid visibility
chart_lpadding = ( graphDef.showMajorGridY() ? graphDef.getChartLeftPadding() : CHART_LPADDING_NM );
chart_bpadding = ( graphDef.showMajorGridX() ? CHART_BPADDING : CHART_BPADDING_NM );
// Size of all lines below chart
commentBlock = 0;
if ( graphDef.showLegend() )
commentBlock = graphDef.getCommentLineCount() * (nfont_height + LINE_PADDING) - LINE_PADDING;
// x_offset and y_offset define the starting corner of the actual graph
x_offset = LBORDER_SPACE;
if ( graphDef.getVerticalLabel() != null )
x_offset += nfont_height + LINE_PADDING;
imgWidth = chartWidth + x_offset + RBORDER_SPACE + chart_lpadding + CHART_RPADDING;
y_offset = UBORDER_SPACE;
if ( graphDef.getTitle() != null ) // Title *always* gets a extra LF automatically
y_offset += ((tfont_height + LINE_PADDING) * graphDef.getTitle().getLineCount() + tfont_height) + LINE_PADDING;
imgHeight = chartHeight + commentBlock + y_offset + BBORDER_SPACE + CHART_UPADDING + CHART_BPADDING;
}
/**
* Calculates the graph and chart dimensions.
* @param cWidth Width of the entire image in pixels.
* @param cHeight Height of the entire image in pixels.
*/
private void calculateDimensionsGlobal( int cWidth, int cHeight )
{
imgWidth = cWidth;
imgHeight = cHeight;
if ( cWidth > 0 ) numPoints = cWidth;
// Padding depends on grid visibility
chart_lpadding = ( graphDef.showMajorGridY() ? graphDef.getChartLeftPadding() : CHART_LPADDING_NM );
chart_bpadding = ( graphDef.showMajorGridX() ? CHART_BPADDING : CHART_BPADDING_NM );
// Size of all lines below chart
commentBlock = 0;
if ( graphDef.showLegend() )
commentBlock = graphDef.getCommentLineCount() * (nfont_height + LINE_PADDING) - LINE_PADDING;
// x_offset and y_offset define the starting corner of the actual graph
x_offset = LBORDER_SPACE;
if ( graphDef.getVerticalLabel() != null )
x_offset += nfont_height + LINE_PADDING;
chartWidth = imgWidth - x_offset - RBORDER_SPACE - chart_lpadding - CHART_RPADDING;
y_offset = UBORDER_SPACE;
if ( graphDef.getTitle() != null ) // Title *always* gets a extra LF automatically
y_offset += ((tfont_height + LINE_PADDING) * graphDef.getTitle().getLineCount() + tfont_height) + LINE_PADDING;
chartHeight = imgHeight - commentBlock - y_offset - BBORDER_SPACE - CHART_UPADDING - CHART_BPADDING;
}
/**
* Creates the actual graph based on the GraphDef definition.
* The graph is created as a <code>java.awt.image.BufferedImage</code>.
* @param cWidth Width of the chart area in pixels.
* @param cHeight Height of the chart area in pixels.
* @return The created graph as a BufferedImage.
* @throws RrdException Thrown in case of a JRobin specific error.
* @throws IOException Thrown in case of a I/O related error.
*/
protected BufferedImage createImage( int cWidth, int cHeight, int colorType ) throws RrdException, IOException
{
calculateDimensions( cWidth, cHeight );
// Create graphics object
BufferedImage bImg = new BufferedImage( imgWidth, imgHeight, colorType );
Graphics2D graphics = (Graphics2D) bImg.getGraphics();
render( graphics );
// Dispose graphics context
graphics.dispose();
return bImg;
}
/**
* Creates the actual graph based on the GraphDef definition.
* The graph is created as a <code>java.awt.image.BufferedImage</code>.
* @param cWidth Width of the entire image in pixels.
* @param cHeight Height of the entire image in pixels.
* @return The created graph as a BufferedImage.
* @throws RrdException Thrown in case of a JRobin specific error.
* @throws IOException Thrown in case of a I/O related error.
*/
protected BufferedImage createImageGlobal( int cWidth, int cHeight, int colorType ) throws RrdException, IOException
{
calculateDimensionsGlobal( cWidth, cHeight );
// Create graphics object
BufferedImage bImg = new BufferedImage( imgWidth, imgHeight, colorType );
Graphics2D graphics = (Graphics2D) bImg.getGraphics();
render( graphics );
// Dispose graphics context
graphics.dispose();
return bImg;
}
/**
* Creates the actual graph based on the GraphDef definition.
* The graph is rendered on the Graphics2D object passed as a parameter.
* @param cWidth Width of the entire image in pixels.
* @param cHeight Height of the entire image in pixels.
* @param graphics The handle to the Graphics2D object to render the graph on.
* @param useGlobal True if the dimensions specified are those of the entire image.
* @throws RrdException Thrown in case of a JRobin specific error.
* @throws IOException Thrown in case of a I/O related error.
*/
protected void renderImage( int cWidth, int cHeight, Graphics2D graphics, boolean useGlobal ) throws RrdException, IOException
{
if ( useGlobal )
calculateDimensionsGlobal( cWidth, cHeight );
else
calculateDimensions( cWidth, cHeight );
render( graphics );
}
/**
* If the lazy flag of the GraphDef has been set, this method will
* check the most recent update stamp of the FetchSources, and return
* true if the update timestamp is larger than the timestamp of the
* previous graph generation (passed on as a parameter).
*
* @param prevGenTime Timestamp of the previous graph generation.
* @return True if the graph should be generated, false if not.
*/
protected boolean shouldGenerate( long prevGenTime ) throws RrdException, IOException
{
FetchSourceList fetchSources = graphDef.getFetchSources();
fetchSources.setRrdOpener( getRrdOpener() );
fetchSources.openAll();
if ( graphDef.isLazy() && fetchSources.getLastUpdateTime() * 1000 < prevGenTime )
{
// Should not generate, release immediately
fetchSources.releaseAll();
return false;
}
return true;
}
// ================================================================
// -- Private methods
// ================================================================
/**
* Renders the actual graph onto the specified Graphics2D object
* @param graphics The handle to the Graphics2D object to render the graph on.
* @throws RrdException Thrown in case of a JRobin specific error.
* @throws IOException Thrown in case of a I/O related error.
*/
private void render( Graphics2D graphics ) throws RrdException, IOException
{
// Do the actual graphing
calculateSeries(); // calculate all datasources
plotImageBackground( graphics ); // draw the image background
plotChart( graphics ); // draw the actual chart
plotComments( graphics ); // draw all comment lines
plotOverlay( graphics ); // draw a possible image overlay
plotSignature( graphics ); // draw the JRobin signature
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -