@thi.ng/text-canvas
Version:
Text based canvas, drawing, plotting, tables with arbitrary formatting (incl. ANSI/HTML)
62 lines (61 loc) • 2.07 kB
JavaScript
import { ensureArray } from "@thi.ng/arrays/ensure-array";
import { peek } from "@thi.ng/arrays/peek";
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 { barChartVLines } from "./bars.js";
import { Canvas } from "./canvas.js";
import { formatCanvas } from "./format.js";
import { blendBarsVAdd, blitBarsV } from "./image.js";
import { textLines } from "./text.js";
const plotBarChartV = (canv, opts, ...plots) => {
const channel = canv.empty();
const blend = opts.blend || blendBarsVAdd;
for (let plot of plots) {
channel.clear();
textLines(
channel,
0,
0,
barChartVLines(channel.height, plot.data, opts.min, opts.max),
plot.color
);
blitBarsV(canv, channel, 0, 0, blend);
}
return canv;
};
const plotLineChart = (canvas, x, y, height, vals, min, max, format = canvas.format) => {
const $vals = ensureArray(vals);
min = min !== void 0 ? min : $min($vals);
max = max !== void 0 ? 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, 9472 | format);
} else {
let [y1, y2] = minMax(ya, yb);
while (++y1 < y2) canvas.setAt(xx, y1, 9474 | format);
canvas.setAt(xx, ya, (ya < yb ? 9582 : 9583) | format);
canvas.setAt(xx, yb, (ya < yb ? 9584 : 9581) | format);
}
}
};
const lineChartStr = (height, vals, min, max) => {
const $vals = ensureArray(vals);
const surf = new Canvas($vals.length, height);
plotLineChart(surf, 0, 0, height, $vals, min, max);
return formatCanvas(surf);
};
export {
lineChartStr,
plotBarChartV,
plotLineChart
};