mirror of
https://github.com/alemidev/scope-tui.git
synced 2024-11-23 14:14:48 +01:00
feat: update ratatui, allow optional legends
This commit is contained in:
parent
ab2d4a0af8
commit
0d4975b189
5 changed files with 51 additions and 46 deletions
|
@ -17,8 +17,8 @@ derive_more = "0.99.17"
|
||||||
thiserror = "1.0.48"
|
thiserror = "1.0.48"
|
||||||
rustfft = "6.1.0"
|
rustfft = "6.1.0"
|
||||||
# for TUI backend
|
# for TUI backend
|
||||||
ratatui = { version = "0.23.0", features = ["all-widgets"], optional = true }
|
ratatui = { version = "0.26", features = ["all-widgets"], optional = true }
|
||||||
crossterm = { version = "0.25", optional = true }
|
crossterm = { version = "0.27", optional = true }
|
||||||
# for pulseaudio
|
# for pulseaudio
|
||||||
libpulse-binding = { version = "2.0", optional = true }
|
libpulse-binding = { version = "2.0", optional = true }
|
||||||
libpulse-simple-binding = { version = "2.25", optional = true }
|
libpulse-simple-binding = { version = "2.25", optional = true }
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub trait DisplayMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DataSet {
|
pub struct DataSet {
|
||||||
name: String,
|
name: Option<String>,
|
||||||
data: Vec<(f64, f64)>,
|
data: Vec<(f64, f64)>,
|
||||||
marker_type: Marker,
|
marker_type: Marker,
|
||||||
graph_type: GraphType,
|
graph_type: GraphType,
|
||||||
|
@ -56,8 +56,11 @@ pub struct DataSet {
|
||||||
|
|
||||||
impl<'a> From::<&'a DataSet> for Dataset<'a> {
|
impl<'a> From::<&'a DataSet> for Dataset<'a> {
|
||||||
fn from(ds: &'a DataSet) -> Dataset<'a> {
|
fn from(ds: &'a DataSet) -> Dataset<'a> {
|
||||||
Dataset::default()
|
let mut out = Dataset::default(); // TODO creating a binding is kinda ugly, is it avoidable?
|
||||||
.name(ds.name.clone())
|
if let Some(name) = &ds.name {
|
||||||
|
out = out.name(name.clone());
|
||||||
|
}
|
||||||
|
out
|
||||||
.marker(ds.marker_type)
|
.marker(ds.marker_type)
|
||||||
.graph_type(ds.graph_type)
|
.graph_type(ds.graph_type)
|
||||||
.style(Style::default().fg(ds.color))
|
.style(Style::default().fg(ds.color))
|
||||||
|
@ -65,9 +68,10 @@ impl<'a> From::<&'a DataSet> for Dataset<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO this is pretty ugly but I need datasets which own the data
|
||||||
impl DataSet {
|
impl DataSet {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
name: String,
|
name: Option<String>,
|
||||||
data: Vec<(f64, f64)>,
|
data: Vec<(f64, f64)>,
|
||||||
marker_type: Marker,
|
marker_type: Marker,
|
||||||
graph_type: GraphType,
|
graph_type: GraphType,
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl DisplayMode for Oscilloscope {
|
||||||
|
|
||||||
fn references(&self, cfg: &GraphConfig) -> Vec<DataSet> {
|
fn references(&self, cfg: &GraphConfig) -> Vec<DataSet> {
|
||||||
vec![
|
vec![
|
||||||
DataSet::new("".into(), vec![(0.0, 0.0), (cfg.samples as f64, 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(0.0, 0.0), (cfg.samples as f64, 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ impl DisplayMode for Oscilloscope {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.triggering {
|
if self.triggering {
|
||||||
out.push(DataSet::new("T".into(), vec![(0.0, self.threshold)], cfg.marker_type, GraphType::Scatter, cfg.labels_color));
|
out.push(DataSet::new(Some("T".into()), vec![(0.0, self.threshold)], cfg.marker_type, GraphType::Scatter, cfg.labels_color));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n, channel) in data.iter().enumerate().rev() {
|
for (n, channel) in data.iter().enumerate().rev() {
|
||||||
|
@ -94,7 +94,7 @@ impl DisplayMode for Oscilloscope {
|
||||||
|
|
||||||
if self.peaks {
|
if self.peaks {
|
||||||
out.push(DataSet::new(
|
out.push(DataSet::new(
|
||||||
"".into(),
|
None,
|
||||||
vec![(0.0, min), (0.0, max)],
|
vec![(0.0, min), (0.0, max)],
|
||||||
cfg.marker_type,
|
cfg.marker_type,
|
||||||
GraphType::Scatter,
|
GraphType::Scatter,
|
||||||
|
@ -103,7 +103,7 @@ impl DisplayMode for Oscilloscope {
|
||||||
}
|
}
|
||||||
|
|
||||||
out.push(DataSet::new(
|
out.push(DataSet::new(
|
||||||
self.channel_name(n),
|
Some(self.channel_name(n)),
|
||||||
tmp,
|
tmp,
|
||||||
cfg.marker_type,
|
cfg.marker_type,
|
||||||
if cfg.scatter { GraphType::Scatter } else { GraphType::Line },
|
if cfg.scatter { GraphType::Scatter } else { GraphType::Line },
|
||||||
|
|
|
@ -115,11 +115,12 @@ impl DisplayMode for Spectroscope {
|
||||||
if self.window {
|
if self.window {
|
||||||
chunk = hann_window(chunk.as_slice());
|
chunk = hann_window(chunk.as_slice());
|
||||||
}
|
}
|
||||||
let max_val = chunk.iter().max_by(|a, b| a.total_cmp(b)).expect("empty dataset?");
|
let mut max_val = *chunk.iter().max_by(|a, b| a.total_cmp(b)).expect("empty dataset?");
|
||||||
let mut tmp : Vec<Complex<f64>> = chunk.iter().map(|x| Complex { re: *x / *max_val, im: 0.0 }).collect();
|
if max_val < 1. { max_val = 1.; }
|
||||||
|
let mut tmp : Vec<Complex<f64>> = chunk.iter().map(|x| Complex { re: *x / max_val, im: 0.0 }).collect();
|
||||||
fft.process(tmp.as_mut_slice());
|
fft.process(tmp.as_mut_slice());
|
||||||
out.push(DataSet::new(
|
out.push(DataSet::new(
|
||||||
self.channel_name(n),
|
Some(self.channel_name(n)),
|
||||||
tmp[..=tmp.len() / 2]
|
tmp[..=tmp.len() / 2]
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -149,37 +150,37 @@ impl DisplayMode for Spectroscope {
|
||||||
fn references(&self, cfg: &GraphConfig) -> Vec<DataSet> {
|
fn references(&self, cfg: &GraphConfig) -> Vec<DataSet> {
|
||||||
let s = if self.log_y { (cfg.scale as f64 / 10.0).ln() } else { cfg.scale as f64 / 10.0 };
|
let s = if self.log_y { (cfg.scale as f64 / 10.0).ln() } else { cfg.scale as f64 / 10.0 };
|
||||||
vec![
|
vec![
|
||||||
DataSet::new("".into(), vec![(0.0, 0.0), ((cfg.samples as f64).ln(), 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(0.0, 0.0), ((cfg.samples as f64).ln(), 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
|
|
||||||
// TODO can we auto generate these? lol...
|
// TODO can we auto generate these? lol...
|
||||||
DataSet::new("".into(), vec![(20.0f64.ln(), 0.0), (20.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(20.0f64.ln(), 0.0), (20.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(30.0f64.ln(), 0.0), (30.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(30.0f64.ln(), 0.0), (30.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(40.0f64.ln(), 0.0), (40.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(40.0f64.ln(), 0.0), (40.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(50.0f64.ln(), 0.0), (50.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(50.0f64.ln(), 0.0), (50.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(60.0f64.ln(), 0.0), (60.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(60.0f64.ln(), 0.0), (60.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(70.0f64.ln(), 0.0), (70.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(70.0f64.ln(), 0.0), (70.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(80.0f64.ln(), 0.0), (80.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(80.0f64.ln(), 0.0), (80.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(90.0f64.ln(), 0.0), (90.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(90.0f64.ln(), 0.0), (90.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(100.0f64.ln(), 0.0), (100.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(100.0f64.ln(), 0.0), (100.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(200.0f64.ln(), 0.0), (200.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(200.0f64.ln(), 0.0), (200.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(300.0f64.ln(), 0.0), (300.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(300.0f64.ln(), 0.0), (300.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(400.0f64.ln(), 0.0), (400.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(400.0f64.ln(), 0.0), (400.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(500.0f64.ln(), 0.0), (500.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(500.0f64.ln(), 0.0), (500.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(600.0f64.ln(), 0.0), (600.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(600.0f64.ln(), 0.0), (600.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(700.0f64.ln(), 0.0), (700.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(700.0f64.ln(), 0.0), (700.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(800.0f64.ln(), 0.0), (800.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(800.0f64.ln(), 0.0), (800.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(900.0f64.ln(), 0.0), (900.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(900.0f64.ln(), 0.0), (900.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(1000.0f64.ln(), 0.0), (1000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(1000.0f64.ln(), 0.0), (1000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(2000.0f64.ln(), 0.0), (2000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(2000.0f64.ln(), 0.0), (2000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(3000.0f64.ln(), 0.0), (3000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(3000.0f64.ln(), 0.0), (3000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(4000.0f64.ln(), 0.0), (4000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(4000.0f64.ln(), 0.0), (4000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(5000.0f64.ln(), 0.0), (5000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(5000.0f64.ln(), 0.0), (5000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(6000.0f64.ln(), 0.0), (6000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(6000.0f64.ln(), 0.0), (6000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(7000.0f64.ln(), 0.0), (7000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(7000.0f64.ln(), 0.0), (7000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(8000.0f64.ln(), 0.0), (8000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(8000.0f64.ln(), 0.0), (8000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(9000.0f64.ln(), 0.0), (9000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(9000.0f64.ln(), 0.0), (9000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(10000.0f64.ln(), 0.0), (10000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(10000.0f64.ln(), 0.0), (10000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(20000.0f64.ln(), 0.0), (20000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(20000.0f64.ln(), 0.0), (20000.0f64.ln(), s)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,8 @@ impl DisplayMode for Vectorscope {
|
||||||
|
|
||||||
fn references(&self, cfg: &GraphConfig) -> Vec<DataSet> {
|
fn references(&self, cfg: &GraphConfig) -> Vec<DataSet> {
|
||||||
vec![
|
vec![
|
||||||
DataSet::new("".into(), vec![(-(cfg.scale as f64), 0.0), (cfg.scale as f64, 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(-(cfg.scale as f64), 0.0), (cfg.scale as f64, 0.0)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
DataSet::new("".into(), vec![(0.0, -(cfg.scale as f64)), (0.0, cfg.scale as f64)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
DataSet::new(None, vec![(0.0, -(cfg.scale as f64)), (0.0, cfg.scale as f64)], cfg.marker_type, GraphType::Line, cfg.axis_color),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,14 +65,14 @@ impl DisplayMode for Vectorscope {
|
||||||
// TODO configure splitting in multiple parts?
|
// TODO configure splitting in multiple parts?
|
||||||
let pivot = tmp.len() / 2;
|
let pivot = tmp.len() / 2;
|
||||||
out.push(DataSet::new(
|
out.push(DataSet::new(
|
||||||
self.channel_name((n * 2) + 1),
|
Some(self.channel_name((n * 2) + 1)),
|
||||||
tmp[pivot..].to_vec(),
|
tmp[pivot..].to_vec(),
|
||||||
cfg.marker_type,
|
cfg.marker_type,
|
||||||
if cfg.scatter { GraphType::Scatter } else { GraphType::Line },
|
if cfg.scatter { GraphType::Scatter } else { GraphType::Line },
|
||||||
cfg.palette((n * 2) + 1),
|
cfg.palette((n * 2) + 1),
|
||||||
));
|
));
|
||||||
out.push(DataSet::new(
|
out.push(DataSet::new(
|
||||||
self.channel_name(n * 2),
|
Some(self.channel_name(n * 2)),
|
||||||
tmp[..pivot].to_vec(),
|
tmp[..pivot].to_vec(),
|
||||||
cfg.marker_type,
|
cfg.marker_type,
|
||||||
if cfg.scatter { GraphType::Scatter } else { GraphType::Line },
|
if cfg.scatter { GraphType::Scatter } else { GraphType::Line },
|
||||||
|
|
Loading…
Reference in a new issue