{"_id":"@aeriz/chart","_rev":"2-ff8b5c376d47c76f7dee0267016278f6","name":"@aeriz/chart","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@aeriz/chart","version":"1.0.0","keywords":["chart","charts","charting","canvas","visualization","dataviz","graph","plot","bar-chart","line-chart","area-chart","scatter-chart","bubble-chart","pie-chart","donut-chart","radar-chart","polar-chart","gauge-chart","heatmap","boxplot","funnel-chart","treemap","sparkline","realtime-chart","waterfall-chart","composite-chart","zero-dependencies","lightweight"],"author":{"name":"aeriz"},"license":"Apache-2.0","_id":"@aeriz/chart@1.0.0","maintainers":[{"name":"aeriz","email":"shinsungj@gmail.com"}],"homepage":"https://www.aeriz.dev","bugs":{"url":"https://github.com/code-repositories/aeriz/issues"},"dist":{"shasum":"6952b9826d62f80bea86b3add3d29a0754e5ac36","tarball":"https://registry.npmjs.org/@aeriz/chart/-/chart-1.0.0.tgz","fileCount":16,"integrity":"sha512-jVP8FH3da8Gf7/c8twU9ewjn1BRQ+FGTt2ffNpOASYQxfY51nc6kWLPJ/Im7XGVaEm1lqKt69QgpZjuPwZxwpA==","signatures":[{"sig":"MEUCIA2zUjE3uMTOmhvJbHqE3cpJK0RcMx9la+i1pcVK4nOPAiEA5GSkw3cVbgnLekVbpxm32tb0hVdwVlIkOpZJdOz/boU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":609242},"main":"./dist/aeriz.cjs","type":"module","types":"./src/index.d.ts","unpkg":"./dist/aeriz.min.js","module":"./dist/aeriz.esm.js","browser":"./dist/aeriz.min.js","engines":{"node":">=14"},"exports":{".":{"types":"./src/index.d.ts","import":{"default":"./dist/aeriz.esm.js"},"browser":"./dist/aeriz.min.js","default":"./dist/aeriz.esm.js","require":{"default":"./dist/aeriz.cjs"}},"./min":{"types":"./src/index.d.ts","import":"./dist/aeriz.esm.min.js","browser":"./dist/aeriz.min.js","default":"./dist/aeriz.esm.min.js","require":"./dist/aeriz.min.cjs"},"./dist/*":"./dist/*","./package.json":"./package.json"},"gitHead":"d739f78ee5fb60a61fc070925d0b09a4ae44a4ae","scripts":{"test":"node test/verify.mjs && node test/bundle.mjs","build":"node scripts/build.mjs","prepublishOnly":"node scripts/build.mjs"},"_npmUser":{"name":"aeriz","email":"shinsungj@gmail.com"},"jsdelivr":"./dist/aeriz.min.js","repository":{"url":"git+https://github.com/code-repositories/aeriz.git","type":"git"},"_npmVersion":"11.12.1","description":"A focused, fast canvas charting library — 21 chart types, single rendering core, zero dependencies.","directories":{},"sideEffects":false,"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/chart_1.0.0_1777115459427_0.13286568139108046","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@aeriz/chart","version":"1.0.1","description":"A focused, fast canvas charting library — 21 chart types, single rendering core, zero dependencies.","keywords":["chart","charts","charting","canvas","visualization","dataviz","graph","plot","bar-chart","line-chart","area-chart","scatter-chart","bubble-chart","pie-chart","donut-chart","radar-chart","polar-chart","gauge-chart","heatmap","boxplot","funnel-chart","treemap","sparkline","realtime-chart","waterfall-chart","composite-chart","zero-dependencies","lightweight"],"license":"Apache-2.0","author":{"name":"aeriz"},"type":"module","main":"./dist/aeriz.cjs","module":"./dist/aeriz.esm.js","browser":"./dist/aeriz.min.js","types":"./src/index.d.ts","unpkg":"./dist/aeriz.min.js","jsdelivr":"./dist/aeriz.min.js","exports":{".":{"types":"./src/index.d.ts","import":{"default":"./dist/aeriz.esm.js"},"require":{"default":"./dist/aeriz.cjs"},"browser":"./dist/aeriz.min.js","default":"./dist/aeriz.esm.js"},"./min":{"types":"./src/index.d.ts","import":"./dist/aeriz.esm.min.js","require":"./dist/aeriz.min.cjs","browser":"./dist/aeriz.min.js","default":"./dist/aeriz.esm.min.js"},"./dist/*":"./dist/*","./package.json":"./package.json"},"sideEffects":false,"scripts":{"build":"node scripts/build.mjs","prepublishOnly":"node scripts/build.mjs","test":"node test/verify.mjs && node test/bundle.mjs"},"engines":{"node":">=14"},"repository":{"type":"git","url":"git+https://github.com/code-repositories/aeriz.git"},"homepage":"https://www.aeriz.dev","bugs":{"url":"https://github.com/code-repositories/aeriz/issues"},"gitHead":"d739f78ee5fb60a61fc070925d0b09a4ae44a4ae","_id":"@aeriz/chart@1.0.1","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-IQPUl+MpktBknVWaF31wc3+CoF3i/oTG8VFG4gtI4J2nUwoHiIl11T8I3VgDe7kb33ECxNv1k7NkUb7p1eMxpQ==","shasum":"fcae30739e62cf5b8486b6ee31c8ff6557ab9e43","tarball":"https://registry.npmjs.org/@aeriz/chart/-/chart-1.0.1.tgz","fileCount":16,"unpackedSize":609393,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDwWyY9VSDvD7uXq6zKK/jO2KrI+1ReMPMUlp8sHFSYggIgLBw6k0lmv8/cLaomb9jKQ+B+4+ikSfUKUSuttekwpKI="}]},"_npmUser":{"name":"aeriz","email":"shinsungj@gmail.com"},"directories":{},"maintainers":[{"name":"aeriz","email":"shinsungj@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/chart_1.0.1_1777116248898_0.5697371077241284"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-25T11:10:59.291Z","modified":"2026-04-25T11:24:09.163Z","1.0.0":"2026-04-25T11:10:59.600Z","1.0.1":"2026-04-25T11:24:09.043Z"},"bugs":{"url":"https://github.com/code-repositories/aeriz/issues"},"author":{"name":"aeriz"},"license":"Apache-2.0","homepage":"https://www.aeriz.dev","keywords":["chart","charts","charting","canvas","visualization","dataviz","graph","plot","bar-chart","line-chart","area-chart","scatter-chart","bubble-chart","pie-chart","donut-chart","radar-chart","polar-chart","gauge-chart","heatmap","boxplot","funnel-chart","treemap","sparkline","realtime-chart","waterfall-chart","composite-chart","zero-dependencies","lightweight"],"repository":{"type":"git","url":"git+https://github.com/code-repositories/aeriz.git"},"description":"A focused, fast canvas charting library — 21 chart types, single rendering core, zero dependencies.","maintainers":[{"name":"aeriz","email":"shinsungj@gmail.com"}],"readme":"# aeriz\n\nA focused, fast canvas charting library. **21 chart types**, single rendering core, zero dependencies.\n\n[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)\n[![npm](https://img.shields.io/badge/npm-%40aeriz%2Fchart-cb3837.svg)](https://www.npmjs.com/package/@aeriz/chart)\n[![size](https://img.shields.io/badge/min-58_KB-green.svg)](dist/aeriz.min.js)\n\n---\n\n## At a glance\n\n- **21 chart types** — bar, line, area, scatter, pie, radar, gauge, heatmap, treemap, realtime, waterfall, **composite** (mixed bar + line + area + scatter, dual y-axis), and more\n- **~58 KB minified · ~94 KB unminified** · zero dependencies\n- **Live theming** via CSS variables — change colors at runtime, call `invalidate()`, redraws\n- **Pixel-perfect events** — hit testing attached to canvas, no DPR confusion\n- **Realtime streaming** — `RealtimeChart.push()` with rolling window\n- **State overlays** — `setLoading()`, `setEmpty()`, `setError()`, `clearState()`\n- **TypeScript types included** (`src/index.d.ts`)\n\n---\n\n## Install\n\n### CDN\n\n```html\n<!-- ✓ Production — pin a specific version (immutable, longest cache) -->\n<script src=\"https://cdn.jsdelivr.net/npm/@aeriz/chart@1.0.0/dist/aeriz.min.js\"></script>\n\n<!-- Tracks the latest 1.x — auto-receives patches, never major bumps -->\n<script src=\"https://cdn.jsdelivr.net/npm/@aeriz/chart@^1.0.0/dist/aeriz.min.js\"></script>\n\n<!-- Always-newest — convenient for prototyping, NOT for production -->\n<script src=\"https://cdn.jsdelivr.net/npm/@aeriz/chart@latest/dist/aeriz.min.js\"></script>\n\n<!-- unpkg alternative (same files, different CDN) -->\n<script src=\"https://unpkg.com/@aeriz/chart@1.0.0/dist/aeriz.min.js\"></script>\n\n<!-- ES Module — same versioning rules apply -->\n<script type=\"module\">\n  import { BarChart } from 'https://cdn.jsdelivr.net/npm/@aeriz/chart@1.0.0/dist/aeriz.esm.min.js';\n</script>\n```\n\n> **Why pin a version?** Pinned URLs (e.g. `@1.0.0`) are immutable and benefit\n> from a one-year CDN cache. `@latest` redirects on every release and may pull\n> in breaking changes when a new major version ships. Use `@latest` only for\n> quick prototypes; pin a version everywhere else.\n\n### npm / yarn / pnpm\n\n```bash\nnpm install @aeriz/chart\nyarn add @aeriz/chart\npnpm add @aeriz/chart\n```\n\n```js\nimport { BarChart, CompositeChart, math, PALETTE } from '@aeriz/chart';\n// or, in CommonJS:\nconst Aeriz = require('@aeriz/chart');\n// or, the minified build (smaller install footprint at runtime):\nimport * as Aeriz from '@aeriz/chart/min';\n```\n\n---\n\n## Quick start\n\n```html\n<div id=\"chart\" style=\"height:320px\"></div>\n<script src=\"https://cdn.jsdelivr.net/npm/@aeriz/chart@1.0.0/dist/aeriz.min.js\"></script>\n<script>\n  const chart = new Aeriz.BarChart('#chart', {\n    data: [\n      { label: 'Jan', value: 64 },\n      { label: 'Feb', value: 42 },\n      { label: 'Mar', value: 78 },\n    ],\n    yTickFormat: v => v + 'k',\n    onClick: hit => hit && console.log(hit),\n  });\n</script>\n```\n\n---\n\n## Chart types\n\nAll 21 types share the same lifecycle (`new` → `setData` → `destroy`) and the same state overlays.\n\n| Chart        | Class                | Notes                                              |\n| ------------ | -------------------- | -------------------------------------------------- |\n| Bar          | `BarChart`           | Vertical, supports negative values                 |\n| H-Bar        | `HBarChart`          | Horizontal                                         |\n| Line         | `LineChart`          | smooth · linear · step · log · time · auto-decimation |\n| Area         | `AreaChart`          | Single + stacked                                   |\n| Stacked Bar  | `StackedBarChart`    |                                                    |\n| Grouped Bar  | `GroupedBarChart`    | Clustered                                          |\n| Multi-Line   | `MultiLineChart`     | Shared crosshair tooltip                           |\n| Scatter      | `ScatterChart`       | Grouped, batched rendering                         |\n| Bubble       | `BubbleChart`        | Scatter with z → radius                            |\n| Pie          | `PieChart`           |                                                    |\n| Donut        | `PieChart` + `innerRadius` | Hover-aware center label                     |\n| Radar        | `RadarChart`         | Multi-series, multi-axis                           |\n| Polar        | `PolarChart`         | Radial bars                                        |\n| Gauge        | `GaugeChart`         | Animated `setValue()`                              |\n| Heatmap      | `HeatmapChart`       | Color interpolation                                |\n| Boxplot      | `BoxplotChart`       | IQR + outliers                                     |\n| Funnel       | `FunnelChart`        | Conversion stages                                  |\n| Treemap      | `TreemapChart`       | Squarified layout                                  |\n| Sparkline    | `Sparkline`          | Mini, no axes                                      |\n| Realtime     | `RealtimeChart`      | `push()` streaming, rolling window                 |\n| Waterfall    | `WaterfallChart`     | Cumulative + connector lines                       |\n| **Composite**| `CompositeChart`     | **Mixed bar + line + area + scatter, dual y-axis** |\n\n---\n\n## Lifecycle\n\n```js\nconst chart = new Aeriz.BarChart('#card', { /* options */ });\n\nchart.setData(newData);     // animated transition\nchart.setLoading('Fetching…');\nchart.setEmpty('No data');\nchart.setError('Network error');\nchart.clearState();         // restore prior render\nchart.invalidate();         // re-resolve theme + redraw\nchart.destroy();            // remove canvas, observers, listeners\n```\n\nMethods other than `invalidate()` and `destroy()` return `this` for chaining.\n\n### Type-specific methods\n\n```js\ngauge.setValue(82);                  // GaugeChart — animated needle\nrealtime.push([cpu, mem]);           // RealtimeChart — append a sample\nrealtime.push(value);                // single-series shortcut\nrealtime.clear();                    // empty the rolling window\n```\n\n---\n\n## Composite (mixed) chart\n\nWhat other libraries call \"complex chart configuration\" — here in one call:\n\n```js\nnew Aeriz.CompositeChart('#card', {\n  categories: ['Jan', 'Feb', 'Mar'],\n  layers: [\n    { type: 'bar',     name: 'Revenue',  values: [100, 130, 90] },\n    { type: 'area',    name: 'Forecast', values: [90, 120, 100] },\n    { type: 'line',    name: 'Margin %', values: [22, 28, 18], axis: 'right' },\n    { type: 'scatter', name: 'Anomaly',  values: [{ x: 1, y: 35 }] },\n  ],\n  yLeftTickFormat:  v => '$' + v + 'k',\n  yRightTickFormat: v => v + '%',\n});\n```\n\n---\n\n## Theming via CSS variables\n\nSet any of the tokens below on `:root`, on the chart container, or on any\nancestor element. Then call `chart.invalidate()` and the chart re-resolves\nits theme and redraws.\n\n```css\n:root {\n  --aeriz-bg:           #0a0e14;\n  --aeriz-surface:      transparent;\n  --aeriz-text:         #e7eef5;\n  --aeriz-muted:        #6a7a8a;\n  --aeriz-grid:         rgba(100, 200, 255, 0.08);\n  --aeriz-axis:         rgba(100, 200, 255, 0.25);\n  --aeriz-accent:       #64c8ff;\n\n  --aeriz-color-1:      #64c8ff;\n  --aeriz-color-2:      #10b981;\n  /* … --aeriz-color-12 */\n\n  --aeriz-font:         ui-monospace, SFMono-Regular, Menlo, monospace;\n  --aeriz-font-size:    13px;\n  --aeriz-line-width:   2;\n  --aeriz-point-radius: 3;\n  --aeriz-bar-radius:   3;\n\n  --aeriz-tooltip-bg:   rgba(0, 0, 0, 0.92);\n  --aeriz-tooltip-fg:   #fff;\n}\n```\n\nThen in JS:\n\n```js\ndocument.documentElement.style.setProperty('--aeriz-accent', '#ff6b9d');\nchart.invalidate();\n```\n\n---\n\n## Realtime streaming\n\n```js\nconst rt = new Aeriz.RealtimeChart('#rt', {\n  series: [{ name: 'CPU' }, { name: 'Memory' }],\n  windowSize: 100,\n});\n\nsetInterval(() => {\n  rt.push([Math.random() * 100, Math.random() * 100]);\n}, 100);\n```\n\n`push()` accepts a single number (one-series charts) or an array aligned\nwith `series`. Older samples beyond `windowSize` are discarded automatically.\n\n---\n\n## State overlays\n\n```js\nchart.setLoading('Fetching…');   // shows a spinner overlay\nchart.setEmpty('No data');       // empty state\nchart.setError('Network error'); // error state\nchart.clearState();              // dismiss overlay, resume rendering\n```\n\nOverlays are non-destructive — `clearState()` restores whatever was\nrendered before.\n\n---\n\n## Framework usage\n\nThe same constructor signature works in every framework. The patterns below\nare the ones the docs site demonstrates per chart type.\n\n<details>\n<summary><strong>React</strong></summary>\n\n```jsx\nimport { useEffect, useRef } from 'react';\nimport * as Aeriz from '@aeriz/chart';\n\nexport default function BarChartDemo() {\n  const ref = useRef(null);\n  useEffect(() => {\n    const chart = new Aeriz.BarChart(ref.current, {\n      data: [{ label: 'A', value: 5 }, { label: 'B', value: 9 }],\n    });\n    return () => chart.destroy();\n  }, []);\n  return <div ref={ref} style={{ width: '100%', height: 320 }} />;\n}\n```\n</details>\n\n<details>\n<summary><strong>Vue 3</strong></summary>\n\n```vue\n<script setup>\nimport { onMounted, onBeforeUnmount, ref } from 'vue';\nimport * as Aeriz from '@aeriz/chart';\n\nconst el = ref(null);\nlet chart = null;\nonMounted(() => {\n  chart = new Aeriz.BarChart(el.value, {\n    data: [{ label: 'A', value: 5 }, { label: 'B', value: 9 }],\n  });\n});\nonBeforeUnmount(() => chart && chart.destroy());\n</script>\n\n<template>\n  <div ref=\"el\" style=\"width:100%;height:320px\"></div>\n</template>\n```\n</details>\n\n<details>\n<summary><strong>Svelte</strong></summary>\n\n```svelte\n<script>\n  import { onMount } from 'svelte';\n  import * as Aeriz from '@aeriz/chart';\n\n  let el;\n  onMount(() => {\n    const chart = new Aeriz.BarChart(el, {\n      data: [{ label: 'A', value: 5 }, { label: 'B', value: 9 }],\n    });\n    return () => chart.destroy();\n  });\n</script>\n\n<div bind:this={el} style=\"width:100%;height:320px\"></div>\n```\n</details>\n\n<details>\n<summary><strong>jQuery</strong></summary>\n\n```js\n$(function () {\n  const chart = new Aeriz.BarChart($('#bar')[0], {\n    data: [{ label: 'A', value: 5 }, { label: 'B', value: 9 }],\n  });\n});\n```\n</details>\n\n<details>\n<summary><strong>ExtJS</strong></summary>\n\n```js\nExt.create('Ext.Component', {\n  renderTo: Ext.getBody(),\n  width: '100%',\n  height: 320,\n  autoEl: { tag: 'div' },\n  listeners: {\n    afterrender(cmp) {\n      cmp.aerizChart = new Aeriz.BarChart(cmp.getEl().dom, {\n        data: [{ label: 'A', value: 5 }, { label: 'B', value: 9 }],\n      });\n    },\n    beforedestroy(cmp) {\n      cmp.aerizChart && cmp.aerizChart.destroy();\n    },\n  },\n});\n```\n</details>\n\n---\n\n## TypeScript\n\nTypes ship in the package — no `@types/aeriz__chart` needed.\n\n```ts\nimport {\n  BarChart,\n  CompositeChart,\n  GaugeChart,\n  RealtimeChart,\n  math,\n  PALETTE,\n} from '@aeriz/chart';\n\nconst bar = new BarChart('#x', {\n  data: [{ label: 'A', value: 5 }],\n  onClick: hit => console.log(hit),\n});\n\nconst gauge = new GaugeChart(document.body, { value: 50, max: 100 });\ngauge.setValue(82);\n\nconst ticks: number[] = math.niceTicks(0, 100, 5);\n```\n\nDiscriminated unions cover composite layers — `type: 'bar'` requires\n`values: number[]` while `type: 'scatter'` requires `values: { x, y }[]`.\n\n---\n\n## API reference\n\n### `Chart` (base class)\n\n| Method                       | Returns | Description                                   |\n| ---------------------------- | ------- | --------------------------------------------- |\n| `new Chart(container, opts)` | —       | `container`: CSS selector or `HTMLElement`    |\n| `setData(data)`              | `this`  | Replace data with an animated transition      |\n| `setLoading(msg?)`           | `this`  | Show loading overlay                          |\n| `setEmpty(msg?)`             | `this`  | Show empty-state overlay                      |\n| `setError(msg?)`             | `this`  | Show error overlay                            |\n| `clearState()`               | `this`  | Dismiss any overlay                           |\n| `invalidate()`               | `void`  | Re-resolve theme + palette and redraw         |\n| `destroy()`                  | `void`  | Tear down listeners, observers, canvas        |\n\n### Common options\n\nAccepted by every chart that has them:\n\n| Option           | Type                       | Description                                  |\n| ---------------- | -------------------------- | -------------------------------------------- |\n| `palette`        | `string[]`                 | Override the default palette                 |\n| `dataLabels`     | `boolean`                  | Render value labels on bars / points         |\n| `onClick`        | `(hit, point, chart) => void` | Click handler                             |\n| `xTickFormat`    | `(value, index) => string` | Format x-axis ticks                          |\n| `yTickFormat`    | `(value) => string`        | Format y-axis ticks                          |\n\n### Math helpers\n\n```js\nimport { math, PALETTE } from '@aeriz/chart';\n\nmath.clamp(15, 0, 10);          // 10\nmath.lerp(0, 1, 0.5);           // 0.5\nmath.niceTicks(0, 100, 5);      // [0, 20, 40, 60, 80, 100]\nmath.niceDomain(3, 97, 5);      // [0, 100]\nmath.colorMix('#000', '#fff', 0.5);\nPALETTE;                        // 8-color qualitative palette\n```\n\nFull list: `TAU`, `clamp`, `lerp`, `extent`, `niceTicks`, `niceDomain`,\n`timeNiceTicks`, `timeFormat`, `minMaxDecimate`, `shouldDecimate`,\n`bezierControlPoints`, `springStep`, `colorParse`, `colorAlpha`,\n`colorMix`, `PALETTE`.\n\n---\n\n## Files\n\n```\nsrc/\n  index.js          # public entry — re-exports\n  index.d.ts        # TypeScript definitions\n  math.js           # scales, ticks, color, decimation\n  engine.js         # canvas primitives + DPR\n  base.js           # Chart base class\n  charts.js         # 20 chart types\n  composite.js      # mixed chart\n\ndist/\n  aeriz.js          # IIFE — window.Aeriz (~94 KB)\n  aeriz.min.js      # IIFE minified (~58 KB) — CDN default\n  aeriz.esm.js      # ES module\n  aeriz.esm.min.js  # ES module minified\n  aeriz.cjs         # CommonJS — for `require('@aeriz/chart')`\n  aeriz.min.cjs     # CommonJS minified\n\nscripts/\n  build.mjs         # build all 6 dist files\ntest/\n  verify.mjs        # 53 unit + integration tests\n  bundle.mjs        # IIFE bundle integrity\n```\n\nTotal source: ~2,600 lines for 21 chart types.\n\n---\n\n## Build\n\nZero dependencies. Just run:\n\n```bash\nnode scripts/build.mjs\n```\n\nProduces all 6 files in `dist/`.\n\n---\n\n## Test\n\n```bash\nnpm test\n```\n\n53 tests covering:\n\n- Engine DPR + dimensions\n- Math primitives (`clamp`, `lerp`, ticks, color ops)\n- Pixel-perfect mouse coordinates\n- `invalidate()` theme reactivity (palette + gradient cache)\n- All 21 chart types instantiate + render\n- State overlays (`loading`/`empty`/`error`/`clear`)\n- Tooltip lifecycle, click handlers, animation completion\n- Destroy cleanup (no leaked listeners or DOM)\n\n---\n\n## License\n\n[Apache License 2.0](LICENSE) — Copyright © 2026\n[code-repositories](https://github.com/code-repositories).\n","readmeFilename":"README.md"}