Skip to content

Commit

Permalink
feat(text-canvas): add lineChart() & lineChartStr()
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Aug 24, 2023
1 parent 76ca59d commit 097e00c
Showing 1 changed file with 55 additions and 1 deletion.
56 changes: 55 additions & 1 deletion packages/text-canvas/src/line.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import type { NumOrString } from "@thi.ng/api";
import { ensureArray } from "@thi.ng/arrays/ensure-array";
import { peek } from "@thi.ng/arrays/peek";
import { liangBarsky2Raw } from "@thi.ng/geom-clip-line/liang-barsky";
import type { Canvas } from "./canvas.js";
import { fitClamped } from "@thi.ng/math/fit";
import { minMax } from "@thi.ng/math/interval";
import { max as $max } from "@thi.ng/transducers/max";
import { min as $min } from "@thi.ng/transducers/min";
import { Canvas } from "./canvas.js";
import { formatCanvas } from "./format.js";
import { charCode } from "./utils.js";

/**
Expand Down Expand Up @@ -59,3 +65,51 @@ export const line = (
}
}
};

export const lineChart = (
canvas: Canvas,
x: number,
y: number,
height: number,
vals: Iterable<number>,
min?: number,
max?: number,
format = canvas.format
) => {
const $vals = ensureArray(vals);
min = min !== undefined ? min : $min($vals);
max = max !== undefined ? max : $max($vals);
height--;
format <<= 16;
const { x1, x2 } = peek(canvas.clipRects);
for (let i = 0, n = $vals.length - 1; i < n; i++) {
const xx = x + i;
if (xx < x1) continue;
if (xx > x2) break;
const ya = Math.round(fitClamped($vals[i], min, max, height, 0)) + y;
const yb =
Math.round(fitClamped($vals[i + 1], min, max, height, 0)) + y;
if (ya === yb) {
canvas.setAt(xx, ya, 0x2500 | format); // ─
} else {
// vline to new Y
let [y1, y2] = minMax(ya, yb);
while (++y1 < y2) canvas.setAt(xx, y1, 0x2502 | format); // │
// end points
canvas.setAt(xx, ya, (ya < yb ? 0x256e : 0x256f) | format); // ╮ ╯
canvas.setAt(xx, yb, (ya < yb ? 0x2570 : 0x256d) | format); // ╰ ╭
}
}
};

export const lineChartStr = (
height: number,
vals: Iterable<number>,
min?: number,
max?: number
) => {
const $vals = ensureArray(vals);
const surf = new Canvas($vals.length, height);
lineChart(surf, 0, 0, height, $vals, min, max);
return formatCanvas(surf);
};

0 comments on commit 097e00c

Please sign in to comment.