/* AAU CRM — lightweight SVG charts. Exposes on window. */ (function () { const GREEN = '#008060', INK = '#303030', GRID = '#ebebeb', SUB = '#8a8a8a'; function LineChart({ data, height = 220, color = INK, markers = [], fmt }) { const w = 640, h = height, pad = { l: 44, r: 16, t: 16, b: 28 }; const max = Math.max(...data.map(d => d.v)) * 1.1 || 1; const min = 0; const iw = w - pad.l - pad.r, ih = h - pad.t - pad.b; const x = i => pad.l + (i / (data.length - 1)) * iw; const y = v => pad.t + ih - ((v - min) / (max - min)) * ih; const path = data.map((d, i) => (i ? 'L' : 'M') + x(i) + ',' + y(d.v)).join(' '); const area = path + ` L${x(data.length - 1)},${pad.t + ih} L${x(0)},${pad.t + ih} Z`; const ticks = 4; return ( ); } function BarChart({ data, height = 220, color = GREEN, fmt, target }) { const w = 640, h = height, pad = { l: 44, r: 16, t: 16, b: 28 }; const max = Math.max(...data.map(d => d.v), target || 0) * 1.15 || 1; const iw = w - pad.l - pad.r, ih = h - pad.t - pad.b; const bw = iw / data.length * 0.6; const x = i => pad.l + (i + 0.5) / data.length * iw; const y = v => pad.t + ih - (v / max) * ih; return ( ); } function StackedBar({ data, keys, height = 220, fmt }) { const w = 640, h = height, pad = { l: 44, r: 16, t: 16, b: 28 }; const max = Math.max(...data.map(d => keys.reduce((s, k) => s + (d[k.key] || 0), 0))) * 1.15 || 1; const iw = w - pad.l - pad.r, ih = h - pad.t - pad.b, bw = iw / data.length * 0.6; const x = i => pad.l + (i + 0.5) / data.length * iw; return ( ); } function Donut({ data, size = 180, thickness = 28, center }) { const r = size / 2, ir = r - thickness, total = data.reduce((s, d) => s + d.v, 0) || 1; let a0 = -Math.PI / 2; const arc = (a0, a1) => { const x0 = r + r * Math.cos(a0), y0 = r + r * Math.sin(a0), x1 = r + r * Math.cos(a1), y1 = r + r * Math.sin(a1); const xi0 = r + ir * Math.cos(a1), yi0 = r + ir * Math.sin(a1), xi1 = r + ir * Math.cos(a0), yi1 = r + ir * Math.sin(a0); const large = a1 - a0 > Math.PI ? 1 : 0; return `M${x0},${y0} A${r},${r} 0 ${large} 1 ${x1},${y1} L${xi0},${yi0} A${ir},${ir} 0 ${large} 0 ${xi1},${yi1} Z`; }; return ( ); } function Funnel({ steps, height }) { // steps: [{l, v, color}] const max = steps[0].v || 1; return (