Graphviz布局程序以简单的文本语言获取图形描述,并以有用的格式制作图表,例如用于网页的图像和SVG;PDF或Postscript包含在其他文档中;或在交互式图形浏览器中显示。Graphviz具有用于具体图表的许多有用功能,例如颜色,字体,表格节点布局,线型,超链接和自定义形状的选项。
开源项目地址:https://github.com/nidi3/graphviz-java
状态图绘制工具maven引入jar包:
<!--状态循环图绘制工具-->
<dependency>
<groupId>guru.nidi</groupId>
<artifactId>graphviz-java</artifactId>
<version>0.16.0</version>
</dependency>
样例一:【hello world】
Graph g = graph("example1") // 图形名称
.directed() // 普通单向箭头
.with(node("a").link(node("b"))); // 节点“a”连接节点“b”
Graphviz.fromGraph(g) // 解析图形
.width(200) // 图片宽度
.render(Format.PNG) // 图片样式
.toFile(new File("E:\\images\\ex1.png")); // 输出图片
样例二:【多样式图】
Node
init = node("init"),
execute = node("execute"),
compare = node("compare")
// 形状长方形,样式填充,填充颜色
.with(Shape.RECTANGLE, Style.FILLED, Color.hsv(.7, .3, 1.0)),
mkString = node("mkString")
// 节点显示标签内容
.with(Label.of("make a\nstring")),
printf = node("printf");
Graph g = graph("example2").directed().with(
// 开始节点为 长方形
node("main").with(Shape.RECTANGLE)
.link(
to(node("parse").link(execute))
.with("weight", 8),
to(init).with(Style.DOTTED),// 虚线
node("cleanup"),
to(printf).with(Style.BOLD, Label.of("100 times"), Color.RED)),// 加粗,跳转内容,红色
execute.link(
graph().with(mkString, printf),
to(compare).with(Color.RED)),
init.link(mkString));
Graphviz.fromGraph(g).width(900).render(Format.PNG).toFile(new File("E:\\images\\ex2.png"));
样列三:【横向图】
Node
node0 = node("node0").with(Records.of(rec("f0", ""), rec("f1", ""), rec("f2", ""), rec("f3", ""), rec("f4", ""))),
node1 = node("node1").with(Records.of(turn(rec("n4"), rec("v", "719"), rec("")))),
node2 = node("node2").with(Records.of(turn(rec("a1"), rec("805"), rec("p", "")))),
node3 = node("node3").with(Records.of(turn(rec("i9"), rec("718"), rec("")))),
node4 = node("node4").with(Records.of(turn(rec("e5"), rec("989"), rec("p", "")))),
node5 = node("node5").with(Records.of(turn(rec("t2"), rec("v", "959"), rec("")))),
node6 = node("node6").with(Records.of(turn(rec("o1"), rec("794"), rec("")))),
node7 = node("node7").with(Records.of(turn(rec("s7"), rec("659"), rec(""))));
Graph g = graph("example3").directed()
.graphAttr().with(Rank.dir(LEFT_TO_RIGHT))
.with(
node0.link(
between(port("f0"), node1.port("v", SOUTH)),
between(port("f1"), node2.port(WEST)),
between(port("f2"), node3.port(WEST)),
between(port("f3"), node4.port(WEST)),
between(port("f4"), node5.port("v", NORTH))),
node2.link(between(port("p"), node6.port(NORTH_WEST))),
node4.link(between(port("p"), node7.port(SOUTH_WEST))));
Graphviz.fromGraph(g).width(900).render(Format.PNG).toFile(new File("E:\\images\\ex3.png"));}
样例四:【实战,动态生成状态图】
// 构造数据
List<Map<String, String>> mapList = new ArrayList<>();
Map<String, String> map = new HashMap<>(1);
// key是节点 value包含节点和 节点之间跳转的信息
map.put("a", "b@a到b");
mapList.add(map);
Map<String, String> map1 = new HashMap<>(1);
map1.put("b","c@b到c");
mapList.add(map1);
Map<String, String> map2 = new HashMap<>(2);
map2.put("a","d@a到d");
map2.put("e",null);
mapList.add(map2);
MutableGraph g = mutGraph("lifeCycle").setDirected(true).use((gr, ctx) -> {
mapList.stream().forEach(list -> {
Iterator<Map.Entry<String, String>> iterator = list.entrySet().iterator();
while ( iterator.hasNext() ) {
Map.Entry<String, String> next = iterator.next();
String key = next.getKey();
String value = next.getValue();
// 这里 value 中 包含了第二个节点和 节点之间跳转的信息
String values = null;
String lable = null;
if(StrUtil.isNotEmpty(value)){
int i = value.indexOf("@");
values = StringUtils.substring(value, 0, i);
lable = StringUtils.substring(value, i + 1, value.length());
}
MutableNode add = null;
add = mutNode(key)
.add(Shape.ELLIPSE) // 选择形状
.add(Color.rgb(168, 214, 255)); // 设置颜色
if(StrUtil.isNotEmpty(value)){
//antd的蓝色 24, 144, 255
MutableNode add2 = null;
add2 = mutNode(values)
.add(Shape.ELLIPSE) // 选择形状
.add(Color.rgb(168, 214, 255)) // 设置颜色
.add(Style.RADIAL); // 设置填充
add.addLink(to((add2)) // 节点之间对接
.add(Label.of(lable)) // 节点之间跳转时候的标签值
.add(Color.rgb(168, 214, 255))); // 颜色
}
}
});
});
// 输出到本地
Graphviz.fromGraph(g).width(900).render(Format.PNG)
.toFile(new File("E:\\images\\ex4.png"));
// 输出到网页
// BufferedImage bufferedImage = Graphviz.fromGraph(g).render(Format.PNG).toImage();
// ByteArrayOutputStream bs =new ByteArrayOutputStream();
// ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
// ImageIO.write(bufferedImage,"png",imOut);
// InputStream inputStream =new ByteArrayInputStream(bs.toByteArray());