{
  "schema": "leumas.docs.page/1",
  "id": "adapter:domain/chart",
  "slug": "adapters/domain/chart",
  "kind": "capabilities",
  "bucket": "package",
  "title": "chart — pure data→SVG chart pack",
  "name": "chart",
  "eyebrow": "pure data→SVG chart pack",
  "chip": null,
  "summary": "Pure server-side data-to-SVG chart pack: render arbitrary data into standalone, themeable SVG charts with zero dependencies. Supports bar (vertical/horizontal), line, area (with smoothing), pie...",
  "keywords": [
    "chart",
    "smoothing",
    "donut",
    "sparkline",
    "gauge",
    "leumas chart",
    "how to use chart",
    "bubble"
  ],
  "audience": "both",
  "funnel": {
    "product": null,
    "cta": null
  },
  "body": "# chart — pure data→SVG chart pack\n\nServer-side data visualization with **zero npm dependencies** (Node built-ins only). Feed it plain\ndata, get back a complete, standalone `<svg>` string you can inline, embed in an email or PDF, drop\ninto a dashboard/report, or turn into an `<img>` data URI. Deterministic, framework-agnostic, and\nthemeable.\n\n## Tools (17)\n\n| Tool | Input shape | What it draws |\n|---|---|---|\n| `bar` | `[n]` · `[{label,value}]` · `{label:value}` | Vertical (or `options.horizontal`) bar chart with nice axes |\n| `line` | numeric series · multi-series | Line chart, optional `smooth`, `showPoints`, multi-series legend |\n| `area` | numeric series · multi-series | Filled area chart (single or overlaid) |\n| `pie` | categories | Pie chart with % labels + legend |\n| `donut` | categories | Donut (ring) chart; supports `centerLabel`/`centerSubLabel` |\n| `sparkline` | numeric series | Tiny inline trend line (no axes), optional min/max markers |\n| `gauge` | number or `{value,min,max}` | Semicircular gauge/dial with value readout + `zones` |\n| `scatter` | `[{x,y}]` · `[[x,y]]` · `{series}` | Scatter/bubble plot (`r` sizes bubbles), numeric x/y axes |\n| `stackedBar` | multi-series | Stacked bar chart |\n| `groupedBar` | multi-series | Grouped/clustered bar chart |\n| `histogram` | numeric series | Auto-binned frequency histogram (`options.bins`) |\n| `radar` | multi-series (≥3 axes) | Radar/spider chart |\n| `heatmap` | 2D matrix · `{values,rows,cols}` | Color-graded heatmap/matrix (`lowColor`/`highColor`) |\n| `progress` | categories | Horizontal progress bars (`options.percent`) |\n| `bullet` | `{value,target,max,bands}` | Bullet chart (value vs target across qualitative bands) |\n| `toDataUri` | `{ svg }` | SVG string (or chart result) → `data:image/svg+xml` URI |\n| `palette` | `{ name? }` | Return a named color ramp (or all) for `options.colors` |\n\nEvery **rendering** tool takes one args object `{ data, options }` and returns\n`{ svg, width, height }`. An HTTP POST body maps 1:1 onto the call.\n\n## Theming (`options`)\n\n- `colors: []` — series palette, **or** `palette: 'ocean'` (a named ramp — see `palette` tool).\n- `width`, `height`, `title`, `titleColor`, `background`, `rounded`.\n- `padding` — a number, or `{ top, right, bottom, left }`.\n- Per-chart toggles: `showValues`, `showLegend`, `showGrid`, `showPoints`, `smooth` (line/area),\n  `horizontal` (bar), `innerRadius`/`centerLabel` (donut), `bins` (histogram),\n  `min`/`max` (gauge/heatmap/bullet), `unit`/`label`/`zones` (gauge), `target`/`bands` (bullet),\n  `lowColor`/`highColor` (heatmap), `percent` (progress), `strokeWidth`.\n\nNamed palettes: `default`, `vivid`, `ocean`, `sunset`, `forest`, `mono`, `warm`, `cool`.\n\n## Usage\n\n```js\nimport chart from './index.js';\n\n// Simple bar chart\nconst { svg } = chart.adapters.bar({\n  data: [{ label: 'Q1', value: 120 }, { label: 'Q2', value: 180 }, { label: 'Q3', value: 90 }],\n  options: { title: 'Quarterly Revenue', palette: 'ocean', height: 320 },\n});\n\n// Multi-series line with smoothing\nchart.adapters.line({\n  data: { categories: ['Jan', 'Feb', 'Mar'], series: [\n    { name: 'Web', values: [10, 22, 18] },\n    { name: 'iOS', values: [5, 9, 14] },\n  ]},\n  options: { smooth: true, showPoints: true },\n});\n\n// Embed anywhere as an <img>\nconst { dataUri } = chart.adapters.toDataUri({ svg });\n// `<img src=\"${dataUri}\">` — works in email, PDF, static HTML\n\n// KPI donut with center label\nchart.adapters.donut({ data: { Done: 72, Todo: 28 }, options: { centerLabel: '72%', centerSubLabel: 'complete' } });\n\n// List a palette to reuse as options.colors\nchart.adapters.palette({ name: 'sunset' }); // → { name, colors: [...] }\n```\n\n## DRY boundary\n\n**No generic charting existed in Leumas2 before this pack.** The only prior SVG-plotting code lives\nin `domain/a-physics` (`plot`), but that is **physics-specific**: it sweeps a physics *formula's*\nvariable to draw a function curve (formula-driven, domain-bound). This pack charts **arbitrary\ncaller-supplied data** (categories / series / points / matrices / KPIs) with no concept of formulas\nor physics — reusable across emails, PDFs, dashboards, and reports.\n\nRule of thumb: **physics `plot` graphs a function; `chart` graphs data.** Keep them separate.\n\nThe tidy internal SVG builder (element/text helpers, linear + \"nice\" scales, color interpolation,\npalettes) is deliberately dependency-free and framework-agnostic. It may later **graduate to a shared\n`@leumas` util**; until then it stays self-contained here per the pack contract (no cross-pack\nimports).\n\n## Notes\n\n- **Pure & deterministic** — no randomness, no clock, no I/O. Same input → same SVG.\n- All user text is XML-escaped; output is a JSON-serializable `{ svg }`.\n- Sane defaults: a bare `{ data }` call renders a themed chart; `options` only refine it.\n",
  "source": {
    "path": "shared/engines/adapters/domain/chart/README.md",
    "blobSha": "",
    "commit": "",
    "committedAt": "",
    "provenance": "no-git",
    "bytes": 5077,
    "hash": "ae7d93925a28475825c982ea4ad45bccaf7b89a5"
  },
  "urls": {
    "html": "/p/adapters/domain/chart",
    "json": "/docs/adapters/domain/chart.json",
    "md": "/docs/adapters/domain/chart.md"
  },
  "links": {
    "composes": [],
    "usedBy": [],
    "product": [],
    "howTo": [],
    "skills": []
  }
}
