#embedding #layout #visualization #tree-structure #debugging #syntree

syntree_layout

用于从'syntree'crate中可视树形的库

2个不稳定版本

0.2.0 2023年3月5日
0.1.0 2023年3月4日

1106算法

Download history 173/week @ 2024-03-25 193/week @ 2024-04-01 147/week @ 2024-04-08 206/week @ 2024-04-15 155/week @ 2024-04-22 139/week @ 2024-04-29 202/week @ 2024-05-06 166/week @ 2024-05-13 74/week @ 2024-05-20 111/week @ 2024-05-27 147/week @ 2024-06-03 113/week @ 2024-06-10 101/week @ 2024-06-17 167/week @ 2024-06-24 75/week @ 2024-07-01 83/week @ 2024-07-08

每月下载 449
13 个crate使用 (直接使用2个)

MIT/Apache

38KB
603

Rust Docs.rs Crates.io

syntree_layout

一个用于可视化树结构的库,专为syntree crate定制。

请参阅 变更日志 了解最新更改。

概述

此crate提供了一种表示树形结构的新方法,类似于syntree的自身print方法。当树开始增长时,这有助于理解它们的结构。

以下是可能的结果

example.svg

可视化树的任务是一个通用任务。因此,我决定为社区提供一个独立的crate。

我想面对的一个抽象是具体的节点数据类型以及它应该如何呈现给树形可视化。

我提供了几种表示节点数据的方法。

  • 使用节点的数据类型的Display实现
  • 使用节点的数据类型的Debug实现
  • 使用节点的数据类型的Visualize实现
  • 使用直接提供的方法

Visualize trait只包含两个方法,其中只有一个方法是必须实现的。这是一个额外的方式,可以灵活地挂钩到数据表示的机制。

库提供了一个另一个抽象。这是关于如何将节点的平面嵌入表示给用户,即嵌入最终转换成什么格式。为了简单起见,syntree_layout crate为此任务提供了一个简单的默认解决方案,即SvgDrawer类型。它提供嵌入式SVG格式的元素表示。但是,如果用户想使用自己的实现,例如将嵌入打印到位图上,他可以轻松地集成到图形生成中。为此,他需要实现自己的抽屉算法,并为它实现Drawer trait。然后,他可以使用Layouter的with_drawer方法将其提供给绘图过程。

示例使用

use std::fmt;

use syntree::Builder;
use syntree_layout::{Layouter, Result, Visualize};

// `Debug` implementation is necessary if you want to use `Layouter::embed_with_debug`
#[derive(Debug)]
struct MyNodeData(i32);

// You need to implement syntree_layout::Visualize for your nodes data type if you want your own
// node representation.
// You should use `Layouter::embed_with_visualize`
impl Visualize for MyNodeData {
    fn visualize(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Id({})", self.0)
    }

    fn emphasize(&self) -> bool {
        // This simply emphasizes only the leaf nodes.
        // It only works for this example.
        self.0 > 1
    }
}

// Display implementation is necessary if you want to use `Layouter::embed`
impl fmt::Display for MyNodeData {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

fn main() -> Result<()> {
    //      0
    //     / \
    //    1   2
    //   / \
    //  3   4
    let mut tree = Builder::new();

    tree.open(MyNodeData(0)).unwrap();
    tree.open(MyNodeData(1)).unwrap();
    tree.token(MyNodeData(3), 1).unwrap();
    tree.token(MyNodeData(4), 1).unwrap();
    tree.close().unwrap();
    tree.token(MyNodeData(2), 1).unwrap();
    tree.close().unwrap();

    let tree = tree.build().unwrap();
    Layouter::new(&tree)
        .with_file_path("examples/example1_vis.svg")
        .embed_with_visualize()?
        .write()?;

    Layouter::new(&tree)
        .with_file_path("examples/example1_deb.svg")
        .embed_with_debug()?
        .write()?;

    Layouter::new(&tree)
        .with_file_path("examples/example1_dis.svg")
        .embed()?
        .write()
}

依赖关系

~0.6–1MB
~22K SLoC