在java语言中使用Graphviz画图

 上图是使用Graphviz画图的一个示例,它是由以下dot脚本生成的。

digraph G{
	A [style=filled, fillcolor=greenyellow];
	B [style=filled, fillcolor=greenyellow];
	C;
	D;
	E;

	A->B[label=1][style=bold, color=dodgerblue];
	A->C[label=2];
	A->D[label=1];
	A->E[label=1];
	C->A[label=1];
	D->C[label=1];
}

如果你没有graphviz请去http://www.graphviz.org/下载(windows在添加环境变量后要restart才能生效),或者到网页版体验一下。

编写你的脚本保存成文件,例如graph.gv。然后在当前路径下运行命令行,使用最基本的dot命令:dot 脚本路径 -格式 -o 生成图片路径

dot graph.gv -Tpng -o img.png

这样会生成一个img.png图片像上图一样,graphviz还有很多其他布局可以自己尝试。

dot语言

dot是一种很方便的描述语言,上面表示一个有向图的dot脚本简单分成3大部分:

①框框,表示构造一个有向图。

digraph G{

}

②顶点,(其实不写顶点A,B直接加边A->B会默认自动生成A,B顶点)。

一般格式是:顶点名称 [属性=值, 属性=值, ……] [属性=值, ……]

一个顶点后面的属性都默认描述这个顶点,边同理,顶点名称会默认作为显示的标签,如果加了label=… 则显示时会显示label。

后面属性说明会覆盖全局的属性说明。

A [style=filled, fillcolor=greenyellow];
B [style=filled, fillcolor=greenyellow];
C;
D;
E;

③边,边的一般格式是:起点->终点 [属性=值, ……] []

属性格式基本和顶点一样,可以重边,自环。

上图的脚本中只展示了样式,填充颜色,线条加粗几个属性,还有很多属性例如修改形状,对齐方案等等可以去看官方文档

A->B[label=1][style=bold, color=dodgerblue];
A->C[label=2];
A->D[label=1];
A->E[label=1];
C->A[label=1];
D->C[label=1];

java中调用graphviz

下面讲怎么用java简单地调用graphviz画图。(当然也可以去找别人写好的工具,例如graphviz-java

第一步我们要生成一个dot脚本

准备好图后我们要按顺序把图的信息写到字符串里再写到文件里。

StringBuilder dotText=new StringBuilder();	//StringBuilder在这里效率要高于用String加加加
dotText.append(String.format("digraph G{"+newLine));	//写入开头
for(Node node:G.getNodeList()) {	//遍历顶点写入顶点属性
	dotText.append(node.name);
	if(!node.color.equals("black"))dotText.append(String.format(" [style=filled, fillcolor=%s]",node.color));
	dotText.append(";"+newLine);
}
dotText.append(newLine);
for(Node node:G.getNodeList()) {	//遍历边写入边属性
	for(Edge edge:node.edges) {
		dotText.append(String.format("%s->%s[label=%d]", edge.from,edge.to,edge.weight));
		if(!edge.color.equals("black"))dotText.append(String.format("[style=bold, color=%s]",edge.color));
		dotText.append(";"+newLine);
	}
}
dotText.append("}"+newLine);	//写入结束
//把生成好的脚本写到指定的缓存路径下
String graphFilePath=Config.tmpPath+"graph.gv";
try {
	File tmpf=new File(Config.tmpPath);
	if(!tmpf.exists()) {
		tmpf.mkdirs();
	}
	FileWriter fw=new FileWriter(graphFilePath);
	BufferedWriter bufw = new BufferedWriter(fw);
	bufw.write(dotText.toString());
	bufw.close();
}catch (Exception e) {
	throw new RuntimeException("Failed to open file");
}

第二步调用graphviz生成图片

用java调用命令行的方式来执行dot命令。(在linux里是调用bash)。

java中可以用Runtime来执行命令,一般用法:

Runtime rt=Runtime.getRuntime();	//使用Runtime执行cmd命令
try {
	String[] args= {Config.dotForWindows,filename,"-Tpng","-o",Config.tmpPath+"img.png"};
	Process process = rt.exec(args);
	process.waitFor();
	
}catch (Exception e) {
	throw new RuntimeException("Failed to generate image.");
}

也可以写一行:

Runtime.getRuntime().exec(Config.dotForWindows+" "+filename+" -Tpng"+" -o"+" "+Config.tmpPath+"img.png").waitFor();

然后就可以去指定位置收集生成的图片了,也可以顺便用命令行执行mspaint img.png 展示出来。

上面的完整代码可见软工实验一 WordGraph/ShowGraph.java

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注