// Lightweight data viz primitives (pure SVG, no deps)
function Sparkline({ data, width = 110, height = 30, color = "var(--brand)", fill = true }) {
if (!data || !data.length) return null;
const min = Math.min(...data);
const max = Math.max(...data);
const range = max - min || 1;
const pts = data.map((v, i) => {
const x = (i / (data.length - 1)) * (width - 2) + 1;
const y = height - 2 - ((v - min) / range) * (height - 4);
return [x, y];
});
const d = pts.map(([x, y], i) => (i === 0 ? `M${x} ${y}` : `L${x} ${y}`)).join(" ");
const area = `${d} L${width - 1} ${height - 1} L1 ${height - 1} Z`;
return (
);
}
function Bars({ data, width = 520, height = 140, color = "var(--brand)", labels }) {
const max = Math.max(...data);
const bw = (width - 20) / data.length;
const gap = 3;
return (
);
}
function StackedArea({ seriesA, seriesB, width = 900, height = 220, labels }) {
const combined = seriesA.map((a, i) => a + (seriesB[i] || 0));
const max = Math.max(...combined) * 1.08;
const w = width;
const h = height;
const pad = { t: 12, r: 12, b: 22, l: 40 };
const iw = w - pad.l - pad.r;
const ih = h - pad.t - pad.b;
const pt = (v, i, offset = 0) => {
const x = pad.l + (i / (seriesA.length - 1)) * iw;
const y = pad.t + ih - ((v + offset) / max) * ih;
return [x, y];
};
const areaPath = (arr, offsetArr = null) => {
const top = arr.map((v, i) => pt(v, i, offsetArr ? offsetArr[i] : 0));
const bottomOffset = offsetArr || new Array(arr.length).fill(0);
const bottom = bottomOffset.map((v, i) => pt(0, i, v)).reverse();
return [...top, ...bottom].map(([x, y], i) => (i === 0 ? `M${x} ${y}` : `L${x} ${y}`)).join(" ") + " Z";
};
const linePath = (arr, offsetArr = null) => arr
.map((v, i) => pt(v, i, offsetArr ? offsetArr[i] : 0))
.map(([x, y], i) => (i === 0 ? `M${x} ${y}` : `L${x} ${y}`))
.join(" ");
const gridTicks = 4;
return (
);
}
function Donut({ segments, size = 140, thickness = 18 }) {
const total = segments.reduce((a, s) => a + s.value, 0);
const r = (size - thickness) / 2;
const c = size / 2;
const circ = 2 * Math.PI * r;
let offset = 0;
return (
);
}
window.Sparkline = Sparkline;
window.Bars = Bars;
window.StackedArea = StackedArea;
window.Donut = Donut;