/**
* Chart primitives (owner of the drawing): inline-SVG emitters shared by the
* A4 dossier renderer (C186/C187) and the Instagram chart renderer (C191).
*
* Extracted from `dossieRender.mjs` when the Instagram generator became the
* second consumer, so a fix to the honest-scale/guardrail drawing lives once.
* The dossier keeps its mm/pt page composition; each consumer composes its own
* page around these primitives — never a second copy of the drawing.
*/
import { htmlEscape } from './reportText.mjs'
/**
* Domain palette of the dossier charts. Instagram passes its own Solla palette
* explicitly; this map stays the dossier default so its output is unchanged.
*/
export const CHART_COLORS = {
municipio: '#315c75',
regiao: '#9d8b64',
polo: '#8f819c',
instituicao: '#315c75',
setor: '#9d8b64',
rede: '#8f819c',
empenhado: '#6b4918',
liquidado: '#4a6b7c',
pago: '#285338',
autorizado: '#8a5a18',
restos: '#5b6470',
nao_informado: '#8b96a2',
default: '#315c75',
}
/**
* Honest-scale proportion of a value against the maximum, as a percentage
* (0..100). Zero stays zero (no bar is drawn); a present small value keeps a
* visible minimum so it is not mistaken for absent. Used for the ranking width
* and the column height of the Instagram renderer.
*/
export const proportionalPercent = (value, max) =>
value <= 0 ? 0 : Math.min(100, Math.max(2, Math.round((value / Math.max(1, max)) * 100)))
export const barChart = ({ rows, width = 330, rowHeight = 19, labelWidth = 118 }) => {
const max = Math.max(1, ...rows.map((row) => row.count))
const barMax = width - labelWidth - 26
const height = rows.length * rowHeight + 4
return ``
}
/** HTML list with a proportional bar per row — long labels wrap, nothing overlaps. */
export const valueList = ({ rows, format }) => {
const max = Math.max(1, ...rows.map((row) => row.value))
return `