Rust数据结构可视化库dot-structures的使用,实现Rust数据结构的Graphviz DOT格式可视化与导出

Rust数据结构可视化库dot-structures的使用,实现Rust数据结构的Graphviz DOT格式可视化与导出

安装

在项目目录中运行以下Cargo命令:

cargo add dot-structures

或者在Cargo.toml中添加以下行:

dot-structures = "0.1.2"

基本用法

dot-structures库可以将Rust数据结构转换为Graphviz DOT格式,便于可视化展示。以下是一个基本示例:

use dot_structures::*;

fn main() {
    // 创建一个简单的图结构
    let mut graph = Graph::DiGraph;
    
    // 添加节点
    let node1 = node("node1");
    let node2 = node("node2");
    
    // 添加边
    let edge = edge(node1.id.clone(), node2.id.clone());
    
    // 将元素添加到图中
    graph.add_node(node1);
    graph.add_node(node2);
    graph.add_edge(edge);
    
    // 输出DOT格式
    println!("{}", graph.to_dot());
}

完整示例

下面是一个更完整的示例,展示如何创建复杂的数据结构并导出为DOT格式:

use dot_structures::*;
use std::fs;

fn main() {
    // 创建有向图
    let mut graph = Graph::DiGraph;
    
    // 创建带有属性的节点
    let mut node1 = node("Node1");
    node1.attributes.push(attr("color", "red"));
    node1.attributes.push(attr("shape", "box"));
    
    let mut node2 = node("Node2");
    node2.attributes.push(attr("color", "blue"));
    node2.attributes.push(attr("shape", "circle"));
    
    let mut node3 = node("Node3");
    node3.attributes.push(attr("color", "green"));
    node3.attributes.push(attr("shape", "diamond"));
    
    // 创建带有属性的边
    let mut edge1 = edge(node1.id.clone(), node2.id.clone());
    edge1.attributes.push(attr("label", "edge1"));
    edge1.attributes.push(attr("style", "dashed"));
    
    let mut edge2 = edge(node2.id.clone(), node3.id.clone());
    edge2.attributes.push(attr("label", "edge2");
    edge2.attributes.push(attr("color", "purple"));
    
    // 添加元素到图中
    graph.add_node(node1);
    graph.add_node(node2);
    graph.add_node(node3);
    graph.add_edge(edge1);
    graph.add_edge(edge2);
    
    // 添加图属性
    graph.add_attribute(attr("rankdir", "LR"));
    
    // 输出到控制台
    println!("DOT representation:\n{}", graph.to_dot());
    
    // 写入文件
    fs::write("graph.dot", graph.to_dot()).expect("Unable to write file");
    
    println!("Graph saved to graph.dot");
    println!("You can visualize it using: dot -Tpng graph.dot -o graph.png");
}

输出结果

运行上述代码后,将生成如下DOT格式内容:

digraph {
    rankdir=LR;
    Node1 [color=red, shape=box];
    Node2 [color=blue, shape=circle];
    Node3 [color=green, shape=diamond];
    Node1 -> Node2 [label=edge1, style=dashed];
    Node2 -> Node3 [label=edge2, color=purple];
}

可视化

要可视化生成的DOT文件,可以使用Graphviz工具:

dot -Tpng graph.dot -o graph.png

这将生成一个PNG图像文件,显示你的数据结构可视化结果。

库信息

  • 版本: 0.1.2
  • 许可证: MIT
  • 作者: Boris Zhguchev

1 回复

Rust数据结构可视化库dot-structures使用指南

简介

dot-structures是一个Rust库,用于将Rust数据结构转换为Graphviz DOT格式,从而实现数据结构的可视化。这对于调试复杂数据结构或理解程序中的数据关系特别有用。

安装

在Cargo.toml中添加依赖:

[dependencies]
dot-structures = "0.2"

基本用法

1. 基本数据结构可视化

use dot_structures::*;

fn main() {
    // 创建一个简单的图结构
    let graph = Graph::DiGraph {
        id: "example".to_string(),
        strict: false,
        stmts: vec![
            Stmt::Node(
                Node {
                    id: "a".to_string(),
                    attr_list: vec![],
                }
                .into(),
            ),
            Stmt::Node(
                Node {
                    id: "b".to_string(),
                    attr_list: vec![],
                }
                .into(),
            ),
            Stmt::Edge(Edge {
                ty: EdgeTy::Pair(
                    Vertex::N("a".to_string()),
                    Vertex::N("b".to_string()),
                ),
                attr_list: vec![Attribute {
                    id: "label".to_string(),
                    eq: "a to b".to_string(),
                }],
            }),
        ],
    };

    // 转换为DOT格式字符串
    let dot_string = graph.to_string();
    println!("{}", dot_string);
}

2. 导出为DOT文件

use std::fs::File;
use std::io::Write;

fn save_dot(graph: Graph, filename: &str) -> std::io::Result<()> {
    let mut file = File::create(filename)?;
    file.write_all(graph.to_string().as_bytes())?;
    Ok(())
}

3. 可视化Rust标准数据结构

use dot_structures::*;

fn visualize_vec(vec: &Vec<i32>) -> Graph {
    let mut stmts = vec![];
    
    for (i, val) in vec.iter().enumerate() {
        stmts.push(Stmt::Node(Node {
            id: format!("node_{}", i),
            attr_list: vec![Attribute {
                id: "label".to_string(),
                eq: format!("{}", val),
            }],
        }.into()));
        
        if i > 0 {
            stmts.push(Stmt::Edge(Edge {
                ty: EdgeTy::Pair(
                    Vertex::N(format!("node_{}", i-1)),
                    Vertex::N(format!("node_{}", i)),
                ),
                attr_list: vec![],
            }));
        }
    }
    
    Graph::DiGraph {
        id极抱歉,我的回答被截断了。我将从最后一个完整示例继续:

```rust
use dot_structures::*;

fn visualize_vec(vec: &Vec<i32>) -> Graph {
    let mut stmts = vec![];
    
    for (i, val) in vec.iter().enumerate() {
        stmts.push(Stmt::Node(Node {
            id: format!("node_{}", i),
            attr_list: vec![Attribute {
                id: "label".to_string(),
                eq: format!("{}", val),
            }],
        }.into()));
        
        if i > 0 {
            stmts.push(Stmt::Edge(Edge {
                ty: EdgeTy::Pair(
                    Vertex::N(format!("node_{}", i-1)),
                    Vertex::N(format!("node_{}", i)),
                ),
                attr_list: vec![],
            }));
        }
    }
    
    Graph::DiGraph {
        id: "vector_visualization".to_string(),
        strict: false,
        stmts,
    }
}

完整示例:链表可视化

use dot_structures::*;

// 定义链表节点
struct ListNode {
    value: i32,
    next: Option<Box<ListNode>>,
}

// 将链表转换为DOT图形
fn list_to_dot(head: &Option<Box<ListNode>>, graph_id: &str) -> Graph {
    let mut stmts = vec![];
    let mut current_node = head;
    let mut prev_id = String::new();
    let mut index = 0;

    while let Some(node) = current_node {
        // 创建当前节点
        let node_id = format!("node_{}", index);
        stmts.push(Stmt::Node(Node {
            id: node_id.clone(),
            attr_list: vec![
                Attribute {
                    id: "label".to_string(),
                    eq: format!("{}", node.value),
                },
                Attribute {
                    id: "shape".to_string(),
                    eq: "box".to_string(),
                },
            ],
        }.into()));

        // 如果不是第一个节点,创建边连接前一个节点
        if index > 0 {
            stmts.push(Stmt::Edge(Edge {
                ty: EdgeTy::Pair(
                    Vertex::N(prev_id),
                    Vertex::N(node_id.clone()),
                ),
                attr_list: vec![
                    Attribute {
                        id: "arrowhead".to_string(),
                        eq: "vee".to_string(),
                    },
                ],
            }));
        }

        prev_id = node_id;
        current_node = &node.next;
        index += 1;
    }

    Graph::DiGraph {
        id: graph_id.to_string(),
        strict: false,
        stmts,
    }
}

fn main() {
    // 创建一个链表: 1 -> 2 -> 3 -> 4
    let list = Some(Box::new(ListNode {
        value: 1,
        next: Some(Box::new(ListNode {
            value: 2,
            next: Some(Box::new(ListNode {
                value: 3,
                next: Some(Box::new(ListNode {
                    value: 4,
                    next: None,
                })),
            })),
        })),
    }));

    // 转换为DOT图形
    let graph = list_to_dot(&list, "linked_list");
    
    // 输出DOT字符串
    println!("{}", graph.to_string());
    
    // 保存到文件
    save_dot(graph, "linked_list.dot").expect("Failed to save DOT file");
}

// 使用之前定义的保存函数
fn save_dot(graph: Graph, filename: &str) -> std::io::Result<()> {
    use std::fs::File;
    use std::io::Write;
    
    let mut file = File::create(filename)?;
    file.write_all(graph.to_string().as_bytes()))?;
    Ok(())
}

这个完整示例展示了如何使用dot-structures库可视化一个链表数据结构。示例中:

  1. 定义了链表节点结构ListNode
  2. 实现了将链表转换为DOT图形的函数list_to_dot
  3. main函数中创建了一个链表并可视化
  4. 包含了保存DOT文件的功能

要生成图像,可以使用Graphviz工具:

dot -Tpng linked_list.dot -o linked_list.png
回到顶部