📄 grapher.java
字号:
// Dispose graphics context
graphics.dispose();
}
/**
* 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.
*/
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;
}
}
/**
* Draws the image background, title and value axis label.
* @param g Handle of a Graphics2D context to draw on.
*/
private void plotImageBackground( Graphics2D g )
{
// Draw general background color
g.setColor( graphDef.getBackColor() );
g.fillRect(0, 0, imgWidth, imgHeight );
// Draw a background image, if background image fails, just continue
try {
File bgImage = graphDef.getBackground();
if ( bgImage != null ) {
RenderedImage img = ImageIO.read(bgImage);
g.drawRenderedImage( img, null );
}
} catch (IOException e) {}
// Set the image border
Color bc = graphDef.getBorderColor();
BasicStroke bs = graphDef.getBorderStroke();
if ( bs != null && bc != null ) // custom single line border
{
g.setColor( bc );
g.setStroke( bs );
// Check for 'visible' line width
int w = new Float(bs.getLineWidth()).intValue();
if ( w > 0 )
g.drawRect( w / 2, w / 2, imgWidth - w, imgHeight - w);
g.setStroke( defaultStroke );
}
else // default slightly beveled border
{
g.setColor( new Color( 0xdc, 0xdc, 0xdc ) );
g.fillRect( 0, 0, 2, imgHeight - 1 );
g.fillRect( 0, 0, imgWidth - 1, 2 );
g.setColor( Color.GRAY );
g.drawLine( 0, imgHeight - 1, imgWidth, imgHeight - 1 );
g.drawLine( imgWidth - 1, 0, imgWidth - 1, imgHeight );
g.drawLine( 1, imgHeight - 2, imgWidth, imgHeight - 2 );
g.drawLine( imgWidth - 2, 1, imgWidth - 2, imgHeight );
}
plotImageTitle( g );
plotVerticalLabel( g );
}
/**
* Plots all datasources on the graph, uses all values gathered in {@link #calculateSeries() }.
* @param graphics Handle of a Graphics2D context to draw on.
* @throws RrdException Thrown in case of a JRobin specific error.
*/
private void plotChart( Graphics2D graphics ) throws RrdException
{
int lux = x_offset + chart_lpadding;
int luy = y_offset + CHART_UPADDING;
// Canvas color should only be drawn if no background image is set
// If there's a background image, canvas should be transparent
if ( graphDef.getBackground() == null ) {
graphics.setColor( graphDef.getCanvasColor() );
graphics.fillRect( lux, luy, chartWidth, chartHeight );
}
// Draw the chart area frame
graphics.setColor( graphDef.getFrameColor() );
graphics.drawRect( lux, luy, chartWidth, chartHeight );
double val;
double[] tmpSeries = new double[numPoints];
boolean rigid = false;
double lowerValue = Double.MAX_VALUE;
double upperValue = Double.MIN_VALUE;
GridRange range = graphDef.getGridRange();
if ( range != null )
{
rigid = range.isRigid();
lowerValue = range.getLowerValue();
upperValue = range.getUpperValue();
if ( Double.isNaN(lowerValue) ) lowerValue = Double.MAX_VALUE;
if ( Double.isNaN(upperValue) ) upperValue = Double.MIN_VALUE;
}
// For autoscale, detect lower and upper limit of values
for ( int i = 0; i < plotDefs.length; i++ )
{
Source src = plotDefs[i].getSource();
// Only try autoscale when we do not have a rigid grid
if ( !rigid && src != null )
{
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 )
{
if ( plotDefs[i - 1].plotType == PlotDef.PLOT_STACK ) { // Use this source plus stack of previous ones
for (int j = 0; j < tmpSeries.length; j++)
{
val = tmpSeries[j] + plotDefs[i].getValue(j, timestamps);
if ( val < lowerValue ) lowerValue = val;
if ( val > upperValue ) upperValue = val;
tmpSeries[j] = val;
}
}
else { // Use this source plus the previous one
for (int j = 0; j < tmpSeries.length; j++)
{
val = plotDefs[i - 1].getValue(j, timestamps) + plotDefs[i].getValue(j, timestamps);
if ( val < lowerValue ) lowerValue = val;
if ( val > upperValue ) upperValue = val;
tmpSeries[j] = val;
}
}
}
else // Only use min/max of a single datasource
{
if ( min < lowerValue ) lowerValue = min;
if ( max > upperValue ) upperValue = max;
}
}
}
vGrid = new ValueGrid( range, lowerValue, upperValue, graphDef.getValueAxis(), graphDef.getBaseValue() );
tGrid = new TimeGrid( startTime, endTime, graphDef.getTimeAxis(), graphDef.getFirstDayOfWeek() );
lowerValue = vGrid.getLowerValue();
upperValue = vGrid.getUpperValue();
// Use a special graph 'object' that takes care of resizing and reversing y coordinates
ChartGraphics g = new ChartGraphics( graphics );
g.setDimensions( chartWidth, chartHeight );
g.setXRange( tGrid.getStartTime(), tGrid.getEndTime() );
g.setYRange( lowerValue, upperValue );
// Set the chart origin point
double diff = 1.0d;
if ( lowerValue < 0 )
diff = 1.0d - ( lowerValue / ( -upperValue + lowerValue ));
graphOriginX = lux;
graphOriginY = new Double(luy + chartHeight * diff).intValue();
// If the grid is behind the plots, draw it first
if ( !graphDef.isFrontGrid() ) plotChartGrid( g );
// Use AA if necessary
if ( graphDef.useAntiAliasing() )
graphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
// Prepare clipping area and origin
graphics.setClip( lux, luy, chartWidth, chartHeight);
graphics.translate( graphOriginX, graphOriginY );
int lastPlotType = PlotDef.PLOT_LINE;
double[] parentSeries = new double[tsChart.length];
// 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
for ( int i = 0; i < plotDefs.length; i++ )
{
plotDefs[i].draw( g, xValues, parentSeries, lastPlotType );
if( plotDefs[i].plotType != PlotDef.PLOT_STACK )
lastPlotType = plotDefs[i].plotType;
}
// Reset clipping area, origin and AA settings
graphics.translate( -graphOriginX, -graphOriginY );
graphics.setClip( 0, 0, imgWidth, imgHeight);
graphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
// If the grid is in front of the plots, draw it now
if ( graphDef.isFrontGrid() ) plotChartGrid( g );
}
/**
* Plots the chart grid on the graph, both value and time axis minor and major grid lines.
* Accompanied by approriate labels at defined intervals.
* @param chartGraph ChartGraphics object containing a Graphics2D handle to draw on.
*/
private void plotChartGrid( ChartGraphics chartGraph )
{
Graphics2D g = chartGraph.getGraphics();
g.setFont( normal_font );
int lux = x_offset + chart_lpadding;
int luy = y_offset + CHART_UPADDING;
boolean minorX = graphDef.showMinorGridX();
boolean minorY = graphDef.showMinorGridY();
boolean majorX = graphDef.showMajorGridX();
boolean majorY = graphDef.showMajorGridY();
Color minColor = graphDef.getMinorGridColor();
Color majColor = graphDef.getMajorGridColor();
// Dashed line
float[] dashPattern = { 1, 1 };
BasicStroke dStroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10,
dashPattern, 0);
// Draw basic axis
int tmpx = lux + chartWidth;
int tmpy = luy + chartHeight;
// Draw X axis with arrow
g.setColor( graphDef.getAxisColor() );
g.drawLine( lux - 4, tmpy, tmpx + 4, tmpy );
g.setColor( graphDef.getArrowColor() );
g.drawLine( tmpx + 4, tmpy - 3, tmpx + 4, tmpy + 3 );
g.drawLine( tmpx + 4, tmpy - 3, tmpx + 9, tmpy );
g.drawLine( tmpx + 4, tmpy + 3, tmpx + 9, tmpy );
// Draw X axis time grid and labels
if ( graphDef.showGridX() )
{
TimeMarker[] timeList = tGrid.getTimeMarkers();
boolean labelCentered = tGrid.centerLabels();
long labelGridWidth = tGrid.getMajorGridWidth();
int pixWidth = 0;
if ( labelCentered )
pixWidth = ( chartGraph.getX( labelGridWidth ) - chartGraph.getX( 0 ) );
for (int i = 0; i < timeList.length; i++)
{
long secTime = timeList[i].getTimestamp();
int posRel = chartGraph.getX(secTime);
int pos = lux + posRel;
String label = timeList[i].getLabel();
if ( posRel >= 0 ) {
if ( majorX && timeList[i].isLabel() )
{
g.setColor( majColor );
g.setStroke( dStroke );
g.drawLine( pos, luy, pos, luy + chartHeight );
g.setStroke( defaultStroke );
g.drawLine( pos, luy - 2, pos, luy + 2 );
g.drawLine( pos, luy + chartHeight - 2, pos, luy + chartHeight + 2 );
// Only draw label itself if we are far enough from the side axis
// Use extra 2 pixel padding (3 pixels from border total at least)
int txtDistance = (label.length() * nfont_width) / 2;
if ( labelCentered )
{
if ( pos + pixWidth <= lux + chartWidth )
graphString( g, label, pos + 2 + pixWidth/2 - txtDistance, luy + chartHeight + nfont_height + LINE_PADDING );
}
else if ( (pos - lux > txtDistance + 2) && (pos + txtDistance + 2 < lux + chartWidth) )
graphString( g, label, pos - txtDistance, luy + chartHeight + nfont_height + LINE_PADDING );
}
else if ( minorX )
{
g.setColor( minColor );
g.setStroke( dStroke );
g.drawLine( pos, luy, pos, luy + chartHeight );
g.setStroke( defaultStroke );
g.drawLine( pos, luy - 1, pos, luy + 1 );
g.drawLine( pos, luy + chartHeight - 1, pos, luy + chartHeight + 1 );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -