diff options
author | jakobst1n <jakob.stendahl@outlook.com> | 2024-06-12 01:09:07 +0200 |
---|---|---|
committer | jakobst1n <jakob.stendahl@outlook.com> | 2024-06-12 01:09:07 +0200 |
commit | 68fb5ef079b8c122acde3252b713dd9c89d8aa5f (patch) | |
tree | 0bf782aa3578a9ef36ba357b39b2c912f019f082 | |
parent | 42c249ebe1cbfaac82b8fb349c34e6110d1df89f (diff) | |
download | textgraph-68fb5ef079b8c122acde3252b713dd9c89d8aa5f.tar.gz textgraph-68fb5ef079b8c122acde3252b713dd9c89d8aa5f.zip |
Add attempt at a braille mode
-rw-r--r-- | src/graph.rs | 93 | ||||
-rw-r--r-- | src/parseopts.rs | 7 | ||||
-rw-r--r-- | tg.1 | 7 |
3 files changed, 92 insertions, 15 deletions
diff --git a/src/graph.rs b/src/graph.rs index 861478c..1958056 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -41,7 +41,7 @@ impl<T: std::fmt::Display> std::fmt::Display for GraphPixel<T> { } /// Available options for how the graph should look -#[derive(Clone)] +#[derive(PartialEq, Clone)] pub enum GraphType { /// Use only * symbols Star, @@ -153,7 +153,11 @@ impl GraphBuilder { /// If you want to only see the "current state", you should clone first! pub fn build(&mut self) -> String { if self.cut_overflow { - self.keep_tail(self.draw_width); + if self.graph_type == GraphType::Braille { + self.keep_tail(self.draw_width * 2); + } else { + self.keep_tail(self.draw_width); + } } //let min_x = self.x_values.iter().cloned().fold(f64::INFINITY, f64::min); @@ -184,7 +188,11 @@ impl GraphBuilder { // Run a second time after axis has been calculated properly if self.cut_overflow { - self.keep_tail(self.draw_width); + if self.graph_type == GraphType::Braille { + self.keep_tail(self.draw_width * 2); + } else { + self.keep_tail(self.draw_width); + } } if true { @@ -199,7 +207,11 @@ impl GraphBuilder { }; // Scale the data - let scale_factor = (self.draw_height - 1) as f64 / (max_y - min_y); + let mut scale_height = self.draw_height; + if self.graph_type == GraphType::Braille { + scale_height = self.draw_height * 3; + } + let scale_factor = (scale_height - 1) as f64 / (max_y - min_y); for i in 0..self.y_values.len() { self.y_values[i] = ((self.y_values[i] - min_y) * scale_factor).round(); } @@ -217,13 +229,23 @@ impl GraphBuilder { // with the x values. // Make sure to only use one downsampling-algorithm fn downsample(&mut self) { - let factor = self.y_values.len() as f64 / self.draw_width as f64; - let mut new_values = Vec::with_capacity(self.draw_width); - for i in 0..self.draw_width { - let new_value = self.y_values[(i as f64 * factor) as usize]; - new_values.push(new_value); + if self.graph_type == GraphType::Braille { + let factor = self.y_values.len() as f64 / (self.draw_width as f64 * 2.0); + let mut new_values = Vec::with_capacity(self.draw_width * 2); + for i in 0..self.draw_width * 2 { + let new_value = self.y_values[(i as f64 * factor) as usize]; + new_values.push(new_value); + } + self.y_values = new_values; + } else { + let factor = self.y_values.len() as f64 / self.draw_width as f64; + let mut new_values = Vec::with_capacity(self.draw_width); + for i in 0..self.draw_width { + let new_value = self.y_values[(i as f64 * factor) as usize]; + new_values.push(new_value); + } + self.y_values = new_values; } - self.y_values = new_values; } /// Turn canvas into a string @@ -370,7 +392,56 @@ impl GraphBuilder { /// Draw a graph using * for the pixels of the graph fn draw_braille(&mut self) { - unimplemented!("The braille mode is not implemented"); + let mut i = 0; + let mut x = 0; + while i < self.y_values.len() - 1 { + let y1 = (self.draw_height * 3) - (self.y_values[i] as usize) - 1; + let y1_abs = y1 / 3; + let y2 = (self.draw_height * 3) - (self.y_values[i + 1] as usize) - 1; + let y2_abs = y2 / 3; + + if y1_abs == y2_abs { + let px = match (y1 % 3, y2 % 3) { + (0, 0) => ' ', + (0, 1) => '⠠', + (0, 2) => '⠐', + (0, 3) => '⠈', + (1, 0) => '⠄', + (1, 1) => '⠤', + (1, 2) => '⠔', + (1, 3) => '⠌', + (2, 0) => '⠂', + (2, 1) => '⠢', + (2, 2) => '⠒', + (2, 3) => '⠊', + (3, 0) => '⠁', + (3, 1) => '⠡', + (3, 2) => '⠑', + (3, 3) => '⠉', + _ => '?', + }; + self.draw(x, y1_abs, GraphPixel::Normal(px)); + } else { + let px = match y1 % 3 { + 0 => ' ', + 1 => '⠄', + 2 => '⠂', + 3 => '⠁', + _ => '?', + }; + self.draw(x, y1_abs, GraphPixel::Normal(px)); + let px = match y2 % 3 { + 0 => ' ', + 1 => '⠠', + 2 => '⠐', + 3 => '⠈', + _ => '?', + }; + self.draw(x, y2_abs, GraphPixel::Normal(px)); + } + i += 2; + x += 1; + } } } diff --git a/src/parseopts.rs b/src/parseopts.rs index 9cb1c7e..7d5d760 100644 --- a/src/parseopts.rs +++ b/src/parseopts.rs @@ -65,7 +65,7 @@ impl OptsBuilder { macro_rules! parseopts_panic { ($progname:expr) => { println!( - "Usage: {} [-h|--height <height>] [-w|--width <width>] [-t <star|ascii>]", + "Usage: {} [-h|--height <height>] [-w|--width <width>] [-t <star|ascii|braille>]", $progname ); std::process::exit(1); @@ -100,7 +100,7 @@ pub fn parseopt(opts: &mut OptsBuilder, arg: &str, value: Option<String>, progna } t => { println!( - "Unknown type \"{}\", valid options are \"star\", \"ascii\".", + "Unknown type \"{}\", valid options are \"star\", \"ascii\" and \"braille\".", t ); parseopts_panic!(progname); @@ -135,6 +135,9 @@ pub fn parseopt(opts: &mut OptsBuilder, arg: &str, value: Option<String>, progna "a" | "ascii" => { opts.graph_type = GraphType::Ascii; } + "b" | "braille" => { + opts.graph_type = GraphType::Braille; + } "c" | "cut" => { opts.cut = true; } @@ -20,11 +20,14 @@ Disable distracting elements, such as axis and non-graph text. Shorthand for -t ascii, if multiple options setting mode is specified, the last will likely be respected. +.IP "\fB-b, --braille\fR" +Shorthand for -t braille, if multiple options setting mode is specified, +the last will likely be respected. + .IP "\fB-n, --last-n\fR \fIcount\fR" If specified, only the newest \fIcount\fR samples will be plotted. This can be useful if you want to follow the latest state of a graph that is piped in. - .IP "\fB-c, --cut\fR" This is a special case of \fB--last-n\fR. Where the number of columns \fB--width\fI will be used for the count. @@ -32,7 +35,7 @@ This is a special case of \fB--last-n\fR. Where the number of columns .IP "\fB-t\fR \fItype\fR" The type of graph to draw, it defaults to \fBstar\fR, which is the fastest one. -Options are \fBstar\fR and \fBascii\fR. +Options are \fBstar\fR, \fBascii\fR and \fBbraille\fR. Ascii is slightly prettier to look at. .IP "\fB-w, --width\fR \fIwidth\fR" |