Rust图形绘制库box_drawing的使用:创建终端ASCII图表和框线图形的轻量级解决方案

Rust图形绘制库box_drawing的使用:创建终端ASCII图表和框线图形的轻量级解决方案

box_drawing是一个轻量级的Rust库,专门用于在终端环境中创建ASCII风格的图表和框线图形。该库通过提供简洁的API,使开发者能够轻松绘制各种框线元素和表格结构。

安装方法

在Rust项目中添加box_drawing库有两种方式:

  1. 使用Cargo命令行工具添加:
cargo add box_drawing
  1. 直接在Cargo.toml文件中添加依赖项:
box_drawing = "0.1.2"

基础使用示例

以下代码展示了如何使用box_drawing创建基本表格结构:

extern crate box_drawing;

use box_drawing::*;

fn main() {
    // 绘制水平线
    println!("{}", LIGHT_HORIZONTAL);
    
    // 绘制带有标题的表格行
    println!("{}   Simple Table   {}", LIGHT_VERTICAL, LIGHT_VERTICAL);
    
    // 再次绘制水平线
    println!("{}", LIGHT_HORIZONTAL);
    
    // 绘制表格内容行
    println!("{}  Item 1  {}  Item 2  {}", LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL);
    
    // 绘制水平分隔线
    println!("{}", LIGHT_HORIZONTAL);
    
    // 绘制数据行
    println!("{}  Data 1  {}  Data 2  {}", LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL);
    
    // 绘制底部边框
    println!("{}", LIGHT_HORIZONTAL);
}

完整功能示例

下面展示更复杂的应用场景,包括带标题的框体和数据表格:

extern crate box_drawing;

use box_drawing::*;

fn main() {
    // 绘制带标题的框体
    draw_box_with_title("示例框体", 40, 8);

    // 绘制数据表格
    draw_data_table();
}

// 绘制带标题的框体函数
fn draw_box_with_title(title: &str, width: usize, height: usize) {
    // 顶部边框
    println!("{}{}{}",
        LIGHT_DOWN_AND_RIGHT,
        LIGHT_HORIZONTAL.repeat(width - 2),
        LIGHT_DOWN_AND_LEFT
    );

    // 居中显示标题
    let title_line = format!(" {} ", title);
    let padding = (width - title_line.len()) / 2;
    println!("{}{}{}{}{}",
        LIGHT_VERTICAL,
        " ".repeat(padding),
        title_line,
        " ".repeat(width - padding - title_line.len() - 2),
        LIGHT_VERTICAL
    );

    // 标题下方分隔线
    println!("{}{}{}",
        LIGHT_VERTICAL_AND_RIGHT,
        LIGHT_HORIZONTAL.repeat(width - 2),
        LIGHT_VERTICAL_AND_LEFT
    );

    // 框体内容区域
    for _ in 0..height {
        println!("{}{}{}",
            LIGHT_VERTICAL,
            " ".repeat(width - 2),
            LIGHT_VERTICAL
        );
    }

    // 底部边框
    println!("{}{}{}",
        LIGHT_UP_AND_RIGHT,
        LIGHT_HORIZONTAL.repeat(width - 2),
        LIGHT_UP_AND_LEFT
    );
}

// 绘制数据表格函数
fn draw_data_table() {
    // 表格顶部边框
    println!("\n{}", LIGHT_HORIZONTAL.repeat(42));
    
    // 表头行
    println!("{}  ID  {}  产品名称   {}  价格   {}  库存  {}",
        LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL);
    
    // 表头分隔线
    println!("{}", LIGHT_HORIZONTAL.repeat(42));

    // 表格数据行
    println!("{}  1  {}  商品A    {}  ¥100  {}   50  {}",
        LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL);
    println!("{}", LIGHT_HORIZONTAL.repeat(42));
    
    println!("{}  2  {}  商品B    {}  ¥200  {}   30  {}",
        LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL);
    println!("{}", LIGHT_HORIZONTAL.repeat(42));
    
    println!("{}  3  {}  商品C    {}  ¥150  {}   75  {}",
        LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL, LIGHT_VERTICAL);
    println!("{}", LIGHT_HORIZONTAL.repeat(42));
}

通过这个完整示例,我们可以了解:

  1. 如何创建带标题的自定义尺寸框体
  2. 如何构建包含多列数据的表格
  3. 如何利用LIGHT_HORIZONTAL、LIGHT_VERTICAL等预定义字符常量构建图形界面
  4. 如何实现文本内容的居中对齐

box_drawing库提供了丰富的框线字符常量,开发者可以灵活组合这些元素来创建各种终端图形界面。


1 回复

Rust图形绘制库box_drawing使用指南

简介

box_drawing是一个轻量级的Rust库,专门用于在终端中创建ASCII图表和框线图形。它提供了一系列工具和预定义的字符,可以方便地绘制各种框线、表格和简单的图形界面。

主要特性

  • 提供完整的Box Drawing Unicode字符集支持
  • 轻量级,无额外依赖
  • 支持组合不同线条样式创建复杂图形
  • 适用于终端UI、图表展示等场景

安装

在Cargo.toml中添加依赖:

[dependencies]
box_drawing = "0.1"

基本用法

1. 使用预定义字符

use box_drawing::light;

fn main() {
    println!("{}", light::DOWN_RIGHT);  // ┌
    println!("{}", light::HORIZONTAL);  // ─
    println!("{}", light::DOWN_LEFT);   // ┐
    println!("{}", light::VERTICAL);    // │
    println!("{}", light::UP_RIGHT);    // └
    println!("{}", light::UP_LEFT);     // ┘
}

2. 绘制简单方框

use box_drawing::light;

fn draw_box(width: usize, height: usize) {
    // 上边框
    println!("{}{}{}", 
        light::DOWN_RIGHT,
        light::HORIZONTAL.to_string().repeat(width - 2),
        light::DOWN_LEFT);
    
    // 中间部分
    for _ in 0..height - 2 {
        println!("{}{}{}",
            light::VERTICAL,
            " ".repeat(width - 2),
            light::VERTICAL);
    }
    
    // 下边框
    println!("{}{}{}",
        light::UP_RIGHT,
        light::HORIZONTAL.to_string().repeat(width - 2),
        light::UP_LEFT);
}

fn main() {
    draw_box(20, 10);
}

3. 绘制表格

use box_drawing::light;

fn draw_table(rows: usize, cols: usize, cell_width: usize) {
    // 绘制顶部边框
    print!("{}", light::DOWN_RIGHT);
    for c in 0..cols {
        print!("{}", light::HORIZONTAL.to_string().repeat(cell_width));
        if c < cols - 1 {
            print!("{}", light::DOWN_HORIZONTAL);
        }
    }
    println!("{}", light::DOWN_LEFT);
    
    // 绘制行
    for r in 0..rows {
        // 内容行
        print!("{}", light::VERTICAL);
        for _ in 0..cols {
            print!("{:^width$}", "Content", width = cell_width);
            print!("{}", light::VERTICAL);
        }
        println!();
        
        // 分隔行(非最后一行)
        if r < rows - 1 {
            print!("{}", light::VERTICAL_RIGHT);
            for c in 0..cols {
                print!("{}", light::HORIZONTAL.to_string().repeat(cell_width));
                if c < cols - 1 {
                    print!("{}", light::VERTICAL_HORIZONTAL);
                }
            }
            println!("{}", light::VERTICAL_LEFT);
        }
    }
    
    // 绘制底部边框
    print!("{}", light::UP_RIGHT);
    for c in 0..cols {
        print!("{}", light::HORIZONTAL.to_string().repeat(cell_width));
        if c < cols - 1 {
            print!("{}", light::UP_HORIZONTAL);
        }
    }
    println!("{}", light::UP_LEFT);
}

fn main() {
    draw_table(3, 4, 10);
}

高级用法

1. 混合不同线条样式

use box_drawing::{light, double};

fn mixed_box() {
    // 顶部使用双线,侧面使用单线
    println!("{}{}{}", 
        double::DOWN_RIGHT,
        double::HORIZONTAL.to_string().repeat(10),
        double::DOWN_LEFT);
    
    for _ in 0..5 {
        println!("{}{}{}",
            light::VERTICAL,
            " ".repeat(10),
            light::VERTICAL);
    }
    
    println!("{}{}{}",
        light::UP_RIGHT,
        light::HORIZONTAL.to_string().repeat(10),
        light::UP_LEFT);
}

2. 创建连接点

use box_drawing::light;

fn draw_intersection() {
    let horizontal = light::HORIZONTAL.to_string().repeat(5);
    let vertical = format!("\n{}     {}\n", light::VERTICAL, light::VERTICAL);
    
    println!("   {}", horizontal);
    println!("   {}", light::VERTICAL);
    println!("{}{}{}{}", 
        horizontal, 
        light::VERTICAL_HORIZONTAL, 
        horizontal, 
        light::VERTICAL);
    println!("   {}", light::VERTICAL);
    println!("   {}", horizontal);
}

完整示例

下面是一个完整的终端菜单界面示例,结合了方框、表格和连接点:

use box_drawing::{light, double};

fn main() {
    // 绘制主标题框
    draw_title_box("Rust终端菜单系统", 40);
    
    // 绘制主菜单选项
    draw_menu_options();
    
    // 绘制底部状态栏
    draw_status_bar("按q退出 | 按↑↓选择选项");
}

fn draw_title_box(title: &str, width: usize) {
    // 使用双线绘制标题框
    println!("{}", double::DOWN_RIGHT);
    println!("{}", double::HORIZONTAL.to_string().repeat(width));
    println!("{}", double::DOWN_LEFT);
    
    // 标题居中显示
    println!("{}{:^width$}{}", 
        double::VERTICAL, 
        title, 
        double::VERTICAL,
        width = width - 2);
    
    // 底部边框
    println!("{}", double::UP_RIGHT);
    println!("{}", double::HORIZONTAL.to_string().repeat(width));
    println!("{}", double::UP_LEFT);
}

fn draw_menu_options() {
    // 菜单选项
    let options = vec![
        "1. 用户管理",
        "2. 系统设置",
        "3. 数据统计",
        "4. 帮助文档"
    ];
    
    // 绘制菜单表格
    println!();
    println!("{}", light::DOWN_RIGHT);
    println!("{}", light::HORIZONTAL.to_string().repeat(30));
    println!("{}", light::DOWN_LEFT);
    
    for (i, option) in options.iter().enumerate() {
        println!("{} {:2} {}", light::VERTICAL, i+1, option);
        if i < options.len() - 1 {
            // 绘制分隔线
            println!("{}", light::VERTICAL_RIGHT);
            println!("{}", light::HORIZONTAL.to_string().repeat(30));
            println!("{}", light::VERTICAL_LEFT);
        }
    }
    
    println!("{}", light::UP_RIGHT);
    println!("{}", light::HORIZONTAL.to_string().repeat(30));
    println!("{}", light::UP_LEFT);
}

fn draw_status_bar(message: &str) {
    // 绘制底部状态栏
    println!();
    println!("{}", light::DOWN_RIGHT);
    println!("{}", light::HORIZONTAL.to_string().repeat(message.len() + 4));
    println!("{}", light::DOWN_LEFT);
    
    println!("{} {} {}", 
        light::VERTICAL, 
        message, 
        light::VERTICAL);
    
    println!("{}", light::UP_RIGHT);
    println!("{}", light::HORIZONTAL.to_string().repeat(message.len() + 4));
    println!("{}", light::UP_LEFT);
}

注意事项

  1. 确保终端使用的字体支持Box Drawing字符
  2. 不同终端可能对Unicode字符的渲染有细微差异
  3. 对于复杂图形,建议先规划好布局再编码

box_drawing库虽然简单,但结合适当的算法可以创建出各种有用的终端图形界面。

回到顶部