rrd4j是个开源的类似Jfreechar的工具..但是我想说的是,这个工具好的地方是因为其建立图形的线都是由很多个细小的点构成的..因为很多所以看起来就像线了。
废话不多说.就拿里面的例子来说..同时加上我的理解....OK
public class Demo {
static final long SEED = 1909752002L;
static final Random RANDOM = new Random();
static final String FILE ="demo";
static final long START = Util.getTimestamp(2010,4,1);
static final long END = Util.getTimestamp(2010, 6, 1); //年、月、日 .解析时间
static final int MAX_STEP = 300;
static final int IMG_WIDTH =500;
static final int IMG_HEIGHT =300;
public static void main(String[] args) throws Exception {
System.out.println("=== Starting demo ====");
System.out.println("start: "+START+"\tend:"+END+"\t"+START+"-"+END+"="+(END-START));
long startMillis = System.currentTimeMillis();
String factory = "FILE"; //设置文件的保存方式 1.FILE 文件形式 2.SAFE 线程安全 3.NIO 缓冲区 4.MEMORY 内存
RrdDb.setDefaultFactory(factory);
long start = START;
long end = END;
String rrdPath = Util.getRrd4jDemoPath(FILE+".rrd"); //文件路径
String imgPath = Util.getRrd4jDemoPath(FILE+".png");
//创建
System.out.println("== Creating RRD file "+ rrdPath);
RrdDef rrdDef = new RrdDef(rrdPath, start - 1, 300); //新建一个RRD定义对象,给定路径,开始时间以及时间间隔
rrdDef.setVersion(2); //文件版本
//DsType包含4个参数 ABSOLUTE COUNTER DERIVE GAUGE
rrdDef.addDatasource("sun", DsType.GAUGE, 600, 0, Double.NaN); //单一数据源添加到RRD定义通过指定它的数据源名称、源类型、心跳、最小和最大的值。
rrdDef.addDatasource("shade", DsType.GAUGE, 600, 0, Double.NaN);
//ConsolFun 被存储存储数据的平均 TOTAL 总的数据点存储 MAX最大的数据点存储
rrdDef.addArchive(ConsolFun.AVERAGE, 0.5, 1, 600); //consolFun 合并函数 xff: x档案的元素.有效的值在0和1之间。 steps: 数量的存步伐 rows数量的存档行
rrdDef.addArchive(ConsolFun.AVERAGE, 0.5, 6, 700);
rrdDef.addArchive(ConsolFun.AVERAGE, 0.5, 24, 775);
rrdDef.addArchive(ConsolFun.AVERAGE, 0.5, 288, 797);
rrdDef.addArchive(ConsolFun.TOTAL, 0.5, 1, 600);
rrdDef.addArchive(ConsolFun.TOTAL, 0.5, 6, 700);
rrdDef.addArchive(ConsolFun.TOTAL, 0.5, 24, 775);
rrdDef.addArchive(ConsolFun.TOTAL, 0.5, 288, 797);
rrdDef.addArchive(ConsolFun.MAX, 0.5, 1, 600);
rrdDef.addArchive(ConsolFun.MAX, 0.5, 6, 700);
rrdDef.addArchive(ConsolFun.MAX, 0.5, 24, 775);
rrdDef.addArchive(ConsolFun.MAX, 0.5, 288, 797);
RrdDb rrdDb = new RrdDb(rrdDef); //建立好模型
rrdDb.close();
GaugeSource sunSource = new GaugeSource(1200, 20);
GaugeSource shadeSource = new GaugeSource(300, 10);
long t = start;
int n = 0;
rrdDb = new RrdDb(rrdPath);
Sample sample = rrdDb.createSample();
//1272643200-1277913600=5270400
//30.5次循环
while (t <= end + 172800L) {
sample.setTime(t);
sample.setValue("sun", sunSource.getValue()); //
sample.setValue("shade", shadeSource.getValue());
// log.println(sample.dump());
sample.update();
t += RANDOM.nextDouble() * MAX_STEP + 1;
if (((++n) % 1000) == 0) {
System.out.print("*");
}
}
rrdDb.close();
// create graph
RrdGraphDef gDef = new RrdGraphDef();
gDef.setWidth(IMG_WIDTH);
gDef.setHeight(IMG_HEIGHT);
gDef.setFilename(imgPath);
gDef.setStartTime(start);
gDef.setEndTime(end);
gDef.setTitle("Temperatures in May-June 2010");
gDef.setVerticalLabel("temperature");
//创建一个新的虚拟的数据源
gDef.datasource("sun", rrdPath, "sun", ConsolFun.AVERAGE); //name:数据源名称 rrdPath:RRD文件路径 dsName:数据源名称在指定的RRD文件 sonsolFun:整合功能(平均、最小,最大,最后)
gDef.datasource("shade", rrdPath, "shade", ConsolFun.AVERAGE);
gDef.datasource("median", "sun,shade,+,2,/"); //创建一个新的虚拟数据源通过评估一个数学表达式. name:数据源名称 rpnExpression:RPN表达式
gDef.datasource("diff", "sun,shade,-,ABS,-1,*");
gDef.datasource("sine", "TIME," + start + ",-," + (end - start) + ",/,2,PI,*,*,SIN,1000,*");
//line 和 area之间的区别是直线和区域描述
gDef.line("sun", Color.GREEN, "sun temp"); //name:数据源名称 Color: 颜色 legend:注释文本
gDef.line("shade", Color.BLUE, "shade temp");
gDef.line("median", Color.MAGENTA, "median value");
gDef.area("diff", Color.YELLOW, "difference"); //srcName:虚拟源名称 color:颜色 legend:注释文本
gDef.line("diff", Color.RED, null);
gDef.line("sine", Color.CYAN, "sine fun");
gDef.hrule(2568, Color.GREEN, "hrule"); // value:位置的规则 color:颜色 legend:注释文本
gDef.vrule((start + 2 * end) / 3, Color.MAGENTA, "vrule\\c"); //timestamp :位置的规则(秒自epoch) color:颜色 legend:注释文本
gDef.comment("\\r"); //上打印图形
gDef.gprint("sun", ConsolFun.MAX, "maxSun = %.3f%s"); //这个方法等同于 print(String, ConsolFun, String), 但结果是印在图形本身,下面的图区域
gDef.gprint("sun", ConsolFun.AVERAGE, "avgSun = %.3f%S\\c"); //srcName:虚拟源名称 consolFun整合功能应用到源代码 format:格式字符串(如“平均= % 10.3 f % s”)
gDef.gprint("shade", ConsolFun.MAX, "maxShade = %.3f%S");
gDef.gprint("shade", ConsolFun.AVERAGE, "avgShade = %.3f%S\\c");
gDef.setImageInfo("<img src='%s' width='%d' height = '%d'>"); //创建额外的图像信息
gDef.setPoolUsed(false); //true:个人rrd文件 false:文件将直接被访问
gDef.setImageFormat("png"); //设置图像格式 imageFormat "PNG", "GIF" or "JPG".
System.out.println("Rendering graph " + Util.getLapTime());
// create graph finally
RrdGraph graph = new RrdGraph(gDef);
System.out.println(graph.getRrdGraphInfo().dump()); //该类,可以采用Rrd4j类实际上创建图表
System.out.println("== Graph created " + Util.getLapTime());
// locks info
System.out.println("== Locks info ==");
System.out.println(RrdSafeFileBackend.getLockInfo());
System.out.println("== Demo completed in " +
((System.currentTimeMillis() - startMillis) / 1000.0) + " sec");
}
static class GaugeSource {
private double value;
private double step;
GaugeSource(double value, double step) {
this.value = value;
this.step = step;
}
long getValue() {
double oldValue = value;
double increment = RANDOM.nextDouble() * step;
if (RANDOM.nextDouble() > 0.5) {
increment *= -1;
}
value += increment;
if (value <= 0) {
value = 0;
}
return Math.round(oldValue);
}
}
}
这个东西很容易报错...一般要自己涉及好,一些参数要设置合理.
首先解释rrd定义对象
RrdDef rrdDef = new RrdDef(rrdPath, start - 1, 300);
这里这里表示从star-1开始,每300s为一个时间间隔5分钟
然后,解释归档
rrdDef.addArchive(ConsolFun.AVERAGE, 0.5, 1, 600);
归档中主要是后面两个参数:表示没一笔数据一归档,保存600笔
这样计算:1*5*600 1表示一归档 5表示时间间隔 即表示近两天多的数据
因为那5*288 =1440 1440/60=24(小时)
其他的注释上已经解释的很详细了。