首页 > 其他分享 >0061-Tui-迷你图示例

0061-Tui-迷你图示例

时间:2022-09-30 21:27:00浏览次数:71  
标签:mut 示例 default self terminal Tui let 0061 signal

环境

  • Time 2022-08-16
  • Rust 1.63.0
  • Tui 0.18.0

前言

说明

参考:https://github.com/fdehau/tui-rs/blob/master/examples/sparkline.rs

目标

使用 tui-rs 显示迷你图。

生成数据

#[derive(Clone)]
pub struct RandomSignal {
    distribution: Uniform<u64>,
    rng: ThreadRng,
}

impl RandomSignal {
    pub fn new(lower: u64, upper: u64) -> RandomSignal {
        RandomSignal {
            distribution: Uniform::new(lower, upper),
            rng: rand::thread_rng(),
        }
    }
}

impl Iterator for RandomSignal {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        Some(self.distribution.sample(&mut self.rng))
    }
}

定义应用

struct App {
    signal: RandomSignal,
    data1: Vec<u64>,
    data2: Vec<u64>,
    data3: Vec<u64>,
}

impl App {
    fn new() -> App {
        let mut signal = RandomSignal::new(0, 100);
        let data1 = signal.by_ref().take(200).collect::<Vec<u64>>();
        let data2 = signal.by_ref().take(200).collect::<Vec<u64>>();
        let data3 = signal.by_ref().take(200).collect::<Vec<u64>>();
        App {
            signal,
            data1,
            data2,
            data3,
        }
    }

    fn on_tick(&mut self) {
        let value = self.signal.next().unwrap();
        self.data1.pop();
        self.data1.insert(0, value);
        let value = self.signal.next().unwrap();
        self.data2.pop();
        self.data2.insert(0, value);
        let value = self.signal.next().unwrap();
        self.data3.pop();
        self.data3.insert(0, value);
    }
}

ui

fn ui<B: Backend>(frame: &mut Frame<B>, app: &mut App) {
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .margin(2)
        .constraints([
            Constraint::Length(3),
            Constraint::Length(3),
            Constraint::Length(7),
            Constraint::Min(0),
        ])
        .split(frame.size());
    let sparkline = widgets::Sparkline::default()
        .block(
            Block::default()
                .title("温度")
                .borders(Borders::LEFT | Borders::RIGHT),
        )
        .data(&app.data1)
        .style(Style::default().fg(Color::Yellow));
    frame.render_widget(sparkline, chunks[0]);
    let sparkline = widgets::Sparkline::default()
        .block(
            Block::default()
                .title("湿度")
                .borders(Borders::LEFT | Borders::RIGHT),
        )
        .data(&app.data2)
        .style(Style::default().bg(Color::Green));
    frame.render_widget(sparkline, chunks[1]);
    // Multiline
    let sparkline = widgets::Sparkline::default()
        .block(
            Block::default()
                .title("降水")
                .borders(Borders::LEFT | Borders::RIGHT),
        )
        .data(&app.data3)
        .style(Style::default().fg(Color::Red));
    frame.render_widget(sparkline, chunks[2]);
}

效果展示

迷你图

总结

使用 tui-rs 渲染迷你图。

附录

源码

use anyhow::{Context, Result};
use crossterm::{event, terminal, ExecutableCommand};
use layout::{Constraint, Direction, Layout};
use rand::distributions::Uniform;
use rand::prelude::Distribution;
use rand::rngs::ThreadRng;
use style::{Color, Style};
use tui::backend::{Backend, CrosstermBackend};
use tui::{layout, style, widgets, Frame, Terminal};
use widgets::{Block, Borders};

pub fn main() -> Result<()> {
    terminal::enable_raw_mode()?;
    let mut backend = CrosstermBackend::new(std::io::stdout());
    backend
        .execute(terminal::EnterAlternateScreen)?
        .execute(terminal::Clear(terminal::ClearType::All))?
        .hide_cursor()?;
    let mut terminal = tui::Terminal::new(backend)?;
    run(&mut terminal)?;
    terminal::disable_raw_mode()?;
    terminal
        .backend_mut()
        .execute(terminal::Clear(terminal::ClearType::All))?
        .execute(terminal::LeaveAlternateScreen)?
        .show_cursor()
        .context("重置控制台失败")
}

fn run<B: Backend>(terminal: &mut Terminal<B>) -> Result<()> {
    let timeout = std::time::Duration::from_millis(500);
    let mut app = App::new();
    loop {
        terminal.draw(|frame| ui(frame, &mut app))?;

        if event::poll(timeout)? {
            if let event::Event::Key(key) = event::read()? {
                use event::KeyCode::{Char, Esc};
                match key.code {
                    Char('q') | Char('Q') | Esc => return Ok(()),
                    _ => {}
                }
            }
        }
        app.on_tick();
    }
}

#[derive(Clone)]
pub struct RandomSignal {
    distribution: Uniform<u64>,
    rng: ThreadRng,
}

impl RandomSignal {
    pub fn new(lower: u64, upper: u64) -> RandomSignal {
        RandomSignal {
            distribution: Uniform::new(lower, upper),
            rng: rand::thread_rng(),
        }
    }
}

impl Iterator for RandomSignal {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        Some(self.distribution.sample(&mut self.rng))
    }
}

struct App {
    signal: RandomSignal,
    data1: Vec<u64>,
    data2: Vec<u64>,
    data3: Vec<u64>,
}

impl App {
    fn new() -> App {
        let mut signal = RandomSignal::new(0, 100);
        let data1 = signal.by_ref().take(200).collect::<Vec<u64>>();
        let data2 = signal.by_ref().take(200).collect::<Vec<u64>>();
        let data3 = signal.by_ref().take(200).collect::<Vec<u64>>();
        App {
            signal,
            data1,
            data2,
            data3,
        }
    }

    fn on_tick(&mut self) {
        let value = self.signal.next().unwrap();
        self.data1.pop();
        self.data1.insert(0, value);
        let value = self.signal.next().unwrap();
        self.data2.pop();
        self.data2.insert(0, value);
        let value = self.signal.next().unwrap();
        self.data3.pop();
        self.data3.insert(0, value);
    }
}

fn ui<B: Backend>(frame: &mut Frame<B>, app: &mut App) {
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .margin(2)
        .constraints([
            Constraint::Length(3),
            Constraint::Length(3),
            Constraint::Length(7),
            Constraint::Min(0),
        ])
        .split(frame.size());
    let sparkline = widgets::Sparkline::default()
        .block(
            Block::default()
                .title("温度")
                .borders(Borders::LEFT | Borders::RIGHT),
        )
        .data(&app.data1)
        .style(Style::default().fg(Color::Yellow));
    frame.render_widget(sparkline, chunks[0]);
    let sparkline = widgets::Sparkline::default()
        .block(
            Block::default()
                .title("湿度")
                .borders(Borders::LEFT | Borders::RIGHT),
        )
        .data(&app.data2)
        .style(Style::default().bg(Color::Green));
    frame.render_widget(sparkline, chunks[1]);
    // Multiline
    let sparkline = widgets::Sparkline::default()
        .block(
            Block::default()
                .title("降水")
                .borders(Borders::LEFT | Borders::RIGHT),
        )
        .data(&app.data3)
        .style(Style::default().fg(Color::Red));
    frame.render_widget(sparkline, chunks[2]);
}

标签:mut,示例,default,self,terminal,Tui,let,0061,signal
From: https://www.cnblogs.com/jiangbo4444/p/16746245.html

相关文章

  • 0064-Tui-图表示例
    环境Time2022-08-16Rust1.63.0Tui0.18.0前言说明参考:https://github.com/fdehau/tui-rs/blob/master/examples/chart.rs目标使用tui-rs显示图表。常量数据......
  • 0065-Tui-Canvas 示例
    环境Time2022-08-17Rust1.63.0Tui0.18.0前言说明参考:https://github.com/fdehau/tui-rs/blob/master/examples/canvas.rs目标使用tui-rs显示Canvas。定义......
  • 0066-Tui-自定义组件
    环境Time2022-08-17Rust1.63.0Tui0.18.0前言说明参考:https://github.com/fdehau/tui-rs/blob/master/examples/custom_widget.rs目标使用tui-rs自定义一个......
  • 0067-Tui-panic 处理
    环境Time2022-08-17Rust1.63.0Tui0.18.0前言说明参考:https://github.com/fdehau/tui-rs/blob/master/examples/panic.rs目标使用tui-rs定义一个panichook......
  • 0068-Tui-用户输入
    环境Time2022-08-18Rust1.63.0Tui0.18.0前言说明参考:https://github.com/fdehau/tui-rs/blob/master/examples/user_input.rs目标使用tui-rs来处理用户的输......
  • 0062-Tui-表格示例
    环境Time2022-08-16Rust1.63.0Tui0.18.0前言说明参考:https://github.com/fdehau/tui-rs/blob/master/examples/table.rs目标使用tui-rs显示表格。定义应用......
  • 0063-Tui-页签示例
    环境Time2022-08-16Rust1.63.0Tui0.18.0前言说明参考:https://github.com/fdehau/tui-rs/blob/master/examples/tabs.rs目标使用tui-rs显示页签。定义应用......
  • 0058-Tui-段落示例
    环境Time2022-08-12Rust1.63.0Tui0.18.0前言说明参考:https://github.com/fdehau/tui-rs/blob/master/examples/paragraph.rs目标使用tui-rs显示段落。定义......
  • 0055-Tui-条形图示例
    环境Time2022-08-09Rust1.62.0Tui0.18.0前言说明参考:https://github.com/fdehau/tui-rs/blob/master/examples/barchart.rs目标使用tui-rs显示条形图。第......
  • 0056-Tui-简单进度条
    环境Time2022-08-11Rust1.62.0Tui0.18.0前言说明参考:https://github.com/fdehau/tui-rs/blob/master/examples/gauge.rs目标使用tui-rs显示进度条。定义数......