Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
import { extent } from "./charts_extent.ts"; ← from charts.extent ^1.0.0 · built alongside by fune
import { linearScale } from "./charts_scale_linear_scale.ts";
import { linePath } from "./charts_shape_line_path.ts";
import type { Point } from "./charts_shape_types.ts";
import type { Sparkline } from "./charts_sparkline_types.ts";
import { roundFloat } from "./math_round_float.ts"; ← from math.round-float ^1.0.0 · built alongside by fune
function checkSize(value: number, what: string): void {
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
throw new RangeError(`${what} must be a finite number of zero or more, received ${value}`);
}
}
/**
* A sparkline in a box: values evenly spaced from left to right, the lowest
* at the bottom and the highest at the top of the padded box.
*
* A flat series is drawn along the middle rather than divided by a zero
* range; a single value sits at the right-hand end, where the latest value of
* a sparkline belongs.
*/
export function sparkline(values: readonly (number | null)[], width: number, height: number, padding: number): Sparkline {
checkSize(width, "width");
checkSize(height, "height");
checkSize(padding, "padding");
if (width - 2 * padding <= 0 || height - 2 * padding <= 0) {
throw new RangeError(`the box is too small for its padding: ${width} by ${height} with ${padding} on each side`);
}
const range = extent(values);
if (range === null) return { path: "", end: null };
const [lo, hi] = range;
const n = values.length;
const points: Point[] = values.map((v, i) => {
const x = n === 1 ? width - padding : linearScale([0, n - 1], [padding, width - padding], i, false);
if (v === null) return { x, y: null };
const y = lo === hi ? height / 2 : linearScale([lo, hi], [height - padding, padding], v, false);
return { x, y };
});
let end = null;
for (const p of points) {
if (p.y !== null) end = { x: roundFloat(p.x, 2), y: roundFloat(p.y, 2) };
}
return { path: linePath(points), end };
}