From 0c5986851dee23e09751ae594d8a43a84a0dab61 Mon Sep 17 00:00:00 2001
From: gennyble <gen@nyble.dev>
Date: Sun, 16 Feb 2025 10:17:28 -0600
Subject: Network stats

---
 src/griph/mod.rs | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 src/griph/mod.rs

(limited to 'src/griph')

diff --git a/src/griph/mod.rs b/src/griph/mod.rs
new file mode 100644
index 0000000..b034207
--- /dev/null
+++ b/src/griph/mod.rs
@@ -0,0 +1,98 @@
+use gifed::{writer::ImageBuilder, Gif, StandardGif};
+
+#[rustfmt::skip]
+pub const DARK_PALETTE: &[u8] = &[
+	  0,   0,   0, // Background - Black
+	192, 192, 192, // Graphline - Mostly White
+	 64,  64,  64, // Gridlines - Dark gray
+	 32,  32,  32, // Minor Gridlines - Darker gray
+	 48,  48, 192, // Primary 2 Colour - Blue
+	 48, 192,  48, // Secondary 2 Colour - Green
+];
+
+const BACKGROUND: u8 = 0;
+const LINE: u8 = 1;
+const GRIDLINE: u8 = 2;
+const MINOR_GRIDLINE: u8 = 3;
+const LINE1: u8 = 4;
+const LINE2: u8 = 5;
+
+const WIDTH: usize = 256;
+const HEIGHT: usize = 160;
+const SIZE: usize = WIDTH * HEIGHT;
+
+pub fn make_1line(min: usize, max: usize, values: &[usize]) -> Gif {
+	let range = max - min;
+	// this assumes a range of values that is >1 per pixel
+	let vpp = range / HEIGHT;
+
+	let mut raster = vec![0; SIZE];
+	draw_grid(&mut raster);
+	draw_line(&mut raster, values, vpp, LINE);
+
+	let mut standard = Gif::new(WIDTH as u16, HEIGHT as u16);
+	standard.set_palette(Some(DARK_PALETTE[0..12].try_into().unwrap()));
+	standard.push(
+		ImageBuilder::new(WIDTH as u16, HEIGHT as u16)
+			.build(raster)
+			.unwrap(),
+	);
+
+	standard
+}
+
+pub fn make_2line(min: usize, max: usize, values1: &[usize], values2: &[usize]) -> Gif {
+	let range = max - min;
+	// this assumes a range of values that is >1 per pixel
+	let vpp = range / HEIGHT;
+
+	let mut raster = vec![0; SIZE];
+	draw_grid(&mut raster);
+	draw_line(&mut raster, values1, vpp, LINE1);
+	draw_line(&mut raster, values2, vpp, LINE2);
+
+	let mut standard = Gif::new(WIDTH as u16, HEIGHT as u16);
+	standard.set_palette(Some(DARK_PALETTE.try_into().unwrap()));
+	standard.push(
+		ImageBuilder::new(WIDTH as u16, HEIGHT as u16)
+			.build(raster)
+			.unwrap(),
+	);
+
+	standard
+}
+
+fn draw_grid(raster: &mut [u8]) {
+	// Draw Divisions
+	// we want a gridline every 16 pixels, but not the bottom
+	// or top, so only 8.
+	for div in 1..=9 {
+		let y_val = div * 16;
+
+		let grid = if div % 2 == 0 {
+			GRIDLINE
+		} else {
+			MINOR_GRIDLINE
+		};
+
+		for x in 0..WIDTH {
+			raster[y_val * WIDTH + x] = grid;
+		}
+	}
+}
+
+fn draw_line(raster: &mut [u8], values: &[usize], vpp: usize, colour: u8) {
+	// Draw Line
+	// this will be discontinuous and i think that's okay. we
+	// could make it a proper line by keeping track what value
+	// was last and drawing the whole vertical there
+	for (x, value) in values.iter().enumerate() {
+		let value_height = value / vpp;
+		if value_height > (HEIGHT - 1) {
+			continue;
+		}
+		let y_val = (HEIGHT - 1) - value_height;
+
+		raster[y_val * WIDTH + x] = colour;
+	}
+}
-- 
cgit 1.4.1-3-g733a5