Browse and listen to thousands of radio stations across the globe right from your terminal 🌎 📻 🎵✨
radio rust tokio web-radio command-line-tool tui
at main 116 lines 3.5 kB view raw
1use ratatui::{ 2 style::Style, 3 text::Span, 4 widgets::{Axis, GraphType}, 5}; 6 7use crate::input::Matrix; 8 9use super::{DataSet, Dimension, DisplayMode, GraphConfig}; 10 11#[derive(Default)] 12pub struct Vectorscope {} 13 14impl DisplayMode for Vectorscope { 15 fn from_args(_opts: &crate::cfg::SourceOptions) -> Self { 16 Vectorscope::default() 17 } 18 19 fn mode_str(&self) -> &'static str { 20 "vector" 21 } 22 23 fn channel_name(&self, index: usize) -> String { 24 format!("{}", index) 25 } 26 27 fn header(&self, _: &GraphConfig) -> String { 28 "live".into() 29 } 30 31 fn axis(&self, cfg: &GraphConfig, dimension: Dimension) -> Axis<'_> { 32 let (name, bounds) = match dimension { 33 Dimension::X => ("left -", [-cfg.scale, cfg.scale]), 34 Dimension::Y => ("| right", [-cfg.scale, cfg.scale]), 35 }; 36 let mut a = Axis::default(); 37 if cfg.show_ui { 38 // TODO don't make it necessary to check show_ui inside here 39 a = a.title(Span::styled(name, Style::default().fg(cfg.labels_color))); 40 } 41 a.style(Style::default().fg(cfg.axis_color)).bounds(bounds) 42 } 43 44 fn references(&self, cfg: &GraphConfig) -> Vec<DataSet> { 45 vec![ 46 DataSet::new( 47 None, 48 vec![(-cfg.scale, 0.0), (cfg.scale, 0.0)], 49 cfg.marker_type, 50 GraphType::Line, 51 cfg.axis_color, 52 ), 53 DataSet::new( 54 None, 55 vec![(0.0, -cfg.scale), (0.0, cfg.scale)], 56 cfg.marker_type, 57 GraphType::Line, 58 cfg.axis_color, 59 ), 60 ] 61 } 62 63 fn process(&mut self, cfg: &GraphConfig, data: &Matrix<f64>) -> Vec<DataSet> { 64 let mut out = Vec::new(); 65 66 for (n, chunk) in data.chunks(2).enumerate() { 67 let mut tmp = vec![]; 68 match chunk.len() { 69 2 => { 70 for i in 0..std::cmp::min(chunk[0].len(), chunk[1].len()) { 71 if i > cfg.samples as usize { 72 break; 73 } 74 tmp.push((chunk[0][i], chunk[1][i])); 75 } 76 } 77 1 => { 78 for i in 0..chunk[0].len() { 79 if i > cfg.samples as usize { 80 break; 81 } 82 tmp.push((chunk[0][i], i as f64)); 83 } 84 } 85 _ => continue, 86 } 87 // split it in two for easier coloring 88 // TODO configure splitting in multiple parts? 89 let pivot = tmp.len() / 2; 90 out.push(DataSet::new( 91 Some(self.channel_name((n * 2) + 1)), 92 tmp[pivot..].to_vec(), 93 cfg.marker_type, 94 if cfg.scatter { 95 GraphType::Scatter 96 } else { 97 GraphType::Line 98 }, 99 cfg.palette((n * 2) + 1), 100 )); 101 out.push(DataSet::new( 102 Some(self.channel_name(n * 2)), 103 tmp[..pivot].to_vec(), 104 cfg.marker_type, 105 if cfg.scatter { 106 GraphType::Scatter 107 } else { 108 GraphType::Line 109 }, 110 cfg.palette(n * 2), 111 )); 112 } 113 114 out 115 } 116}