apexcharts-skill 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/SKILL.md +56 -12
- package/package.json +1 -1
- package/references/bar-charts.md +24 -0
- package/references/cartesian-charts.md +1 -1
- package/references/circular-charts.md +180 -1
- package/references/financial-charts.md +111 -5
- package/references/grid-charts.md +93 -0
- package/references/tree-shaking.md +8 -1
- package/references/v6-features.md +114 -3
package/README.md
CHANGED
|
@@ -20,10 +20,10 @@ This skill targets **ApexCharts v6** (backward compatible with v5 configs).
|
|
|
20
20
|
|
|
21
21
|
### Coverage
|
|
22
22
|
|
|
23
|
-
- **
|
|
23
|
+
- **24 chart types**: line, area, bar, pie, donut, radialBar, scatter, bubble, heatmap, candlestick, boxPlot, violin, histogram, radar, polarArea, rangeBar, rangeArea, treemap, funnel, pyramid, gauge, sunburst, unit, waffle
|
|
24
24
|
- **Correct data formats** for every chart type
|
|
25
25
|
- **Common pitfalls** with wrong/correct code examples
|
|
26
|
-
- **v6 feature platform**: plugins (Weave), canvas renderer (Strata), custom series (Marks), undo/redo (Rewind), shareable views (Perspectives), themes (Facet), easing (Cadence), crossfilter (Link), annotation authoring (Ink), measure ruler, context menu, storyboard, streaming, drilldown
|
|
26
|
+
- **v6 feature platform**: plugins (Weave), canvas renderer (Strata), custom series (Marks), undo/redo (Rewind), shareable views (Perspectives), themes (Facet), easing (Cadence), crossfilter (Link), annotation authoring (Ink), measure ruler, context menu, storyboard, streaming, drilldown, raw-sample statistics (Stats), unit-chart shape kit (`apexcharts/unit-shapes`)
|
|
27
27
|
- **Tree-shaking** and bundle optimization patterns
|
|
28
28
|
- **SSR** (server-side rendering) and hydration
|
|
29
29
|
- **Framework integration**: React, Vue 3, Angular
|
|
@@ -80,8 +80,8 @@ const barCharts = await readFile(referencePath('bar-charts.md'), 'utf8');
|
|
|
80
80
|
├── references/
|
|
81
81
|
│ ├── cartesian-charts.md # line, area, scatter, bubble, rangeArea
|
|
82
82
|
│ ├── bar-charts.md # bar, column, rangeBar, timeline/Gantt, funnel, pyramid
|
|
83
|
-
│ ├── financial-charts.md # candlestick, boxPlot, violin
|
|
84
|
-
│ ├── circular-charts.md # pie, donut, polarArea, radialBar, gauge
|
|
83
|
+
│ ├── financial-charts.md # candlestick, boxPlot, violin, histogram
|
|
84
|
+
│ ├── circular-charts.md # pie, donut, polarArea, radialBar, gauge, sunburst, unit, waffle
|
|
85
85
|
│ ├── grid-charts.md # heatmap, treemap
|
|
86
86
|
│ ├── radar-charts.md # radar
|
|
87
87
|
│ ├── v6-features.md # v6 feature platform (plugins, canvas, undo/redo, themes, ...)
|
package/SKILL.md
CHANGED
|
@@ -4,7 +4,8 @@ description: >
|
|
|
4
4
|
AI skill for building ApexCharts.js charts and data visualizations (targets v6).
|
|
5
5
|
Use when the user asks to create, configure, or troubleshoot any chart using ApexCharts
|
|
6
6
|
(line, area, bar, pie, donut, radialBar, scatter, bubble, heatmap, candlestick, boxPlot,
|
|
7
|
-
violin, radar, polarArea, rangeBar, rangeArea, treemap, funnel, pyramid, gauge
|
|
7
|
+
violin, histogram, radar, polarArea, rangeBar, rangeArea, treemap, funnel, pyramid, gauge,
|
|
8
|
+
sunburst, unit, waffle). Covers
|
|
8
9
|
correct data formats, lifecycle, formatters, tree-shaking, SSR, and the v6 feature
|
|
9
10
|
platform (plugins, canvas renderer, custom series, undo/redo, shareable views, themes,
|
|
10
11
|
crossfilter, annotation authoring, storyboard, streaming, drilldown). In React /
|
|
@@ -12,8 +13,8 @@ description: >
|
|
|
12
13
|
(`react-apexcharts`, `vue3-apexcharts`, `ng-apexcharts`) over the core API.
|
|
13
14
|
metadata:
|
|
14
15
|
author: ApexCharts
|
|
15
|
-
version: "2.0
|
|
16
|
-
library_version: "6.
|
|
16
|
+
version: "2.2.0"
|
|
17
|
+
library_version: "6.10.0"
|
|
17
18
|
category: data-visualization
|
|
18
19
|
tags: [charts, visualization, javascript, typescript, svg, apexcharts]
|
|
19
20
|
docs: https://apexcharts.com/docs/
|
|
@@ -31,6 +32,8 @@ metadata:
|
|
|
31
32
|
> Wrappers handle `destroy()` automatically on unmount, accept reactive props, and forward events as idiomatic framework events. Use the core API directly only when no framework is detected, or when the user explicitly asks for vanilla. See `references/framework-wrappers.md`.
|
|
32
33
|
|
|
33
34
|
> **Targets ApexCharts v6.** v6 is backward compatible: existing v5 configs keep working unchanged. Everything new (the plugin platform, canvas renderer, custom series, undo/redo, shareable views, themes, crossfilter, annotation authoring, storyboard, streaming, drilldown) is opt-in and tree-shakeable. Two behaviors changed *on by default* (both respect `prefers-reduced-motion`): (1) data updates that add/remove points now animate coherently, and (2) mobile pinch-zoom / two-finger pan gestures are enabled. See `references/v6-features.md` for the full v6 surface.
|
|
35
|
+
>
|
|
36
|
+
> **Premium features and licensing (6.5.0+).** Seven of the v6 features are premium: `storyboard`, `link` (crossfilter / linked views), `ink` (annotation authoring), `measure`, `context-menu`, `perspectives` (shareable views), and `history` (undo/redo). The `unit` / `waffle` chart type is also premium (6.6.0+). These still function fully, but render an `APEXCHARTS` trial watermark until an entitled license is set via `ApexCharts.setLicense(key)` (static) or per-chart `chart.license`. As of 6.7.0 they require a `premium` or `enterprise` plan; a `pro` key or the free tier keeps the watermark. Every other chart type and free module is never gated. See the Licensing section in `references/v6-features.md`.
|
|
34
37
|
|
|
35
38
|
## 1. Critical Rules
|
|
36
39
|
|
|
@@ -47,8 +50,9 @@ metadata:
|
|
|
47
50
|
11. **Color hex values must include the `#` prefix** (e.g., `'#FF5733'`, not `'FF5733'`).
|
|
48
51
|
12. **Tree-shaking**: importing `apexcharts/core` gives you a bare class — you must also import chart-type entries and feature entries separately.
|
|
49
52
|
13. **v6 first-class aliases**: `funnel` and `pyramid` render through the bar engine; `gauge` renders through radialBar. Use them as `chart.type` directly (no `plotOptions.bar.isFunnel` needed). They are covered by the `apexcharts/bar` and `apexcharts/radialBar` tree-shaking entries respectively.
|
|
50
|
-
14. **`violin` (v6, statistical)** uses a per-point density profile: `data: [{ x, y: { density: [[value, weight], ...], points?: [number] } }]`, not a plain number.
|
|
53
|
+
14. **`violin` (v6, statistical)** uses a per-point density profile: `data: [{ x, y: { density: [[value, weight], ...], points?: [number] } }]`, not a plain number. Since v6.9 a datum may instead supply only raw observations (`points: [number]`, no `y`) and the library derives the density via KDE (needs `apexcharts/features/stats` when tree-shaking).
|
|
51
54
|
15. **`render()` is idempotent (v6)**: calling `render()` twice on the same instance returns the same promise instead of building a duplicate chart. You still must `destroy()` before creating a *new* instance on the same element.
|
|
55
|
+
16. **`histogram` (v6.9)** series carry **raw observations** (one number per event), not pre-aggregated counts; the chart chooses bin edges and counts them. Binning ships behind the stats feature: use the `apexcharts/histogram` entry, or `import 'apexcharts/features/stats'` alongside `apexcharts/bar` (the full `apexcharts` bundle already includes it).
|
|
52
56
|
|
|
53
57
|
---
|
|
54
58
|
|
|
@@ -68,22 +72,23 @@ This is the most critical reference. Using the wrong data format is the #1 cause
|
|
|
68
72
|
| Range Area | `'rangeArea'` | `[{ name, data: [{ x, y: [low, high] }] }]` | `series: [{ name: 'Temp', data: [{ x: 'Jan', y: [5, 15] }] }]` |
|
|
69
73
|
| Range Bar | `'rangeBar'` | `[{ name, data: [{ x, y: [start, end] }] }]` — for timeline/Gantt, use timestamps | `series: [{ name: 'Tasks', data: [{ x: 'Design', y: [1, 5] }] }]` |
|
|
70
74
|
| Candlestick | `'candlestick'` | `[{ data: [{ x, y: [O, H, L, C] }] }]` — array of 4: Open, High, Low, Close | `series: [{ data: [{ x: new Date('2024-01-01'), y: [51, 56, 48, 53] }] }]` |
|
|
71
|
-
| Box Plot | `'boxPlot'` | `[{ data: [{ x, y: [min, Q1, median, Q3, max] }] }]` — array of 5 | `series: [{ data: [{ x: 'Group A', y: [10, 20, 30, 40, 50] }] }]` |
|
|
72
|
-
| Violin *(v6)* | `'violin'` | `[{ name, data: [{ x, y: { density: [[value, weight], ...], points?: [number] } }] }]` | `series: [{ name: 'Sessions', data: [{ x: 'A', y: { density: [[20, 0.1], [30, 0.2]], points: [21, 29] } }] }]` |
|
|
75
|
+
| Box Plot | `'boxPlot'` | `[{ data: [{ x, y: [min, Q1, median, Q3, max] }] }]` — array of 5. *(v6.9)* Or supply the raw sample instead: `[{ data: [{ x, points: [number] }] }]` and the quartiles are computed (R type 7; needs the stats feature). | `series: [{ data: [{ x: 'Group A', y: [10, 20, 30, 40, 50] }] }]` |
|
|
76
|
+
| Violin *(v6)* | `'violin'` | `[{ name, data: [{ x, y: { density: [[value, weight], ...], points?: [number] } }] }]`. *(v6.9)* Or supply the raw sample instead: `[{ name, data: [{ x, points: [number] }] }]` and the density is derived via KDE (needs the stats feature). | `series: [{ name: 'Sessions', data: [{ x: 'A', y: { density: [[20, 0.1], [30, 0.2]], points: [21, 29] } }] }]` |
|
|
77
|
+
| Histogram *(v6.9)* | `'histogram'` | `[{ name, data: [number] }]`: **raw observations**, one number per event, NOT pre-binned counts. The chart bins them (needs the stats feature). | `series: [{ name: 'Latency', data: [102, 87, 143, 91] }]` |
|
|
73
78
|
| Heatmap | `'heatmap'` | `[{ name, data: [{ x, y: number }] }]` — y is the intensity value | `series: [{ name: 'Mon', data: [{ x: '10am', y: 45 }] }]` |
|
|
74
|
-
| Treemap | `'treemap'` | `[{ data: [{ x, y: number }] }]` — y is the area/value | `series: [{ data: [{ x: 'Item A', y: 100 }, { x: 'Item B', y: 60 }] }]` |
|
|
79
|
+
| Treemap | `'treemap'` | `[{ data: [{ x, y: number }] }]` — y is the area/value. *(v6.9)* A datum may carry `children` to any depth for a nested treemap (see `references/grid-charts.md`). | `series: [{ data: [{ x: 'Item A', y: 100 }, { x: 'Item B', y: 60 }] }]` |
|
|
75
80
|
| Radar | `'radar'` | `[{ name, data: [number] }]` + `xaxis: { categories: [...] }` | `series: [{ name: 'Skill', data: [80, 50, 30, 40, 100] }]` |
|
|
76
81
|
| Funnel *(v6)* | `'funnel'` | `[{ name, data: [number] }]` + `xaxis: { categories: [...] }`. Order values **largest→smallest**. | `series: [{ data: [1380, 990, 548, 200] }]` |
|
|
77
82
|
| Pyramid *(v6)* | `'pyramid'` | Same as funnel; order values **smallest→largest** (wide base at bottom). | `series: [{ data: [200, 548, 990, 1380] }]` |
|
|
78
83
|
|
|
79
|
-
### Non-Axis Charts (pie, donut, radialBar, polarArea, gauge)
|
|
84
|
+
### Non-Axis Charts (pie, donut, radialBar, polarArea, gauge, unit, waffle)
|
|
80
85
|
|
|
81
86
|
These use a **flat number array** for `series`, NOT the object format:
|
|
82
87
|
|
|
83
88
|
```js
|
|
84
89
|
// CORRECT — flat number array + labels
|
|
85
90
|
{
|
|
86
|
-
chart: { type: 'pie' }, // or 'donut', 'polarArea', 'radialBar', 'gauge'
|
|
91
|
+
chart: { type: 'pie' }, // or 'donut', 'polarArea', 'radialBar', 'gauge', 'unit', 'waffle'
|
|
87
92
|
series: [44, 55, 13, 43, 22],
|
|
88
93
|
labels: ['Team A', 'Team B', 'Team C', 'Team D', 'Team E']
|
|
89
94
|
}
|
|
@@ -91,6 +96,29 @@ These use a **flat number array** for `series`, NOT the object format:
|
|
|
91
96
|
|
|
92
97
|
**Gauge *(v6)*** is a single-value radialBar alias: `series: [72]`, `labels: ['Progress']`. Configure the arc/needle, colored bands, ticks, and `min`/`max` domain through `plotOptions.radialBar` (see `references/circular-charts.md`).
|
|
93
98
|
|
|
99
|
+
**Unit / Waffle *(v6.6, premium)*** render one mark per unit of value (dot clusters, pictograms, waffles, beeswarms). Same flat-array + `labels` shape as pie; layout is chosen through `plotOptions.unit.layout`. A per-mark object form (`series: [{ name, data: [{ value, x, z, name, fillColor, id }] }]`) gives each mark its own color, position, size, and tooltip. `waffle` is a preset alias of `unit` (grid layout). Both render an `APEXCHARTS` watermark until an entitled license is set. See `references/circular-charts.md`.
|
|
100
|
+
|
|
101
|
+
### Hierarchical Charts (sunburst)
|
|
102
|
+
|
|
103
|
+
**Sunburst *(v6.7, free)*** draws tree-structured data as concentric rings (a nested pie / donut). It uses the axis-style `[{ data: [...] }]` wrapper, but each datum is an `{ x, y, children }` node nested to any depth:
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
{
|
|
107
|
+
chart: { type: 'sunburst' },
|
|
108
|
+
series: [{
|
|
109
|
+
data: [
|
|
110
|
+
{ x: 'Mobile', y: 55, children: [
|
|
111
|
+
{ x: 'iOS', y: 30, children: [{ x: 'iOS 17', y: 18 }, { x: 'iOS 16', y: 9 }] },
|
|
112
|
+
{ x: 'Android', y: 23 }
|
|
113
|
+
] },
|
|
114
|
+
{ x: 'Desktop', y: 33, children: [{ x: 'Windows', y: 20 }, { x: 'macOS', y: 10 }] }
|
|
115
|
+
]
|
|
116
|
+
}]
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Configure the centre hole, corner rounding, and inter-arc gap through `plotOptions.sunburst` (see `references/circular-charts.md`).
|
|
121
|
+
|
|
94
122
|
---
|
|
95
123
|
|
|
96
124
|
## 3. Package / Module Map
|
|
@@ -114,6 +142,7 @@ import ApexCharts from 'apexcharts/rangeBar' # same as /bar
|
|
|
114
142
|
import ApexCharts from 'apexcharts/candlestick' # candlestick, boxPlot
|
|
115
143
|
import ApexCharts from 'apexcharts/boxPlot' # same as /candlestick
|
|
116
144
|
import ApexCharts from 'apexcharts/violin' # violin (v6)
|
|
145
|
+
import ApexCharts from 'apexcharts/histogram' # histogram (v6.9): bar engine + the stats feature
|
|
117
146
|
import ApexCharts from 'apexcharts/pie' # pie, donut, polarArea
|
|
118
147
|
import ApexCharts from 'apexcharts/donut' # same as /pie
|
|
119
148
|
import ApexCharts from 'apexcharts/polarArea' # same as /pie
|
|
@@ -121,14 +150,20 @@ import ApexCharts from 'apexcharts/radialBar' # radialBar + gauge (v6)
|
|
|
121
150
|
import ApexCharts from 'apexcharts/radar' # radar only
|
|
122
151
|
import ApexCharts from 'apexcharts/heatmap' # heatmap only
|
|
123
152
|
import ApexCharts from 'apexcharts/treemap' # treemap only
|
|
153
|
+
import ApexCharts from 'apexcharts/sunburst' # sunburst (v6.7, hierarchical)
|
|
154
|
+
import ApexCharts from 'apexcharts/unit' # unit + waffle (v6.6, premium)
|
|
124
155
|
# funnel + pyramid (v6) render through the bar engine; use apexcharts/bar
|
|
125
156
|
|
|
157
|
+
# Unit-chart shape kit (v6.10): named exports, tree-shaken per shape (~4 KB gzipped each)
|
|
158
|
+
import { heart, outlined, glyphs, preview } from 'apexcharts/unit-shapes'
|
|
159
|
+
|
|
126
160
|
# Optional features (side-effect imports — just import, no default export needed)
|
|
127
161
|
import 'apexcharts/features/exports' # PNG/SVG/CSV export methods
|
|
128
162
|
import 'apexcharts/features/legend' # Interactive legend component
|
|
129
163
|
import 'apexcharts/features/toolbar' # Toolbar (zoom, pan, download buttons)
|
|
130
164
|
import 'apexcharts/features/annotations' # X/Y/point/text/image annotations
|
|
131
165
|
import 'apexcharts/features/keyboard' # Keyboard navigation (accessibility)
|
|
166
|
+
import 'apexcharts/features/stats' # Statistics (v6.9): histogram binning, boxPlot/violin raw samples, rowSeries()
|
|
132
167
|
# v6 feature platform (all opt-in, all tree-shakeable)
|
|
133
168
|
import 'apexcharts/features/morph' # Animated chart-type morphs
|
|
134
169
|
import 'apexcharts/features/drilldown' # Hierarchical drill-down
|
|
@@ -152,6 +187,8 @@ import ApexCharts from 'apexcharts/client' # Browser: explicit client import for
|
|
|
152
187
|
|
|
153
188
|
**Note:** When using `apexcharts` (full bundle), all chart types and features are included automatically. Tree-shaking entries (`/core`, `/line`, etc.) are for reducing bundle size.
|
|
154
189
|
|
|
190
|
+
**Note (v6.9):** ApexCharts is no longer dependency-free: it depends on `apex-commons` at runtime. npm resolves it automatically and the browser (script-tag) bundles inline it, so no action is needed; it only matters for tooling that assumed zero dependencies.
|
|
191
|
+
|
|
155
192
|
---
|
|
156
193
|
|
|
157
194
|
## 4. Core Lifecycle Pattern
|
|
@@ -215,6 +252,8 @@ chart.destroy()
|
|
|
215
252
|
|
|
216
253
|
**Important:** All formatters must return a `string` (or `number` for `dataLabels.formatter`). Never return `undefined`.
|
|
217
254
|
|
|
255
|
+
**Per-point data label offsets (v6.8):** `dataLabels.offsetX` and `dataLabels.offsetY` accept `number | ((opts) => number)`. The function receives `{ series, seriesIndex, dataPointIndex, w }` (same signature as `dataLabels.style.colors` functions), so colliding labels from two series at the same x can be pushed apart, e.g. `offsetY: ({ seriesIndex }) => (seriesIndex === 0 ? -12 : 12)`. Keep it pure; it may be called more than once per label.
|
|
256
|
+
|
|
218
257
|
---
|
|
219
258
|
|
|
220
259
|
## 6. Pitfalls & Anti-Patterns
|
|
@@ -508,6 +547,7 @@ await chart.updateOptions({ title: { text: 'New Title' } })
|
|
|
508
547
|
| `exportToCSV(options?)` | Trigger CSV download. |
|
|
509
548
|
| `setLocale(localeName)` | Switch locale. |
|
|
510
549
|
| `toggleDataPointSelection(seriesIndex, dataPointIndex?)` | Select/deselect data point. |
|
|
550
|
+
| `rowSeries(opts?)` | *(v6.9)* Returns the raw rows behind this chart's marks as a unit-chart series (one cluster per mark), or `null` when the type has no row source (works for histogram / boxPlot / violin, needs `apexcharts/features/stats`). `opts.maxRows` caps the output (default 3000). |
|
|
511
551
|
| `getState()` | Returns snapshot of chart state. |
|
|
512
552
|
| `addEventListener(name, handler)` | Subscribe to chart event. |
|
|
513
553
|
| `removeEventListener(name, handler)` | Unsubscribe from chart event. |
|
|
@@ -531,6 +571,7 @@ await chart.updateOptions({ title: { text: 'New Title' } })
|
|
|
531
571
|
|---|---|
|
|
532
572
|
| `ApexCharts.exec(chartID, fn, ...args)` | Call method on chart by its `chart.id`. |
|
|
533
573
|
| `ApexCharts.getChartByID(chartID)` | Get chart instance by id. |
|
|
574
|
+
| `ApexCharts.setLicense(key)` | *(v6.5)* Set the license key that clears the premium-feature trial watermark. Static, family-shared, offline, SSR-safe; call before `render()`. Per-chart override is `chart.license`. As of 6.7.0 requires a `premium`/`enterprise` plan. |
|
|
534
575
|
| `ApexCharts.merge(target, source)` | Deep-merge objects. |
|
|
535
576
|
| `ApexCharts.use(typeMap)` | Register chart type constructors (tree-shaking). |
|
|
536
577
|
| `ApexCharts.registerFeatures(featureMap)` | Register optional feature modules. |
|
|
@@ -538,6 +579,7 @@ await chart.updateOptions({ title: { text: 'New Title' } })
|
|
|
538
579
|
| `ApexCharts.registerSeriesType(name, def) / unregisterSeriesType(name)` | *(v6, Marks)* Register a custom series type. |
|
|
539
580
|
| `ApexCharts.registerTheme(name, def) / unregisterTheme(name)` | *(v6, Facet)* Register a named brand theme. |
|
|
540
581
|
| `ApexCharts.registerEasing(name, fn)` | *(v6, Cadence)* Register a custom easing curve. |
|
|
582
|
+
| `ApexCharts.registerUnitLayout(name, fn) / unregisterUnitLayout(name)` | *(v6.9)* Register a named unit-chart layout, referenceable via `plotOptions.unit.positions: '<name>'` with `layout: 'custom'`. |
|
|
541
583
|
| `ApexCharts.crossfilter({ id, records }) / getCrossfilter(id)` | *(v6, Link)* Create / fetch a crossfilter engine. |
|
|
542
584
|
| `ApexCharts.perspectives.fromURL(href)` | *(v6)* Decode a perspective token from a URL. |
|
|
543
585
|
|
|
@@ -595,6 +637,7 @@ await chart.updateOptions({ title: { text: 'New Title' } })
|
|
|
595
637
|
drillDownStart: (info, chart, options) => {},// drilldown
|
|
596
638
|
drillDownEnd: (info, chart, options) => {}, // drilldown
|
|
597
639
|
drillUp: (info, chart, options) => {}, // drilldown
|
|
640
|
+
drillDownError: ({ id, error }, chart, options) => {}, // drilldown (v6.9): async level failed; view unchanged
|
|
598
641
|
}
|
|
599
642
|
}
|
|
600
643
|
}
|
|
@@ -621,7 +664,8 @@ All of the following are new in v6, off by default, and each ships as a `apexcha
|
|
|
621
664
|
| **Context menu** | `apexcharts/features/context-menu` | `chart: { contextMenu: { enabled, items } }` for point-specific right-click actions. |
|
|
622
665
|
| **Storyboard** (scrollytelling) | `apexcharts/features/storyboard` | `chart.storyboard.bind({ beats })` pairs prose sections with saved views. |
|
|
623
666
|
| **Streaming** | core | `chart: { streaming: { enabled, maxPoints } }` for constant-velocity rolling-window scroll. |
|
|
624
|
-
| **Drilldown** | `apexcharts/features/drilldown` | `drilldown: { enabled, series }` + a `drilldown` id on data points; `chart.drillDown()/drillUp()`. |
|
|
667
|
+
| **Drilldown** | `apexcharts/features/drilldown` | `drilldown: { enabled, series }` + a `drilldown` id on data points; `chart.drillDown()/drillUp()`. v6.9 adds line/area support, async levels (`onDrillDown` may return a Promise), a loading overlay, and the `drillDownError` event. |
|
|
668
|
+
| **Stats** | `apexcharts/features/stats` | *(v6.9)* Statistics behind histogram binning, boxPlot/violin raw-sample summaries (R type 7 quartiles, KDE), and `chart.rowSeries()`. The `apexcharts/histogram` entry includes it. |
|
|
625
669
|
|
|
626
670
|
## 10. Reference Routing Table
|
|
627
671
|
|
|
@@ -631,8 +675,8 @@ For detailed chart-family-specific options, data format variants, and full worki
|
|
|
631
675
|
|---|---|
|
|
632
676
|
| Line, Area, Scatter, Bubble, Range Area | `references/cartesian-charts.md` |
|
|
633
677
|
| Bar, Column, Range Bar, Timeline/Gantt, Funnel, Pyramid | `references/bar-charts.md` |
|
|
634
|
-
| Candlestick, Box Plot, Violin | `references/financial-charts.md` |
|
|
635
|
-
| Pie, Donut, Polar Area, Radial Bar, Gauge | `references/circular-charts.md` |
|
|
678
|
+
| Candlestick, Box Plot, Violin, Histogram | `references/financial-charts.md` |
|
|
679
|
+
| Pie, Donut, Polar Area, Radial Bar, Gauge, Sunburst, Unit, Waffle | `references/circular-charts.md` |
|
|
636
680
|
| Heatmap, Treemap | `references/grid-charts.md` |
|
|
637
681
|
| Radar | `references/radar-charts.md` |
|
|
638
682
|
| v6 feature platform (plugins, canvas, undo/redo, themes, crossfilter, storyboard, ...) | `references/v6-features.md` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apexcharts-skill",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "AI coding skill for ApexCharts.js — structured reference docs that help AI assistants (Claude, Cursor, Copilot, etc.) generate correct ApexCharts code.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"apexcharts",
|
package/references/bar-charts.md
CHANGED
|
@@ -19,6 +19,8 @@ import ApexCharts from 'apexcharts/bar'
|
|
|
19
19
|
|
|
20
20
|
**v6 note:** `funnel` and `pyramid` are first-class `chart.type` aliases that render through the bar engine. Use them directly as `chart.type`; you do **not** need `plotOptions.bar.isFunnel`. `plotOptions.funnel` carries the funnel-specific shape options.
|
|
21
21
|
|
|
22
|
+
**Histogram (v6.9):** `chart.type: 'histogram'` also renders through the bar pathway, but its series carry raw observations that the chart bins itself, and the binning needs the stats feature (`apexcharts/histogram` entry, or `apexcharts/features/stats` alongside `apexcharts/bar`). It is documented with the other statistical charts in `references/financial-charts.md`.
|
|
23
|
+
|
|
22
24
|
---
|
|
23
25
|
|
|
24
26
|
## Data Formats
|
|
@@ -213,6 +215,28 @@ plotOptions: {
|
|
|
213
215
|
}
|
|
214
216
|
```
|
|
215
217
|
|
|
218
|
+
### Bar Chart Race (v6.4)
|
|
219
|
+
|
|
220
|
+
A reorder update animates into a bar chart race: when you re-sort the data and update the chart, the bars slide to their new ranks and their category labels ride along automatically (whenever `dynamicAnimation` is on). Two opt-in `dataLabels` flags complete the effect. Both are off by default and apply to **bar / column only**; their speed and easing follow `chart.animations.dynamicAnimation`.
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
const options = {
|
|
224
|
+
chart: {
|
|
225
|
+
type: 'bar',
|
|
226
|
+
animations: { dynamicAnimation: { speed: 800 } },
|
|
227
|
+
},
|
|
228
|
+
plotOptions: { bar: { horizontal: true } },
|
|
229
|
+
dataLabels: {
|
|
230
|
+
enabled: true,
|
|
231
|
+
animate: { enabled: true }, // value labels ride to the new rank instead of snapping
|
|
232
|
+
countUp: { enabled: true }, // and count up/down from the previous value (formatter runs each frame)
|
|
233
|
+
},
|
|
234
|
+
}
|
|
235
|
+
// On each frame, re-sort your data and call updateOptions (or updateSeries) with the
|
|
236
|
+
// new series and categories. Bars, category labels, and value labels animate together.
|
|
237
|
+
// Rotated axis labels ride correctly too.
|
|
238
|
+
```
|
|
239
|
+
|
|
216
240
|
### Goals / Target Markers
|
|
217
241
|
|
|
218
242
|
```js
|
|
@@ -242,6 +242,6 @@ xaxis: {
|
|
|
242
242
|
|
|
243
243
|
1. **Bubble chart without z value** — renders with zero-size bubbles. Always provide `z` in data.
|
|
244
244
|
2. **Using `xaxis.categories` with `{ x, y }` data** — categories are silently ignored when data contains x values. Choose one approach.
|
|
245
|
-
3. **Datetime axis with string dates** — pass timestamps (`new Date(...).getTime()`) or `Date` objects, not raw strings like `'January 2024'`.
|
|
245
|
+
3. **Datetime axis with string dates** — pass timestamps (`new Date(...).getTime()`) or `Date` objects, not raw strings like `'January 2024'`. Since v6.10 a `Date` object `x` is accepted by the types and keeps millisecond resolution (previously milliseconds were truncated, collapsing points within the same second).
|
|
246
246
|
4. **`stroke.curve: 'smooth'` on sparse data** — can produce visual artifacts. Use `'monotoneCubic'` for mathematically smoother interpolation.
|
|
247
247
|
5. **Range Area with single value instead of array** — `y` must be `[low, high]`, not a single number.
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
- **Polar Area** (`'polarArea'`) — Radial segments with equal angles, varying radius
|
|
8
8
|
- **Radial Bar** (`'radialBar'`): Circular progress chart (one or more concentric tracks)
|
|
9
9
|
- **Gauge** (`'gauge'`, **new in v6**): Single-value gauge with arc/needle shapes, colored bands, and ticks
|
|
10
|
+
- **Sunburst** (`'sunburst'`, **new in v6.7, free**): Hierarchical nested pie/donut; concentric rings, one per level
|
|
11
|
+
- **Unit / Waffle** (`'unit'` / `'waffle'`, **new in v6.6, premium**): One mark per unit of value (dot clusters, pictograms, waffles, beeswarms, parliament, custom layouts and the v6.10 shape kit)
|
|
10
12
|
|
|
11
13
|
## Tree-Shakeable Import
|
|
12
14
|
|
|
@@ -18,6 +20,15 @@ import ApexCharts from 'apexcharts/pie'
|
|
|
18
20
|
import ApexCharts from 'apexcharts/radialBar'
|
|
19
21
|
// Registers: radialBar (separate entry point)
|
|
20
22
|
// Also covers gauge (it normalizes to the radialBar engine in v6)
|
|
23
|
+
|
|
24
|
+
import ApexCharts from 'apexcharts/sunburst'
|
|
25
|
+
// Registers: sunburst (v6.7, hierarchical). Free, not gated.
|
|
26
|
+
|
|
27
|
+
import ApexCharts from 'apexcharts/unit'
|
|
28
|
+
// Registers: unit + waffle (v6.6). Premium: watermarked until a license is set.
|
|
29
|
+
|
|
30
|
+
import { heart, outlined, glyphs, preview } from 'apexcharts/unit-shapes'
|
|
31
|
+
// Unit-chart shape kit (v6.10), named exports tree-shaken per shape. See "Unit shapes" below.
|
|
21
32
|
```
|
|
22
33
|
|
|
23
34
|
---
|
|
@@ -94,6 +105,157 @@ A gauge is a single-value `radialBar` alias. Series is a flat one-element array;
|
|
|
94
105
|
|
|
95
106
|
A plain radialBar is effectively a gauge with `shape: 'arc'`. A semi-circle gauge is `startAngle: -90, endAngle: 90`.
|
|
96
107
|
|
|
108
|
+
### Sunburst (v6.7)
|
|
109
|
+
|
|
110
|
+
A sunburst draws a hierarchy as concentric rings: the first level fills a donut around the centre hole, and each deeper level stacks outward, with every child arc constrained to its parent's angular wedge. It is a **free** chart type (not gated). Data uses the axis-style `[{ data: [...] }]` wrapper, but each datum is an `{ x, y, children }` node nested to any depth. A leaf node omits `children`.
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
{
|
|
114
|
+
chart: { type: 'sunburst', height: 380 },
|
|
115
|
+
series: [{
|
|
116
|
+
data: [
|
|
117
|
+
{ x: 'Mobile', y: 55, children: [
|
|
118
|
+
{ x: 'iOS', y: 30, children: [
|
|
119
|
+
{ x: 'iOS 17', y: 18 },
|
|
120
|
+
{ x: 'iOS 16', y: 9 }
|
|
121
|
+
] },
|
|
122
|
+
{ x: 'Android', y: 23 }
|
|
123
|
+
] },
|
|
124
|
+
{ x: 'Desktop', y: 33, children: [
|
|
125
|
+
{ x: 'Windows', y: 20 },
|
|
126
|
+
{ x: 'macOS', y: 10 }
|
|
127
|
+
] }
|
|
128
|
+
]
|
|
129
|
+
}],
|
|
130
|
+
plotOptions: {
|
|
131
|
+
sunburst: {
|
|
132
|
+
innerSize: '25%', // centre hole radius as a % of max radius (or px)
|
|
133
|
+
borderRadius: 5, // round the arc corners (px), same semantics as pie.borderRadius
|
|
134
|
+
spacing: 1, // gap between adjacent arcs (px), same semantics as pie.spacing
|
|
135
|
+
startAngle: 0,
|
|
136
|
+
endAngle: 360,
|
|
137
|
+
leaf: 'extend', // 'extend' draws a shallow branch's leaf to the rim | 'stop'
|
|
138
|
+
partition: 'normalize', // angular partition of a parent's wedge among children: 'normalize' | 'strict'
|
|
139
|
+
tint: 0, // per-depth lightening of the parent colour (0 = same, 1 = white)
|
|
140
|
+
zoomOnClick: true, // click a wedge to zoom into its branch (breadcrumb to go back). Default true
|
|
141
|
+
dataLabels: {
|
|
142
|
+
show: true,
|
|
143
|
+
minAngleToShow: 5, // hide the label on any arc narrower than this (degrees)
|
|
144
|
+
style: { fontSize: '12px', colors: ['#fff'] }
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Colours, `stroke`, `legend`, and `title` behave as they do on pie and donut. A sunburst can also adapt an existing `drilldown` config instead of a native `children` hierarchy.
|
|
152
|
+
|
|
153
|
+
### Unit / Waffle (v6.6, premium)
|
|
154
|
+
|
|
155
|
+
A `unit` chart renders one discrete mark for every unit of value instead of a single bar or slice, so "37 of 200" reads as a countable quantity. It is a **non-axis** chart (dispatched like pie or treemap) and is **premium**: it renders fully in trial mode with an `APEXCHARTS` watermark until an entitled license is set (see `references/v6-features.md`). On every update each mark tweens from its old position to its new one, so re-grouping, filtering, or a changing count re-forms the marks.
|
|
156
|
+
|
|
157
|
+
Data is the same flat number array + `labels` shape as pie:
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
{
|
|
161
|
+
chart: { type: 'unit', height: 360 },
|
|
162
|
+
series: [276, 266, 3],
|
|
163
|
+
labels: ['For', 'Against', 'Abstain'],
|
|
164
|
+
plotOptions: { unit: { layout: 'grouped' } }
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Layouts** via `plotOptions.unit.layout`:
|
|
169
|
+
|
|
170
|
+
- `grouped` (default): one phyllotaxis blob per category, laid out in a row.
|
|
171
|
+
- `packed`: one shared blob, coloured by group (`sortByGroup: true` nests the minority in the centre).
|
|
172
|
+
- `columns`: each category is a vertical bar built from stacked dots (a waffle column).
|
|
173
|
+
- `grid`: one waffle lattice, a part-to-whole square "pie" (`grid.total: 100` rounds it to a fixed cell budget for a percentage waffle; `grid.split: true` makes small-multiple mini-waffles).
|
|
174
|
+
- `scatter`: a beeswarm on real value axes (`scatter.y: 'lanes'` default, or `'value'` for a 2D value-value plot; `scatter.sizeRange` for area-scaled bubbles). Since **v6.7.1** `scatter.orientation: 'horizontal' | 'vertical'` picks the beeswarm axis (lanes mode only): `'horizontal'` (default) puts the value on X with category lanes on Y; `'vertical'` puts the value on Y with lanes as columns. The value-axis keys (`xMin`/`xMax`/`xTitle`/`xFormatter`/`tickAmount`) describe the value axis in both orientations.
|
|
175
|
+
- `arc` (**v6.7**): a parliament / hemicycle, seats in concentric arced rows across an annulus, filled in category order.
|
|
176
|
+
- `custom` (**v6.9**): positions come from you. `plotOptions.unit.positions` is either a function `(objects, rect) => [{ id, x, y, r? }]` or the name of a layout registered with `ApexCharts.registerUnitLayout(name, fn)`. `objects` carries identity and data per mark (`{ id, index, seriesIndex, dataPointIndex, label, value, datum, r }`), `rect` is the plot area in pixels. A layout is objects in, positions out; the engine already tweens position, radius, and colour and keeps mark identity across a relayout. Marks whose id the provider omits animate out; unknown ids are ignored.
|
|
177
|
+
|
|
178
|
+
**Also available:** `shape` (`'circle'` | `'square'` | `'image'` pictogram with `image.tint`); per-mark object data `series: [{ name, data: [{ value, x, z, name, fillColor, id }] }]`; `transition` (`'group'` default | `'flow'` crowd migration | `'identity'` keyed by `id`/`name`); numeric or `'auto'` dot `size`; `sizeByValue` bubbles; `unitValue` (1 mark = N units); `maxUnits` cap; per-cluster `clusterLabels`; and per-mark `tooltip.formatter`.
|
|
179
|
+
|
|
180
|
+
**Motion (v6.9):** marks travel on a damped spring by default, so an update landing mid-flight retargets with the marks' velocity instead of restarting them (a dragged slider reads as continuous motion, not stutter). Configure via `plotOptions.unit.gather`: `motion: 'auto' | 'spring' | 'tween'`, `spring: 'crisp' | 'gentle' | 'snappy'`, `easing: 'outCubic' | 'inOutCubic' | 'outBack'` (setting `easing` implies tween), and `enter: 'burst' | 'fade' | 'rise'`.
|
|
181
|
+
|
|
182
|
+
### Unit shapes (`apexcharts/unit-shapes`, v6.10)
|
|
183
|
+
|
|
184
|
+
A companion kit of **39 shapes** a count can take (a heart, a house, a globe, the figure 1,024 drawn in 1,024 dots). Each shape is a plain callable layout, so it plugs straight into `plotOptions.unit.positions` with `layout: 'custom'`; no registration step. The entry point is tree-shaken per shape (about 4 KB gzipped each). Dots are packed to fill the outline, so one shape serves 40 dots in a sparkline and 3,000 in a poster.
|
|
185
|
+
|
|
186
|
+
```js
|
|
187
|
+
import ApexCharts from 'apexcharts'
|
|
188
|
+
import { heart } from 'apexcharts/unit-shapes'
|
|
189
|
+
|
|
190
|
+
new ApexCharts(el, {
|
|
191
|
+
chart: { type: 'unit' },
|
|
192
|
+
series: [57600, 16800, 4200, 3400],
|
|
193
|
+
labels: ['Repeat donors', 'First-time', 'Workplace drives', 'Emergency call-ups'],
|
|
194
|
+
plotOptions: {
|
|
195
|
+
unit: { layout: 'custom', positions: heart, unitValue: 100 },
|
|
196
|
+
},
|
|
197
|
+
}).render()
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Three kinds:
|
|
201
|
+
|
|
202
|
+
- **Silhouettes** (29, filled outlines): `heart`, `house`, `tree`, `leaf`, `flame`, `droplet`, `fish`, `sun`, `human`, `group`, `star`, `crown`, `trophy`, `moneybag`, `funnel`, `shield`, `gear`, `robot`, `bulb`, `flask`, `car`, `plane`, `rocket`, `battery`, `pin`, `mountain`, `cross`, `bolt`, `arrow`.
|
|
203
|
+
- **Strokes** (7, packed centrelines for things with no interior): `check`, `wifi`, `pulse`, `xmark`, `percent`, `question`, `spiral`.
|
|
204
|
+
- **Generated** (3, positions from maths, no outline): `globe`, `target`, `pyramid`.
|
|
205
|
+
|
|
206
|
+
Composition helpers (also exported from `apexcharts/unit-shapes`):
|
|
207
|
+
|
|
208
|
+
```js
|
|
209
|
+
outlined(heart) // hollow twin: trace the outline instead of filling it (silhouettes only)
|
|
210
|
+
heart.with({ order: 'cols' }) // variant: where each series band lands ('rows' | 'rowsUp' | 'cols' |
|
|
211
|
+
// 'colsRev' | 'centerOut' | 'centerIn'); battery fills like a charge
|
|
212
|
+
// meter because its order is 'cols'
|
|
213
|
+
glyphs('1,024') // a number, drawn in that many dots (digits plus '-', '.', ',', ':')
|
|
214
|
+
preview(heart, { series }) // render to a standalone SVG string, no chart and no DOM (build-time galleries)
|
|
215
|
+
shapeFrom(path, opts?) // your own outline, packed like the catalog's
|
|
216
|
+
strokeFrom(path, opts?) // your own centreline
|
|
217
|
+
registerShapes([...]) // register so positions: '<name>' resolves by string
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Every shape carries metadata on `shape` (category, kind, and `minUnits`: the count below which it stops being recognisable; asking for fewer logs a console warning naming the shape). From a script tag, `dist/unit-shapes.js` exposes the kit as the global `ApexUnitShapes` with every shape pre-registered, so `positions: 'heart'` works by name.
|
|
221
|
+
|
|
222
|
+
**Outer name labels (v6.10):** a shape packed with several categories can name them in the margin with a leader line to their own dots (the pie/donut outer-label mechanism), instead of needing a legend:
|
|
223
|
+
|
|
224
|
+
```js
|
|
225
|
+
plotOptions: {
|
|
226
|
+
unit: { clusterLabels: { external: { show: true } } },
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`clusterLabels.external` also takes `connector: { show, width, color, gap, length }`, `offsetX`, `offsetY`. It applies to `layout: 'custom'` only and reads best on silhouettes whose category bands stack vertically. The gutter is reserved before the dot size is chosen, so the shape stays centred but renders slightly smaller.
|
|
231
|
+
|
|
232
|
+
`waffle` is a thin alias of `unit` that presets the `grid` layout with square cells. With `grid.total: 100` the values are largest-remainder rounded to exactly 100 cells, so the grid reads as percentages. The original alias is preserved on the read-only `chart.requestedType`; an explicit `layout` or `shape` still wins.
|
|
233
|
+
|
|
234
|
+
```js
|
|
235
|
+
{
|
|
236
|
+
chart: { type: 'waffle', height: 360 },
|
|
237
|
+
series: [35, 23, 15, 9, 8, 6, 4],
|
|
238
|
+
labels: ['Coal', 'Gas', 'Hydro', 'Nuclear', 'Wind', 'Solar', 'Other'],
|
|
239
|
+
plotOptions: { unit: { grid: { columns: 10, total: 100 } } }
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
A parliament (hemicycle) seat chart:
|
|
244
|
+
|
|
245
|
+
```js
|
|
246
|
+
{
|
|
247
|
+
chart: { type: 'unit', height: 320 },
|
|
248
|
+
series: [120, 95, 60, 25],
|
|
249
|
+
labels: ['Party A', 'Party B', 'Party C', 'Party D'],
|
|
250
|
+
plotOptions: {
|
|
251
|
+
unit: {
|
|
252
|
+
layout: 'arc',
|
|
253
|
+
arc: { startAngle: -90, endAngle: 90, innerRadiusRatio: 0.4, rows: 'auto' }
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
97
259
|
---
|
|
98
260
|
|
|
99
261
|
## Key plotOptions
|
|
@@ -105,12 +267,25 @@ plotOptions: {
|
|
|
105
267
|
pie: {
|
|
106
268
|
startAngle: 0,
|
|
107
269
|
endAngle: 360,
|
|
108
|
-
expandOnClick: true, //
|
|
270
|
+
expandOnClick: true, // react to a slice click at all
|
|
271
|
+
expandOffset: 10, // (v6.9) how far the clicked slice slides out (px) along its mid-angle.
|
|
272
|
+
// The slice is translated, not redrawn bigger, so the quantity it
|
|
273
|
+
// encodes is unchanged. 0 keeps it in place. Ignored for polarArea.
|
|
274
|
+
hoverOutline: { // (v6.9) hover traces a translucent band outside the slice rim
|
|
275
|
+
show: true, // instead of lightening the fill
|
|
276
|
+
size: 8, // band thickness (px)
|
|
277
|
+
gap: 0, // clearance between slice rim and band (px)
|
|
278
|
+
opacity: 0.3,
|
|
279
|
+
color: undefined // defaults to the hovered slice's own color
|
|
280
|
+
},
|
|
109
281
|
offsetX: 0,
|
|
110
282
|
offsetY: 0,
|
|
111
283
|
|
|
112
284
|
customScale: 1, // scale the pie (0.5 = half size)
|
|
113
285
|
|
|
286
|
+
borderRadius: 0, // (v6.7) round each slice's corners (px). Applies to pie, donut, polarArea
|
|
287
|
+
spacing: 0, // (v6.7) gap between adjacent slices (px). Applies to pie, donut, polarArea
|
|
288
|
+
|
|
114
289
|
dataLabels: {
|
|
115
290
|
offset: 0, // move labels away from center
|
|
116
291
|
minAngleToShowLabel: 10 // hide labels on tiny slices
|
|
@@ -266,3 +441,7 @@ plotOptions: {
|
|
|
266
441
|
6. **Polar Area confused with Radar** — polar area uses `series: [num]` (flat), radar uses `series: [{ data: [num] }]` (axis format). They look similar but have different data shapes.
|
|
267
442
|
7. **Looking for `plotOptions.gauge`**: it does not exist. Gauge is a `radialBar` alias; configure `shape`, `bands`, `ticks`, `needle`, and `min`/`max` under `plotOptions.radialBar`.
|
|
268
443
|
8. **Gauge value outside `min`/`max`**: unlike a plain radialBar (fixed 0-100), a gauge maps its value to the `min..max` domain you set. A value beyond that domain saturates at the arc ends.
|
|
444
|
+
9. **Legend click now toggles the slice (v6.7 behavior change)**: on pie, donut, and polarArea a legend click hides and shows the slice (like other chart types). Previously it darkened and expanded the slice. If your app relied on the old darken-and-expand behavior, review this.
|
|
445
|
+
10. **Expecting `unit` / `waffle` without a license to be watermark-free**: they are premium and render an `APEXCHARTS` watermark until an entitled `premium`/`enterprise` license is set. Sunburst, by contrast, is free.
|
|
446
|
+
11. **Slice click behavior changed (v6.9)**: clicking a pie/donut slice now slides it out along its own mid-angle (`plotOptions.pie.expandOffset`, default 10 px) instead of darkening it and redrawing it at a larger radius, and hover traces an outline band (`plotOptions.pie.hoverOutline`) instead of lightening the fill. Set `expandOffset: 0` to keep slices in place; set `states.hover.filter.type: 'none'` to suppress the hover band.
|
|
447
|
+
12. **Unit shapes below `minUnits`**: each `apexcharts/unit-shapes` shape declares the minimum dot count at which it still reads. Feeding fewer units logs a console warning naming the shape; pick a simpler shape or raise `unitValue` so the count lands above the threshold.
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
- **Candlestick** (`'candlestick'`) — OHLC (Open, High, Low, Close) financial chart
|
|
6
6
|
- **Box Plot** (`'boxPlot'`) — Statistical distribution chart showing min, Q1, median, Q3, max
|
|
7
7
|
- **Violin** (`'violin'`, **new in v6**): Statistical distribution chart showing a density curve per category, optionally with the raw sample points overlaid as jitter
|
|
8
|
+
- **Histogram** (`'histogram'`, **new in v6.9**): Bins raw observations into columns; the series carries the sample, the chart does the aggregating
|
|
8
9
|
|
|
9
10
|
## Tree-Shakeable Import
|
|
10
11
|
|
|
@@ -15,8 +16,18 @@ import ApexCharts from 'apexcharts/candlestick'
|
|
|
15
16
|
|
|
16
17
|
import ApexCharts from 'apexcharts/violin'
|
|
17
18
|
// Registers: violin (separate entry point, new in v6)
|
|
19
|
+
|
|
20
|
+
import ApexCharts from 'apexcharts/histogram'
|
|
21
|
+
// Registers: histogram (v6.9), the bar engine plus the stats feature
|
|
22
|
+
|
|
23
|
+
// The statistics (histogram binning, boxPlot/violin raw-sample summaries,
|
|
24
|
+
// rowSeries()) live behind one optional feature. apexcharts/histogram already
|
|
25
|
+
// includes it; boxPlot/violin raw samples need it explicitly when tree-shaking:
|
|
26
|
+
import 'apexcharts/features/stats'
|
|
18
27
|
```
|
|
19
28
|
|
|
29
|
+
**Raw samples (v6.9):** boxPlot, violin, and histogram can all take the raw observations and compute the statistics themselves (quartiles for boxPlot, KDE density for violin, bin counts for histogram). Precomputed summaries keep working exactly as before. With the full `apexcharts` bundle the stats feature is always present; with tree-shaking entries it must be imported (without it, a raw-sample boxPlot/violin datum has nothing to summarize and a histogram warns and draws nothing).
|
|
30
|
+
|
|
20
31
|
---
|
|
21
32
|
|
|
22
33
|
## Data Formats
|
|
@@ -72,11 +83,39 @@ The `y` value must be an array of exactly 5 numbers: `[min, Q1, median, Q3, max]
|
|
|
72
83
|
}
|
|
73
84
|
```
|
|
74
85
|
|
|
86
|
+
### Box Plot: Raw Sample (v6.9)
|
|
87
|
+
|
|
88
|
+
Instead of a five-number `y`, a datum may supply the raw observations in `points` and the library computes the summary (quartiles interpolate between ranks, R type 7). Requires `apexcharts/features/stats` when tree-shaking. `points` is the same field used for the jitter-dot overlay, so the sample lives in one place whether you summarize it or the library does.
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
{
|
|
92
|
+
chart: { type: 'boxPlot', height: 350 },
|
|
93
|
+
series: [{
|
|
94
|
+
data: [
|
|
95
|
+
{ x: 'Phone', points: [1.2, 1.9, 3.4, 2.2, 2.8, 4.1, 1.7] },
|
|
96
|
+
{ x: 'Tablet', points: [2.4, 3.1, 3.9, 2.9, 4.6, 3.3] }
|
|
97
|
+
]
|
|
98
|
+
}],
|
|
99
|
+
plotOptions: {
|
|
100
|
+
boxPlot: {
|
|
101
|
+
whiskers: 'minmax', // 'minmax' (default): whiskers reach the extremes, nothing hidden
|
|
102
|
+
// 'tukey': stop at the last observation within 1.5 × IQR of each quartile
|
|
103
|
+
points: { show: true } // overlay the observations as jitter dots
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
- `whiskers` only applies when the summary is **derived** from `points`; a precomputed five-number `y` is drawn exactly as given.
|
|
110
|
+
- With `whiskers: 'tukey'`, observations beyond the fence fall outside the whisker, so pair it with `points: { show: true }` or they become invisible.
|
|
111
|
+
- `plotOptions.boxPlot.points` also takes `shape` (`'circle'` | `'square'`), `size`, `jitter` (0..1 fraction of the box half-width), `maxPoints` (cap per box, stride-thinned beyond), `opacity`, `fillColor` (`'series-dark'` default | `'series'` | any color), `strokeColor`, `strokeWidth`, and a value-driven `colorScale: { colors, min, max, steps }`.
|
|
112
|
+
- A datum with both `y` and `points` draws the given summary and overlays the points as jitter.
|
|
113
|
+
|
|
75
114
|
### Violin: Density Profile (v6)
|
|
76
115
|
|
|
77
116
|
Each point is `{ x, y: { density, points } }`:
|
|
78
117
|
|
|
79
|
-
- `density
|
|
118
|
+
- `density`: an array of `[value, weight]` pairs describing the precomputed density/KDE profile. Drawn exactly as given.
|
|
80
119
|
- `points` (optional): a flat array of raw observations, rendered as jitter dots.
|
|
81
120
|
|
|
82
121
|
```js
|
|
@@ -111,6 +150,32 @@ Each point is `{ x, y: { density, points } }`:
|
|
|
111
150
|
}
|
|
112
151
|
```
|
|
113
152
|
|
|
153
|
+
### Violin: Raw Sample (v6.9)
|
|
154
|
+
|
|
155
|
+
A datum may instead supply only the raw observations (in `points`, no `y`) and the library derives the density itself via kernel density estimation. Requires `apexcharts/features/stats` when tree-shaking. `plotOptions.violin.kde` tunes the estimation; it is ignored when a precomputed `density` profile is given.
|
|
156
|
+
|
|
157
|
+
```js
|
|
158
|
+
{
|
|
159
|
+
chart: { type: 'violin', height: 420 },
|
|
160
|
+
series: [{
|
|
161
|
+
name: 'Session duration',
|
|
162
|
+
data: [
|
|
163
|
+
{ x: 'Direct', points: [22, 31, 38, 41, 47, 52, 58, 33, 40] },
|
|
164
|
+
{ x: 'Referral', points: [27, 34, 44, 48, 53, 61, 39] }
|
|
165
|
+
]
|
|
166
|
+
}],
|
|
167
|
+
plotOptions: {
|
|
168
|
+
violin: {
|
|
169
|
+
kde: {
|
|
170
|
+
bandwidth: undefined, // kernel width in value units; unset = Silverman's rule of thumb
|
|
171
|
+
resolution: 64 // density samples per violin (default 64)
|
|
172
|
+
},
|
|
173
|
+
points: { show: true } // the same sample doubles as the jitter overlay
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
114
179
|
**Orientation and per-category color come from `plotOptions.bar`** (violin reuses the bar renderer):
|
|
115
180
|
|
|
116
181
|
```js
|
|
@@ -123,6 +188,44 @@ plotOptions: {
|
|
|
123
188
|
}
|
|
124
189
|
```
|
|
125
190
|
|
|
191
|
+
### Histogram (v6.9)
|
|
192
|
+
|
|
193
|
+
The series carries **raw observations** (a flat number array, or `{ y }` objects), one number per event; the chart chooses the bin width and counts them. It renders through the bar pathway (like funnel, pyramid, gauge, and waffle), so stacking, zoom, export, and animation all work on the bins. Import from `apexcharts/histogram`, or add `import 'apexcharts/features/stats'` alongside `apexcharts/bar`; the full `apexcharts` bundle already includes it. Without the stats feature the chart warns and draws nothing.
|
|
194
|
+
|
|
195
|
+
```js
|
|
196
|
+
{
|
|
197
|
+
chart: { type: 'histogram', height: 350 },
|
|
198
|
+
series: [{ name: 'Latency', data: [102, 87, 143, 91, 118, 95, 132, 88, 107] }],
|
|
199
|
+
plotOptions: {
|
|
200
|
+
histogram: {
|
|
201
|
+
bins: 'auto', // 'auto' | 'fd' | 'sturges' | 'scott' | 'rice' | 'sqrt' | number (fixed count)
|
|
202
|
+
// 'auto' takes the narrower of Freedman-Diaconis and Sturges
|
|
203
|
+
binWidth: undefined, // explicit bin width in value units; wins over `bins` when the
|
|
204
|
+
// boundaries carry meaning (decades, 5-minute buckets)
|
|
205
|
+
range: undefined, // [min, max] to bin over instead of the data's own extent
|
|
206
|
+
normalize: 'count', // 'count' | 'relative' (percent of series total) | 'density' (total area = 1)
|
|
207
|
+
cumulative: false, // running total across bins (a CDF)
|
|
208
|
+
overlap: true // multi-series: draw each series across the full bin (overlay).
|
|
209
|
+
// false = side-by-side grouped bars per bin
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
- **All series share one set of bin edges** derived from their combined extent, so two distributions stay comparable instead of putting different bars at the same x.
|
|
216
|
+
- `overlap: true` (the default with multiple series) also softens the fill and drops the bin separator stroke so the overlapping region reads; both remain overridable. A single series is unaffected either way.
|
|
217
|
+
- Do NOT pass pre-aggregated counts; that is a plain `bar` chart. The histogram's job is the binning.
|
|
218
|
+
|
|
219
|
+
### `rowSeries()`: the rows behind a summary mark (v6.9)
|
|
220
|
+
|
|
221
|
+
A histogram bin, a box, and a violin all stand for rows the chart is already holding. `chart.rowSeries()` returns them as a unit-chart series (one cluster per mark, one datum per row), so a summary can be opened into its observations:
|
|
222
|
+
|
|
223
|
+
```js
|
|
224
|
+
chart.updateOptions({ chart: { type: 'unit' }, series: chart.rowSeries() })
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Returns `null` when the current type has no row source or the stats feature is not loaded. `chart.rowSeries({ maxRows })` caps the dots produced (default 3000); past the cap every cluster is thinned by one shared stride so relative sizes survive. With the `morph` feature loaded, each dot animates out of the part of the mark that stood for it.
|
|
228
|
+
|
|
126
229
|
---
|
|
127
230
|
|
|
128
231
|
## Key plotOptions
|
|
@@ -206,9 +309,12 @@ plotOptions: {
|
|
|
206
309
|
## Family-Specific Pitfalls
|
|
207
310
|
|
|
208
311
|
1. **Wrong OHLC order** — must be `[Open, High, Low, Close]`, not `[High, Low, Open, Close]` or any other order.
|
|
209
|
-
2. **Box Plot with wrong array length** — must be exactly 5 values `[min, Q1, median, Q3, max]`. Fewer or more values cause rendering errors.
|
|
210
|
-
3. **Using simple numeric array** — `data: [10, 20, 30]` does NOT work for candlestick/boxPlot. Each point requires an array in `y
|
|
312
|
+
2. **Box Plot with wrong array length** — a summary `y` must be exactly 5 values `[min, Q1, median, Q3, max]`. Fewer or more values cause rendering errors. (Since v6.9 the alternative is no `y` at all: put the raw sample in `points` and the summary is computed.)
|
|
313
|
+
3. **Using simple numeric array** — `data: [10, 20, 30]` does NOT work for candlestick/boxPlot. Each point requires an array in `y` (or, for boxPlot since v6.9, a raw sample in `points`). For a distribution of a flat number array, use `chart.type: 'histogram'` instead.
|
|
211
314
|
4. **Missing `xaxis.type: 'datetime'`** — candlestick charts with date x-values need `xaxis: { type: 'datetime' }` to format dates correctly.
|
|
212
315
|
5. **Confusing candlestick with boxPlot** — candlestick is 4 values (OHLC), boxPlot is 5 values (five-number summary). They share the same entry point but have different data shapes.
|
|
213
|
-
6. **Violin with a plain numeric `y`**: violin points need `y: { density: [[value, weight], ...] }`, not a number.
|
|
214
|
-
7. **Violin orientation set on the wrong namespace**: horizontal violins and per-violin colors come from `plotOptions.bar` (`horizontal`, `distributed`), while `bandwidthScale`, `normalize`, and `points` live under `plotOptions.violin`.
|
|
316
|
+
6. **Violin with a plain numeric `y`**: violin points need `y: { density: [[value, weight], ...] }` or (v6.9) raw observations in `points`, not a single number. With a precomputed `density` profile it is drawn exactly as given; with raw `points` the KDE runs for you (stats feature required when tree-shaking).
|
|
317
|
+
7. **Violin orientation set on the wrong namespace**: horizontal violins and per-violin colors come from `plotOptions.bar` (`horizontal`, `distributed`), while `bandwidthScale`, `kde`, `normalize`, and `points` live under `plotOptions.violin`.
|
|
318
|
+
8. **Feeding a histogram pre-binned counts**: the series must carry raw observations. If you already have counts per bucket, use a `bar` chart; a histogram would bin your counts as if they were measurements.
|
|
319
|
+
9. **`whiskers: 'tukey'` on a precomputed boxPlot summary**: `plotOptions.boxPlot.whiskers` only applies when the summary is derived from `points`. A five-number `y` is drawn exactly as given.
|
|
320
|
+
10. **Raw samples with tree-shaking but no stats feature**: `apexcharts/candlestick` and `apexcharts/violin` alone cannot summarize `points`. Add `import 'apexcharts/features/stats'` (the `apexcharts/histogram` entry and the full bundle already include it).
|
|
@@ -46,6 +46,49 @@ Each series is a row; each data point is a cell. The `y` value determines the co
|
|
|
46
46
|
}
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
#### Continuous numeric / datetime x-axis (v6.4)
|
|
50
|
+
|
|
51
|
+
By default a heatmap tiles one cell per column by index. On a **numeric or datetime** x-axis (`xaxis.type: 'numeric'` or `'datetime'`), cells are instead placed at their real x value, so irregular spacing and gaps render as real empty space: a missing hour is a gap in the grid, not a squeezed column, and the axis shows sparse proportional ticks rather than one label per cell. Rows stay categorical (one series per row).
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
{
|
|
55
|
+
chart: { type: 'heatmap', height: 350 },
|
|
56
|
+
xaxis: { type: 'datetime' },
|
|
57
|
+
series: [{
|
|
58
|
+
name: 'Server 1',
|
|
59
|
+
data: [
|
|
60
|
+
{ x: new Date('2024-01-01T09:00').getTime(), y: 20 },
|
|
61
|
+
{ x: new Date('2024-01-01T11:00').getTime(), y: 80 }, // 10:00 is absent -> real gap
|
|
62
|
+
{ x: new Date('2024-01-01T12:00').getTime(), y: 65 }
|
|
63
|
+
]
|
|
64
|
+
}]
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Canvas rendering for large heatmaps (v6.4)
|
|
69
|
+
|
|
70
|
+
With `chart.renderer: 'canvas'` (or `'auto'` past `chart.rendererThreshold`) and the canvas feature imported, heatmap cells paint to a single canvas instead of one `<rect>` per cell, which is several times faster for large grids (roughly 3x at 50,000+ cells).
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
import ApexCharts from 'apexcharts'
|
|
74
|
+
import 'apexcharts/features/renderer-canvas'
|
|
75
|
+
|
|
76
|
+
const options = {
|
|
77
|
+
chart: {
|
|
78
|
+
type: 'heatmap',
|
|
79
|
+
renderer: 'canvas', // 'svg' | 'canvas' | 'auto'
|
|
80
|
+
},
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Heatmap default changes (v6.4)
|
|
85
|
+
|
|
86
|
+
Three heatmap defaults changed in 6.4.0. Each is a default, not a removal:
|
|
87
|
+
|
|
88
|
+
- **Tooltip anchored above the cell.** The heatmap tooltip now sits centered above the hovered cell with a downward arrow pointing at it (flipping below when the cell is against the top edge), instead of following the cursor.
|
|
89
|
+
- **Zoom is off by default.** Re-enable with `chart.zoom: { enabled: true }` if you need it.
|
|
90
|
+
- **Y-axis label thinning.** Dense y-axis (row) labels are thinned to fit.
|
|
91
|
+
|
|
49
92
|
### Treemap
|
|
50
93
|
|
|
51
94
|
Flat list of `{ x, y }` where `x` is the label and `y` is the value (determines area).
|
|
@@ -90,6 +133,55 @@ Flat list of `{ x, y }` where `x` is the label and `y` is the value (determines
|
|
|
90
133
|
}
|
|
91
134
|
```
|
|
92
135
|
|
|
136
|
+
### Nested Treemap (v6.9)
|
|
137
|
+
|
|
138
|
+
A datum may carry `children` to any depth; every branch is drawn as a real container with a header strip and its children inset below it, and a container's area is exactly the sum of its children. A branch normally omits `y` and takes the sum of its children; a leaf supplies one. Flat inputs are untouched and render identically to before.
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
{
|
|
142
|
+
chart: { type: 'treemap', height: 400 },
|
|
143
|
+
series: [{
|
|
144
|
+
data: [
|
|
145
|
+
{ x: 'Technology', children: [
|
|
146
|
+
{ x: 'Software', children: [
|
|
147
|
+
{ x: 'Acme Corp', y: 120 },
|
|
148
|
+
{ x: 'Initech', y: 80 }
|
|
149
|
+
] },
|
|
150
|
+
{ x: 'Hardware', y: 95 }
|
|
151
|
+
] },
|
|
152
|
+
{ x: 'Energy', children: [
|
|
153
|
+
{ x: 'Solar Co', y: 60 },
|
|
154
|
+
{ x: 'Wind Ltd', y: 45 }
|
|
155
|
+
] }
|
|
156
|
+
]
|
|
157
|
+
}]
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Nested-specific options under `plotOptions.treemap`:
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
plotOptions: {
|
|
165
|
+
treemap: {
|
|
166
|
+
nested: {
|
|
167
|
+
enabled: true, // 'auto' behavior: parents appear as soon as the data is nested;
|
|
168
|
+
// false forces the flat two-level layout
|
|
169
|
+
drilldownAsLevels: false // read `drilldown: '<id>'` ids on data points as extra levels
|
|
170
|
+
// instead of as click targets for the drilldown feature.
|
|
171
|
+
// Default false ("descend on click" is the historical meaning)
|
|
172
|
+
},
|
|
173
|
+
parents: { // how branch containers are drawn once the data is nested
|
|
174
|
+
show: 'auto' // 'auto' (on when the data carries children) | true | false
|
|
175
|
+
// plus header/label styling and a tooltip.formatter receiving
|
|
176
|
+
// { name, value, depth, leafCount, percentOfParent, percentOfTotal, node, w }
|
|
177
|
+
},
|
|
178
|
+
levels: [ /* per-depth overrides of `parents`, indexed from the outermost drawn group */ ]
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The hierarchy resolver is shared with sunburst, including the `drilldown: '<id>'` adapter (opted into via `nested.drilldownAsLevels`).
|
|
184
|
+
|
|
93
185
|
---
|
|
94
186
|
|
|
95
187
|
## Key plotOptions
|
|
@@ -196,3 +288,4 @@ plotOptions: {
|
|
|
196
288
|
2. **Inconsistent x-values across heatmap series** — all series should have the same set of x-values to form a proper grid. Missing cells show as gaps.
|
|
197
289
|
3. **Treemap with negative values** — treemap `y` values must be positive (they represent area). Negative values cause rendering issues.
|
|
198
290
|
4. **Confusing heatmap `y` with position** — in heatmap data `{ x, y }`, the `y` is the VALUE (color intensity), NOT the y-axis position. The series `name` determines the row.
|
|
291
|
+
5. **Nested treemap branch carrying its own `y` (v6.9)**: a branch node normally omits `y`; its area is the sum of its children. Only leaves supply values. Flattening a hierarchy by hand is no longer necessary; pass `children` instead.
|
|
@@ -29,6 +29,7 @@ Each entry point registers a family of related chart types:
|
|
|
29
29
|
| `apexcharts/candlestick` | candlestick, boxPlot |
|
|
30
30
|
| `apexcharts/boxPlot` | same as /candlestick |
|
|
31
31
|
| `apexcharts/violin` | violin *(new in v6)* |
|
|
32
|
+
| `apexcharts/histogram` | histogram *(new in v6.9)*: the bar engine plus the stats feature |
|
|
32
33
|
| `apexcharts/pie` | pie, donut, polarArea |
|
|
33
34
|
| `apexcharts/donut` | same as /pie |
|
|
34
35
|
| `apexcharts/polarArea` | same as /pie |
|
|
@@ -36,8 +37,11 @@ Each entry point registers a family of related chart types:
|
|
|
36
37
|
| `apexcharts/radar` | radar |
|
|
37
38
|
| `apexcharts/heatmap` | heatmap |
|
|
38
39
|
| `apexcharts/treemap` | treemap |
|
|
40
|
+
| `apexcharts/sunburst` | sunburst *(new in v6.7, free)* |
|
|
41
|
+
| `apexcharts/unit` | unit, **waffle** *(new in v6.6, premium: watermarked until licensed)* |
|
|
42
|
+
| `apexcharts/unit-shapes` | *(new in v6.10)* not a chart entry: named shape exports for the unit chart (`heart`, `house`, ... plus `outlined`, `glyphs`, `preview`), tree-shaken per shape (~4 KB gzipped each). See `references/circular-charts.md`. |
|
|
39
43
|
|
|
40
|
-
**v6 first-class aliases:** `funnel` and `pyramid` render through the bar engine, so `apexcharts/bar` covers them. `gauge` renders through radialBar, so `apexcharts/radialBar` covers it. There is no separate `apexcharts/funnel`, `apexcharts/pyramid`, or `apexcharts/gauge` entry.
|
|
44
|
+
**v6 first-class aliases:** `funnel` and `pyramid` render through the bar engine, so `apexcharts/bar` covers them. `gauge` renders through radialBar, so `apexcharts/radialBar` covers it. There is no separate `apexcharts/funnel`, `apexcharts/pyramid`, or `apexcharts/gauge` entry. `histogram` also renders through the bar engine but has its own `apexcharts/histogram` entry because it bundles the stats feature; `apexcharts/bar` + `import 'apexcharts/features/stats'` is equivalent.
|
|
41
45
|
|
|
42
46
|
### Using Multiple Chart Types
|
|
43
47
|
|
|
@@ -60,6 +64,7 @@ Features are optional modules that add functionality. When using per-type entrie
|
|
|
60
64
|
| Annotations | `import 'apexcharts/features/annotations'` | X/Y/point/text/image annotations |
|
|
61
65
|
| Exports | `import 'apexcharts/features/exports'` | `dataURI()`, `getSvgString()`, `exportToCSV()` |
|
|
62
66
|
| Keyboard | `import 'apexcharts/features/keyboard'` | Keyboard navigation (accessibility) |
|
|
67
|
+
| Stats *(v6.9)* | `import 'apexcharts/features/stats'` | Histogram binning, boxPlot/violin raw-sample summaries, `rowSeries()` |
|
|
63
68
|
| Morph *(v6)* | `import 'apexcharts/features/morph'` | Animated chart-type morphs |
|
|
64
69
|
| Drilldown *(v6)* | `import 'apexcharts/features/drilldown'` | Hierarchical drill-down |
|
|
65
70
|
| History / Rewind *(v6)* | `import 'apexcharts/features/history'` | Undo/redo (`chart.history`) |
|
|
@@ -77,6 +82,8 @@ Features are optional modules that add functionality. When using per-type entrie
|
|
|
77
82
|
|
|
78
83
|
**Important:** Tooltip is always included in core (it cannot be tree-shaken). Easing (Cadence) and real-time streaming are also core, so they need no feature import. See `v6-features.md` for the config and API of each v6 feature.
|
|
79
84
|
|
|
85
|
+
**Runtime dependency (v6.9):** ApexCharts is no longer dependency-free: it depends on `apex-commons` at runtime (license manager, crossfilter engine, spring primitives shared across the ApexCharts family). npm resolves it automatically, and the browser (script-tag) bundles inline it, so no configuration is needed; bundlers just see one more resolvable package. The `apexcharts/unit` and `apexcharts/unit-shapes` sub-entry points resolve for bundlers and script tags alike (from a script tag, `dist/unit-shapes.js` exposes the global `ApexUnitShapes`).
|
|
86
|
+
|
|
80
87
|
### What Happens If You Forget a Feature
|
|
81
88
|
|
|
82
89
|
Features fail **silently**. If you use a per-type entry without importing legend:
|
|
@@ -9,6 +9,50 @@ Two behaviors changed *on by default* (both respect `prefers-reduced-motion`):
|
|
|
9
9
|
|
|
10
10
|
Also new by default: **`render()` is idempotent**: a repeated `render()` (e.g. a framework double-invoking an effect) returns the same promise instead of building a duplicate chart. `destroy()` clears it so an instance can render fresh.
|
|
11
11
|
|
|
12
|
+
Two update behaviors worth knowing (both 6.9/6.10):
|
|
13
|
+
|
|
14
|
+
- **Function-valued options are compared by identity (6.10)**: `update()` skips a redundant render by comparing the incoming options with the previous ones. Passing a *different* function (a new `dataLabels.formatter`, custom tooltip, `plotOptions.unit.positions`) gets the render it asked for; passing the *same* function twice still skips. Building a fresh closure on every update means a render every time.
|
|
15
|
+
- **A type change re-chooses type defaults (6.9)**: `updateOptions({ chart: { type } })` now re-picks the defaults that decide what a chart reads, says, hit-tests, or offers as interaction (e.g. a boxPlot-to-violin switch gets the right tooltip formatter). Deliberate paint choices and anything you set yourself are never re-chosen.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Licensing: premium features and the trial watermark
|
|
20
|
+
|
|
21
|
+
Introduced in **6.5.0**, tightened in **6.7.0**. Not every v6 feature is free. Seven feature modules plus the `unit` / `waffle` chart type are **premium** and run under a lightweight, offline license check. They keep working fully without a key (trial mode), but the chart shows an unobtrusive `APEXCHARTS` watermark until an entitled license is set.
|
|
22
|
+
|
|
23
|
+
**The premium set (watermarked until entitled):**
|
|
24
|
+
|
|
25
|
+
- `storyboard` (scrollytelling)
|
|
26
|
+
- `link` (crossfilter / linked views)
|
|
27
|
+
- `ink` (annotation authoring)
|
|
28
|
+
- `measure` (delta ruler)
|
|
29
|
+
- `context-menu` (`contextMenu`)
|
|
30
|
+
- `perspectives` (shareable view state)
|
|
31
|
+
- `history` (undo/redo, Rewind)
|
|
32
|
+
- the `unit` / `waffle` chart type (premium since **6.6.0**, the first premium chart type)
|
|
33
|
+
|
|
34
|
+
**Everything else is free and never gated**: every other chart type (including `sunburst`), and every other module (Weave, Strata / canvas, Marks, Facet / themes, Cadence, drilldown, streaming, exports, legend, toolbar, annotations, keyboard).
|
|
35
|
+
|
|
36
|
+
### Setting a license
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
// Static: applies to every chart on the page. Call before render().
|
|
40
|
+
ApexCharts.setLicense('APEX-...')
|
|
41
|
+
|
|
42
|
+
// Per-chart: overrides the static key and window.Apex.license for this chart.
|
|
43
|
+
const options = { chart: { license: 'APEX-...' } }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Both are typed: `ApexCharts.setLicense(key: string)` (static) and `chart.license?: string`.
|
|
47
|
+
|
|
48
|
+
- **In use, not bundled.** Importing a premium module without actually enabling it does not watermark; only *using* it does.
|
|
49
|
+
- **Live.** A late `setLicense(validKey)` followed by an update clears an on-screen watermark; no full re-render needed. The watermark is re-evaluated on every render/update.
|
|
50
|
+
- **One key across the family.** The key format is shared across the ApexCharts family (apexgantt, apextree, apexsankey, apex-grid-enterprise, apexstock), validated offline with no network call. SSR-safe.
|
|
51
|
+
|
|
52
|
+
### Plan entitlement (6.7.0 behavior change)
|
|
53
|
+
|
|
54
|
+
As of **6.7.0** the premium features clear the watermark only on a `premium` or `enterprise` plan. A valid `pro` key, or the free tier, keeps them in trial mode with the watermark and logs a one-time upgrade notice (it is **not** treated as an invalid key). **Existing `pro`-plan customers using these features will now see the watermark.** No functionality is blocked in any case, the watermark is the only effect.
|
|
55
|
+
|
|
12
56
|
---
|
|
13
57
|
|
|
14
58
|
## Weave: public plugin platform
|
|
@@ -116,6 +160,8 @@ Dumbbell uses `dataType: 'rangeXY'` (datum `y` is `[start, end]`, both bounds fo
|
|
|
116
160
|
|
|
117
161
|
`import 'apexcharts/features/history'`
|
|
118
162
|
|
|
163
|
+
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
164
|
+
|
|
119
165
|
Generic Ctrl-Z over a command journal. Zooms, series toggles, option changes, and annotation edits are recorded; high-frequency gestures coalesce into a single step.
|
|
120
166
|
|
|
121
167
|
```js
|
|
@@ -137,6 +183,8 @@ chart.history.entries() // [{ id, label, at }]
|
|
|
137
183
|
|
|
138
184
|
`import 'apexcharts/features/perspectives'`
|
|
139
185
|
|
|
186
|
+
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
187
|
+
|
|
140
188
|
Serialize the exact view (zoom window, hidden series, selection, annotations, theme) into a compact token you can put in a URL and restore anywhere.
|
|
141
189
|
|
|
142
190
|
```js
|
|
@@ -219,6 +267,8 @@ Built-in curve names: `linear`, `easeInSine`, `easeOutSine`, `easeInOutSine`, `e
|
|
|
219
267
|
|
|
220
268
|
`import 'apexcharts/features/link'`
|
|
221
269
|
|
|
270
|
+
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
271
|
+
|
|
222
272
|
Coordinate a group of charts without wiring.
|
|
223
273
|
|
|
224
274
|
```js
|
|
@@ -255,6 +305,8 @@ const b = {
|
|
|
255
305
|
|
|
256
306
|
`import 'apexcharts/features/ink'`
|
|
257
307
|
|
|
308
|
+
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
309
|
+
|
|
258
310
|
Annotations become draggable and resizable, with click-to-create, snap to gridlines, and a floating editor card (rename, recolor, bold, font size, marker size/shape, delete). Every edit is undoable when Rewind is enabled.
|
|
259
311
|
|
|
260
312
|
```js
|
|
@@ -277,6 +329,8 @@ const options = {
|
|
|
277
329
|
|
|
278
330
|
`import 'apexcharts/features/measure'`
|
|
279
331
|
|
|
332
|
+
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
333
|
+
|
|
280
334
|
Hold a key and drag to read the change, percent, range, and slope between two points; on release the ruler pins as a data-anchored overlay that re-projects on zoom and resize.
|
|
281
335
|
|
|
282
336
|
```js
|
|
@@ -324,6 +378,8 @@ const options = {
|
|
|
324
378
|
|
|
325
379
|
`import 'apexcharts/features/context-menu'`
|
|
326
380
|
|
|
381
|
+
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
382
|
+
|
|
327
383
|
Right-click or long-press a data point for actions that operate at that exact point.
|
|
328
384
|
|
|
329
385
|
```js
|
|
@@ -350,6 +406,8 @@ Built-in `annotate` / `xline` / `yline` items are ink-managed when the ink featu
|
|
|
350
406
|
|
|
351
407
|
`import 'apexcharts/features/storyboard'` (includes Perspectives)
|
|
352
408
|
|
|
409
|
+
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
410
|
+
|
|
353
411
|
Pair prose sections with saved views. Scrolling a beat past the viewport trigger applies its view; scrolling back reverses it. A beat can also merge an `options` payload to restyle or morph `chart.type` inside one animated transition.
|
|
354
412
|
|
|
355
413
|
```js
|
|
@@ -386,7 +444,7 @@ const options = { chart: { streaming: { enabled: true, maxPoints: 100000 } } }
|
|
|
386
444
|
|
|
387
445
|
`import 'apexcharts/features/drilldown'` (add `import 'apexcharts/features/morph'` for animated cross-type transitions)
|
|
388
446
|
|
|
389
|
-
Data points reference a child level via a `drilldown` id; clicking drills in, with an optional breadcrumb.
|
|
447
|
+
Data points reference a child level via a `drilldown` id; clicking drills in, with an optional breadcrumb. Since **v6.9** drilldown also works on **line and area** charts, and levels can be resolved **async** against a backend.
|
|
390
448
|
|
|
391
449
|
```js
|
|
392
450
|
import 'apexcharts/features/drilldown'
|
|
@@ -404,14 +462,23 @@ const options = {
|
|
|
404
462
|
series: [
|
|
405
463
|
{ id: '2021', name: '2021 by Channel', data: [/* ... */], chart: { type: 'bar' } },
|
|
406
464
|
],
|
|
407
|
-
// or resolve lazily:
|
|
408
|
-
onDrillDown: (ctx) => ({ id: ctx.point.drilldown, name: '...', data:
|
|
465
|
+
// or resolve lazily; may return a Promise (v6.9):
|
|
466
|
+
onDrillDown: async (ctx) => ({ id: ctx.point.drilldown, name: '...', data: await fetchLevel(ctx) }),
|
|
467
|
+
loading: { show: true, text: 'Loading' }, // (v6.9) overlay while an async level resolves;
|
|
468
|
+
// false disables it. role="status", aria-live="polite",
|
|
469
|
+
// spinner flattens to a pulse under prefers-reduced-motion
|
|
470
|
+
cache: true, // (v6.9) cache onDrillDown results by id (default true);
|
|
471
|
+
// clear with the drilldown module's clearCache()
|
|
472
|
+
// (v6.9) line/area only: the dot marking a drillable point when the chart
|
|
473
|
+
// draws no markers. Only drillable points get one, so it reads as "these open".
|
|
474
|
+
marker: { show: true, size: 6, shape: 'circle', fillColor: undefined, strokeColor: '#fff' },
|
|
409
475
|
},
|
|
410
476
|
chart: {
|
|
411
477
|
events: {
|
|
412
478
|
drillDownStart: (info, chart, options) => {},
|
|
413
479
|
drillDownEnd: (info, chart, options) => {},
|
|
414
480
|
drillUp: (info, chart, options) => {},
|
|
481
|
+
drillDownError: ({ id, error }, chart, options) => {}, // (v6.9) async level failed
|
|
415
482
|
},
|
|
416
483
|
},
|
|
417
484
|
}
|
|
@@ -421,6 +488,50 @@ chart.drillUp()
|
|
|
421
488
|
chart.drillToRoot()
|
|
422
489
|
```
|
|
423
490
|
|
|
491
|
+
**Async failure semantics (v6.9):** a failed fetch never strands the view. On a throw, a rejection, or a resolver returning something without a `data` array, the chart stays where it was, the breadcrumb is untouched, nothing is cached, and `drillDownError` fires. A second click while one resolve is in flight is ignored rather than starting a second request.
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## Stats: raw-sample statistics (6.9.0)
|
|
496
|
+
|
|
497
|
+
`import 'apexcharts/features/stats'`
|
|
498
|
+
|
|
499
|
+
Free. The statistics behind three things, kept out of core so they cost nothing unless used:
|
|
500
|
+
|
|
501
|
+
- **Histogram binning**: `chart.type: 'histogram'` bins raw observations (the `apexcharts/histogram` entry includes this feature automatically).
|
|
502
|
+
- **Raw samples for boxPlot and violin**: a datum supplying `points: [number]` instead of a summary `y` gets its quartiles (R type 7) or KDE density computed.
|
|
503
|
+
- **`chart.rowSeries(opts?)`**: returns the rows behind the chart's marks as a unit-chart series (one cluster per mark), or `null` when the type has no row source. `chart.updateOptions({ chart: { type: 'unit' }, series: chart.rowSeries() })` opens a summary into its observations; with the `morph` feature loaded each dot leaves from the part of the mark that stood for it.
|
|
504
|
+
|
|
505
|
+
Full data shapes and options are in `references/financial-charts.md`. The full `apexcharts` bundle includes it.
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
## Point annotation tooltips (6.7.0)
|
|
510
|
+
|
|
511
|
+
`import 'apexcharts/features/annotations'` (free, part of the standard annotations module)
|
|
512
|
+
|
|
513
|
+
A point annotation can now show its own hover tooltip, so an annotated marker carries explanatory text without a separate custom element. Add `tooltip` to any entry in `annotations.points`:
|
|
514
|
+
|
|
515
|
+
```js
|
|
516
|
+
const options = {
|
|
517
|
+
annotations: {
|
|
518
|
+
points: [{
|
|
519
|
+
x: 'Mar',
|
|
520
|
+
y: 62,
|
|
521
|
+
marker: { size: 6, fillColor: '#FF4560' },
|
|
522
|
+
label: { text: 'Peak' },
|
|
523
|
+
tooltip: {
|
|
524
|
+
enabled: true,
|
|
525
|
+
text: 'All-time high: 62', // string, or an array joined with line breaks; falls back to label.text
|
|
526
|
+
// formatter: (opts) => `<b>${opts.annotation.label.text}</b>` // HTML, takes precedence over text
|
|
527
|
+
},
|
|
528
|
+
}],
|
|
529
|
+
},
|
|
530
|
+
}
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
`tooltip.formatter` receives `{ annotation, seriesIndex, id, ... }` and returns HTML.
|
|
534
|
+
|
|
424
535
|
---
|
|
425
536
|
|
|
426
537
|
## Common Pitfalls
|