⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rrdgraph.java

📁 jrobin,使用纯java实现的RRD数据库,使用RRD数据库来统计数据.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* ============================================================
 * 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)
 *
 *
 * (C) Copyright 2003-2005, 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 org.jrobin.core.RrdException;
import org.jrobin.core.Util;
import org.jrobin.data.DataProcessor;

import javax.swing.*;
import java.awt.*;
import java.io.IOException;

/**
 * Class which actually creates JRobin graphs (does the hard work).
 */
public class RrdGraph implements RrdGraphConstants {
	RrdGraphDef gdef;
	ImageParameters im = new ImageParameters();
	DataProcessor dproc;
	ImageWorker worker;
	Mapper mapper;
	RrdGraphInfo info = new RrdGraphInfo();

	/**
	 * Creates graph from the corresponding {@link RrdGraphDef} object.
	 *
	 * @param gdef Graph definition
	 * @throws IOException  Thrown in case of I/O error
	 * @throws RrdException Thrown in case of JRobin related error
	 */
	public RrdGraph(RrdGraphDef gdef) throws IOException, RrdException {
		this.gdef = gdef;
		worker = new ImageWorker(100, 100); // Dummy worker, just to start with something
		try {
			createGraph();
		}
		finally {
			worker.dispose();
			worker = null;
			dproc = null;
		}
	}

	/**
	 * Returns complete graph information in a single object.
	 *
	 * @return Graph information (width, height, filename, image bytes, etc...)
	 */
	public RrdGraphInfo getRrdGraphInfo() {
		return info;
	}

	private void createGraph() throws RrdException, IOException {
		boolean lazy = lazyCheck();
		if (!lazy || gdef.printStatementCount() != 0) {
			fetchData();
			resolveTextElements();
			if (gdef.shouldPlot() && !lazy) {
				calculatePlotValues();
				findMinMaxValues();
				identifySiUnit();
				expandValueRange();
				removeOutOfRangeRules();
				initializeLimits();
				placeLegends();
				createImageWorker();
				drawBackground();
				drawAxis();
				drawData();
				drawGrid();
				drawText();
				drawLegend();
				drawRules();
				gator();
				drawOverlay();
				saveImage();
			}
		}
		collectInfo();
	}

	private void collectInfo() {
		info.filename = gdef.filename;
		info.width = im.xgif;
		info.height = im.ygif;
		for (CommentText comment : gdef.comments) {
			if (comment instanceof PrintText) {
				PrintText pt = (PrintText) comment;
				if (pt.isPrint()) {
					info.addPrintLine(pt.resolvedText);
				}
			}
		}
		if (gdef.imageInfo != null) {
			info.imgInfo = Util.sprintf(gdef.imageInfo, gdef.filename, im.xgif, im.ygif);
		}
	}

	private void saveImage() throws IOException {
		if (!gdef.filename.equals("-")) {
			info.bytes = worker.saveImage(gdef.filename, gdef.imageFormat, gdef.imageQuality);
		}
		else {
			info.bytes = worker.getImageBytes(gdef.imageFormat, gdef.imageQuality);
		}
	}

	private void drawOverlay() throws IOException {
		if (gdef.overlayImage != null) {
			worker.loadImage(gdef.overlayImage);
		}
	}

	private void gator() {
		if (!gdef.onlyGraph && gdef.showSignature) {
			Font font = new Font(DEFAULT_FONT_NAME, Font.PLAIN, 9);
			int x = (int) (im.xgif - 2 - worker.getFontAscent(font));
			int y = 4;
			worker.transform(x, y, Math.PI / 2);
			worker.drawString("Created with JRobin", 0, 0, font, Color.LIGHT_GRAY);
			worker.reset();
		}
	}

	private void drawRules() {
		worker.clip(im.xorigin + 1, im.yorigin - gdef.height - 1, gdef.width - 1, gdef.height + 2);
		for (PlotElement pe : gdef.plotElements) {
			if (pe instanceof HRule) {
				HRule hr = (HRule) pe;
				if (hr.value >= im.minval && hr.value <= im.maxval) {
					int y = mapper.ytr(hr.value);
					worker.drawLine(im.xorigin, y, im.xorigin + im.xsize, y, hr.color, new BasicStroke(hr.width));
				}
			}
			else if (pe instanceof VRule) {
				VRule vr = (VRule) pe;
				if (vr.timestamp >= im.start && vr.timestamp <= im.end) {
					int x = mapper.xtr(vr.timestamp);
					worker.drawLine(x, im.yorigin, x, im.yorigin - im.ysize, vr.color, new BasicStroke(vr.width));
				}
			}
		}
		worker.reset();
	}

	private void drawText() {
		if (!gdef.onlyGraph) {
			if (gdef.title != null) {
				int x = im.xgif / 2 - (int) (worker.getStringWidth(gdef.title, gdef.largeFont) / 2);
				int y = PADDING_TOP + (int) worker.getFontAscent(gdef.largeFont);
				worker.drawString(gdef.title, x, y, gdef.largeFont, gdef.colors[COLOR_FONT]);
			}
			if (gdef.verticalLabel != null) {
				int x = PADDING_LEFT;
				int y = im.yorigin - im.ysize / 2 + (int) worker.getStringWidth(gdef.verticalLabel, gdef.smallFont) / 2;
				int ascent = (int) worker.getFontAscent(gdef.smallFont);
				worker.transform(x, y, -Math.PI / 2);
				worker.drawString(gdef.verticalLabel, 0, ascent, gdef.smallFont, gdef.colors[COLOR_FONT]);
				worker.reset();
			}
		}
	}

	private void drawGrid() {
		if (!gdef.onlyGraph) {
			Paint shade1 = gdef.colors[COLOR_SHADEA], shade2 = gdef.colors[COLOR_SHADEB];
			Stroke borderStroke = new BasicStroke(1);
			worker.drawLine(0, 0, im.xgif - 1, 0, shade1, borderStroke);
			worker.drawLine(1, 1, im.xgif - 2, 1, shade1, borderStroke);
			worker.drawLine(0, 0, 0, im.ygif - 1, shade1, borderStroke);
			worker.drawLine(1, 1, 1, im.ygif - 2, shade1, borderStroke);
			worker.drawLine(im.xgif - 1, 0, im.xgif - 1, im.ygif - 1, shade2, borderStroke);
			worker.drawLine(0, im.ygif - 1, im.xgif - 1, im.ygif - 1, shade2, borderStroke);
			worker.drawLine(im.xgif - 2, 1, im.xgif - 2, im.ygif - 2, shade2, borderStroke);
			worker.drawLine(1, im.ygif - 2, im.xgif - 2, im.ygif - 2, shade2, borderStroke);
			if (gdef.drawXGrid) {
				new TimeAxis(this).draw();
			}
			if (gdef.drawYGrid) {
				boolean ok;
				if (gdef.altYMrtg) {
					ok = new ValueAxisMrtg(this).draw();
				}
				else if (gdef.logarithmic) {
					ok = new ValueAxisLogarithmic(this).draw();
				}
				else {
					ok = new ValueAxis(this).draw();
				}
				if (!ok) {
					String msg = "No Data Found";
					worker.drawString(msg,
							im.xgif / 2 - (int) worker.getStringWidth(msg, gdef.largeFont) / 2,
							(2 * im.yorigin - im.ysize) / 2,
							gdef.largeFont, gdef.colors[COLOR_FONT]);
				}
			}
		}
	}

	private void drawData() throws RrdException {
		worker.setAntiAliasing(gdef.antiAliasing);
		worker.clip(im.xorigin + 1, im.yorigin - gdef.height - 1, gdef.width - 1, gdef.height + 2);
		double areazero = mapper.ytr((im.minval > 0.0) ? im.minval : (im.maxval < 0.0) ? im.maxval : 0.0);
		double[] x = xtr(dproc.getTimestamps()), lastY = null;
		// draw line, area and stack
		for (PlotElement plotElement : gdef.plotElements) {
			if (plotElement instanceof SourcedPlotElement) {
				SourcedPlotElement source = (SourcedPlotElement) plotElement;
				double[] y = ytr(source.getValues());
				if (source instanceof Line) {
					worker.drawPolyline(x, y, source.color, new BasicStroke(((Line) source).width));
				}
				else if (source instanceof Area) {
					worker.fillPolygon(x, areazero, y, source.color);
				}
				else if (source instanceof Stack) {
					Stack stack = (Stack) source;
					float width = stack.getParentLineWidth();
					if (width >= 0F) {
						// line
						worker.drawPolyline(x, y, stack.color, new BasicStroke(width));
					}
					else {
						// area
						worker.fillPolygon(x, lastY, y, stack.color);
						worker.drawPolyline(x, lastY, stack.getParentColor(), new BasicStroke(0));
					}
				}
				else {
					// should not be here
					throw new RrdException("Unknown plot source: " + source.getClass().getName());
				}
				lastY = y;
			}
		}
		worker.reset();
		worker.setAntiAliasing(false);
	}

	private void drawAxis() {
		if (!gdef.onlyGraph) {
			Paint gridColor = gdef.colors[COLOR_GRID];
			Paint fontColor = gdef.colors[COLOR_FONT];
			Paint arrowColor = gdef.colors[COLOR_ARROW];
			Stroke stroke = new BasicStroke(1);
			worker.drawLine(im.xorigin + im.xsize, im.yorigin, im.xorigin + im.xsize, im.yorigin - im.ysize,
					gridColor, stroke);
			worker.drawLine(im.xorigin, im.yorigin - im.ysize, im.xorigin + im.xsize, im.yorigin - im.ysize,
					gridColor, stroke);
			worker.drawLine(im.xorigin - 4, im.yorigin, im.xorigin + im.xsize + 4, im.yorigin,
					fontColor, stroke);
			worker.drawLine(im.xorigin, im.yorigin, im.xorigin, im.yorigin - im.ysize,
					gridColor, stroke);
			worker.drawLine(im.xorigin + im.xsize + 4, im.yorigin - 3, im.xorigin + im.xsize + 4, im.yorigin + 3,
					arrowColor, stroke);
			worker.drawLine(im.xorigin + im.xsize + 4, im.yorigin - 3, im.xorigin + im.xsize + 9, im.yorigin,
					arrowColor, stroke);
			worker.drawLine(im.xorigin + im.xsize + 4, im.yorigin + 3, im.xorigin + im.xsize + 9, im.yorigin,
					arrowColor, stroke);
		}
	}

	private void drawBackground() throws IOException {
		worker.fillRect(0, 0, im.xgif, im.ygif, gdef.colors[COLOR_BACK]);
		if (gdef.backgroundImage != null) {
			worker.loadImage(gdef.backgroundImage);
		}
		worker.fillRect(im.xorigin, im.yorigin - im.ysize, im.xsize, im.ysize, gdef.colors[COLOR_CANVAS]);
	}

	private void createImageWorker() {
		worker.resize(im.xgif, im.ygif);
	}

	private void placeLegends() {
		if (!gdef.noLegend && !gdef.onlyGraph) {
			int border = (int) (getSmallFontCharWidth() * PADDING_LEGEND);
			LegendComposer lc = new LegendComposer(this, border, im.ygif, im.xgif - 2 * border);
			im.ygif = lc.placeComments() + PADDING_BOTTOM;
		}
	}

	private void initializeLimits() throws RrdException {
		im.xsize = gdef.width;
		im.ysize = gdef.height;
		im.unitslength = gdef.unitsLength;
		if (gdef.onlyGraph) {
			if (im.ysize > 64) {
				throw new RrdException("Cannot create graph only, height too big");
			}
			im.xorigin = 0;
		}
		else {
			im.xorigin = (int) (PADDING_LEFT + im.unitslength * getSmallFontCharWidth());
		}
		if (gdef.verticalLabel != null) {
			im.xorigin += getSmallFontHeight();
		}
		if (gdef.onlyGraph) {
			im.yorigin = im.ysize;
		}
		else {
			im.yorigin = PADDING_TOP + im.ysize;
		}
		mapper = new Mapper(this);
		if (gdef.title != null) {
			im.yorigin += getLargeFontHeight() + PADDING_TITLE;
		}
		if (gdef.onlyGraph) {
			im.xgif = im.xsize;
			im.ygif = im.yorigin;
		}
		else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -