Rust图形可视化库graphviz-rust的使用,graphviz-rust提供DOT语言解析与图表生成功能

Rust图形可视化库graphviz-rust的使用

graphviz-rust 是一个Rust库,提供了对Graphviz格式图的基本访问能力,支持导入和导出功能。

基础示例

解析DOT源码

use dot_generator::*;
use dot_structures::*;

// 解析DOT格式字符串并转换为Graph结构
fn parse_test() {
    let g: Graph = parse(
        r#"
        strict digraph t {
            aa[color=green]
            subgraph v {
                aa[shape=square]
                subgraph vv{a2 -> b2}
                aaa[color=red]
                aaa -> bbb
            }
            aa -> be -> subgraph v { d -> aaa}
            aa -> aaa -> v
        }
        "#,
    )
    .unwrap();

    // 验证解析结果是否符合预期
    assert_eq!(
        g,
        graph!(strict di id!("t");
          node!("aa";attr!("color","green")),
          subgraph!("v";
            node!("aa"; attr!("shape","square")),
            subgraph!("vv"; edge!(node_id!("a2") => node_id!("b2"))),
            node!("aaa";attr!("color","red")),
            edge!(node_id!("aaa") => node_id!("bbb"))
            ),
          edge!(node_id!("aa") => node_id!("be") => subgraph!("v"; edge!(node_id!("d") => node_id!("aaa")))),
          edge!(node_id!("aa") => node_id!("aaa") => node_id!("v"))
        )
    )
}

将图打印为DOT源码

use dot_generator::*;
use dot_structures::*;
use graphviz_rust::printer::{DotPrinter, PrinterContext};

// 将Graph结构转换回DOT格式字符串
fn print_test() {
    let mut g = graph!(strict di id!("id"));
    assert_eq!(
        "strict digraph id {}".to_string(),
        g.print(&mut PrinterContext::default())
    );
}

使用cmd引擎将图转换为外部格式

use dot_generator::*;
use dot_structures::*;
use graphviz_rust::{
    attributes::*,
    cmd::{CommandArg, Format},
    exec, parse,
    printer::{DotPrinter, PrinterContext},
};

// 将图形转换为SVG格式
fn output_test() {
    let mut g = graph!(id!("id");
         node!("nod"),
         subgraph!("sb";
             edge!(node_id!("a") => subgraph!(;
                node!("n";
                NodeAttributes::color(color_name::black), NodeAttributes::shape(shape::egg))
            ))
        ),
        edge!(node_id!("a1") => node_id!(esc "a2"))
    );
    let graph_svg = exec(
        g,
        &mut PrinterContext::default(),
        vec![Format::Svg.into()],
    )
    .unwrap();
}

完整示例代码

use dot_generator::*;
use dot_structures::*;
use graphviz_rust::{
    attributes::*,
    cmd::{CommandArg, Format},
    exec,
    printer::{DotPrinter, PrinterContext},
};

fn main() {
    // 创建一个有向图
    let mut graph = graph!(strict di id!("example_graph");
        // 定义节点属性
        node!("start"; attr!("shape", "box"), attr!("color", "blue")),
        node!("end"; attr!("shape", "ellipse"), attr!("color", "red")),
        
        // 定义子图
        subgraph!("cluster_0";
            attr!("label", "Subgraph A"),
            node!("a"; NodeAttributes::color(color_name::green)),
            node!("b"; NodeAttributes::shape(shape::circle)),
            edge!(node_id!("a") => node_id!("b"); attr!("label", "a_to_b"))
        ),
        
        // 定义边
        edge!(node_id!("start") => node_id!("a")),
        edge!(node_id!("b") => node_id!("end"))
    );

    // 打印DOT格式
    let dot_output = graph.print(&mut PrinterContext::default());
    println!("DOT格式输出:\n{}", dot_output);

    // 转换为SVG格式并保存到文件
    let svg_output = exec(
        graph,
        &mut PrinterContext::default(),
        vec![
            Format::Svg.into(),
            CommandArg::Output("graph.svg".to_string()),
        ],
    ).unwrap();
    
    println!("SVG文件已保存为graph.svg");
}

属性系统

graphviz提供了大量的属性,该库提供了一组结构来简化导航:

  • 使用attr!宏可以方便地定义自定义属性
  • 预定义的命名属性如color可以直接使用
  • 属性按类型分组:EdgeAttributesSubgraphAttributesGraphAttributesNodeAttributes
use dot_generator::*;
use dot_structures::*;
use graphviz_rust::attributes::{
    color, color_name, GraphAttributes, NodeAttributes,
};
use into_attr::IntoAttribute;

// 属性使用示例
fn test() {
    // 验证属性设置是否正确
    assert_eq!(GraphAttributes::center(true), attr!("center", true));
    assert_eq!(
        NodeAttributes::color(color_name::antiquewhite1),
        attr!("color", "antiquewhite1")
    );
    assert_eq!(color::default().into_attr(), attr!("color", "black"));
}

注意事项

需要安装Graphviz命令行工具

由于该库依赖Graphviz命令行工具执行转换命令,因此需要预先安装Graphviz,否则会报错提示找不到程序或文件。在Linux上可通过包管理器安装,在Windows上需要下载并安装Graphviz软件包。


1 回复

Rust图形可视化库graphviz-rust的使用指南

完整示例demo

以下是一个完整的示例,展示了如何使用graphviz-rust创建、渲染并保存一个流程图:

use graphviz_rust::{
    dot_generator::*,
    dot_structures::*,
    attributes::*,
    cmd::{CommandArg, Format, Layout},
    exec,
};

fn main() {
    // 1. 创建流程图
    let flow_chart = graph!(di id!("flow_chart")
        // 设置图形属性
        attr!("rankdir", "\"LR\"")  // 从左到右布局
        attr!("label", "\"简单流程图示例\"")
        attr!("labelloc", "\"t\"")  // 标题在顶部
        
        // 定义节点
        node!("start"; 
            attr!("shape", "\"ellipse\"")
            attr!("label", "\"开始\"")
        )
        node!("process1"; 
            attr!("shape", "\"box\"")
            attr!("label", "\"处理步骤1\"")
        )
        node!("process2"; 
            attr!("shape", "\"box\"")
            attr!("label", "\"处理步骤2\"")
        )
        node!("decision"; 
            attr!("shape", "\"diamond\"")
            attr!("label", "\"判断条件\"")
        )
        node!("end"; 
            attr!("shape", "\"ellipse\"")
            attr!("label", "\"结束\"")
        )
        
        // 定义边
        edge!(node_id!("start") => node_id!("process1"); 
            attr!("label", "\"开始流程\"")
        )
        edge!(node_id!("process1") => node_id!("process2"))
        edge!(node_id!("process2") => node_id!("decision"))
        edge!(node_id!("decision") => node_id!("end"); 
            attr!("label", "\"条件满足\"")
            attr!("color", "\"green\"")
        )
        edge!(node_id!("decision") => node_id!("process1"; 
            attr!("label", "\"条件不满足\"")
            attr!("color", "\"red\"")
            attr!("style", "\"dashed\"")
        ))
    );
    
    // 2. 输出DOT格式
    println!("生成的DOT代码:\n{}", flow_chart.to_string());
    
    // 3. 渲染为PNG文件
    exec(
        flow_chart,
        &mut std::io::stdout(),
        vec![
            CommandArg::Layout(Layout::Dot),  // 使用dot布局算法
            CommandArg::Format(Format::Png),  // 输出PNG格式
            CommandArg::Output("flow_chart.png".to_string()),  // 输出文件名
        ],
    ).expect("渲染图表失败");
    
    println!("流程图已保存为flow_chart.png");
}

这个完整示例演示了:

  1. 创建一个有向图(Digraph)
  2. 添加多种形状的节点(椭圆、方框、菱形)
  3. 设置各种图形属性(布局方向、标签等)
  4. 添加带标签和样式的边
  5. 输出DOT格式代码
  6. 渲染为PNG图片文件

输出示例:

digraph flow_chart {
    rankdir="LR";
    label="简单流程图示例";
    labelloc="t";
    start [shape="ellipse", label="开始"];
    process1 [shape="box", label="处理步骤1"];
    process2 [shape="box", label="处理步骤2"];
    decision [shape="diamond", label="判断条件"];
    end [shape="ellipse", label="结束"];
    start -> process1 [label="开始流程"];
    process1 -> process2;
    process2 -> decision;
    decision -> end [label="条件满足", color="green"];
    decision -> process1 [label="条件不满足", color="red", style="dashed"];
}

运行后会生成一个名为"flow_chart.png"的图片文件,显示创建的流程图。

回到顶部