Java图形可视化工具graphviz-java

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());
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章