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
可以直接使用 - 属性按类型分组:
EdgeAttributes
、SubgraphAttributes
、GraphAttributes
、NodeAttributes
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");
}
这个完整示例演示了:
- 创建一个有向图(Digraph)
- 添加多种形状的节点(椭圆、方框、菱形)
- 设置各种图形属性(布局方向、标签等)
- 添加带标签和样式的边
- 输出DOT格式代码
- 渲染为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"的图片文件,显示创建的流程图。