apexcharts-skill 1.2.2 → 2.0.1
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/.cursorrules +40 -13
- package/README.md +9 -5
- package/SKILL.md +102 -22
- package/index.js +1 -0
- package/package.json +1 -1
- package/references/bar-charts.md +44 -0
- package/references/circular-charts.md +51 -1
- package/references/financial-charts.md +58 -1
- package/references/ssr.md +52 -37
- package/references/tree-shaking.md +19 -3
- package/references/v6-features.md +432 -0
package/.cursorrules
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# ApexCharts.js — AI Coding Rules
|
|
2
2
|
|
|
3
|
-
You are working with ApexCharts.js, a JavaScript charting library.
|
|
3
|
+
You are working with ApexCharts.js (v6), a JavaScript charting library.
|
|
4
4
|
Documentation: https://apexcharts.com/docs/
|
|
5
5
|
NPM: apexcharts
|
|
6
6
|
GitHub: https://github.com/apexcharts/apexcharts.js
|
|
7
7
|
|
|
8
|
+
v6 is backward compatible: existing v5 configs keep working. New chart types (violin, funnel, pyramid, gauge) and the feature platform (plugins, canvas renderer, custom series, undo/redo, shareable views, themes, crossfilter, annotation authoring, storyboard, streaming, drilldown) are opt-in and tree-shakeable. Two behaviors changed on by default (both respect prefers-reduced-motion): coherent add/remove data-transition animations, and mobile pinch-zoom / two-finger pan.
|
|
9
|
+
|
|
8
10
|
## Framework wrapper detection — check `package.json` first
|
|
9
11
|
|
|
10
12
|
- `react` → use **`react-apexcharts`** instead of the core API.
|
|
@@ -27,6 +29,9 @@ Wrappers handle `destroy()` automatically on unmount, accept reactive props, and
|
|
|
27
29
|
10. **RadialBar values must be 0–100** (percentages).
|
|
28
30
|
11. **Color hex values must include `#`** (e.g., `'#FF5733'`).
|
|
29
31
|
12. **Tree-shaking**: `apexcharts/core` requires separate chart-type + feature imports.
|
|
32
|
+
13. **v6 aliases**: `funnel`/`pyramid` render through bar, `gauge` through radialBar. Use them as `chart.type` directly (no `plotOptions.bar.isFunnel`); covered by `apexcharts/bar` and `apexcharts/radialBar`.
|
|
33
|
+
14. **`violin`** points use a density profile: `data: [{ x, y: { density: [[value, weight], ...], points?: [num] } }]`.
|
|
34
|
+
15. **`render()` is idempotent (v6)**: a repeated `render()` returns the same promise; still `destroy()` before a new instance on the same element.
|
|
30
35
|
|
|
31
36
|
---
|
|
32
37
|
|
|
@@ -45,9 +50,12 @@ Wrappers handle `destroy()` automatically on unmount, accept reactive props, and
|
|
|
45
50
|
| Range Bar | `'rangeBar'` | `[{ data: [{ x, y: [start, end] }] }]` | `[{ data: [{ x: 'Task', y: [1, 5] }] }]` |
|
|
46
51
|
| Candlestick | `'candlestick'` | `[{ data: [{ x, y: [O,H,L,C] }] }]` — 4 values | `[{ data: [{ x: new Date(), y: [51,56,48,53] }] }]` |
|
|
47
52
|
| Box Plot | `'boxPlot'` | `[{ data: [{ x, y: [min,Q1,med,Q3,max] }] }]` — 5 values | `[{ data: [{ x: 'A', y: [10,20,30,40,50] }] }]` |
|
|
53
|
+
| Violin *(v6)* | `'violin'` | `[{ name, data: [{ x, y: { density: [[value,weight],...], points?: [num] } }] }]` | `[{ data: [{ x: 'A', y: { density: [[20,0.1],[30,0.2]], points: [21,29] } }] }]` |
|
|
48
54
|
| Heatmap | `'heatmap'` | `[{ name, data: [{ x, y: number }] }]` — y is intensity | `[{ name: 'Mon', data: [{ x: '10am', y: 45 }] }]` |
|
|
49
55
|
| Treemap | `'treemap'` | `[{ data: [{ x, y: number }] }]` — y is area value | `[{ data: [{ x: 'Item', y: 100 }] }]` |
|
|
50
56
|
| Radar | `'radar'` | `[{ name, data: [num] }]` + `xaxis.categories` | `[{ data: [80, 50, 30] }]` |
|
|
57
|
+
| Funnel *(v6)* | `'funnel'` | `[{ name, data: [num] }]` + `xaxis.categories`; order largest→smallest | `[{ data: [1380, 990, 548, 200] }]` |
|
|
58
|
+
| Pyramid *(v6)* | `'pyramid'` | Same as funnel; order smallest→largest | `[{ data: [200, 548, 990, 1380] }]` |
|
|
51
59
|
|
|
52
60
|
### Non-Axis Charts (flat number array — NOT object format)
|
|
53
61
|
|
|
@@ -57,6 +65,9 @@ Wrappers handle `destroy()` automatically on unmount, accept reactive props, and
|
|
|
57
65
|
|
|
58
66
|
// Radial Bar (values 0–100)
|
|
59
67
|
{ chart: { type: 'radialBar' }, series: [76, 67, 61], labels: ['X', 'Y', 'Z'] }
|
|
68
|
+
|
|
69
|
+
// Gauge (v6): single value; domain via plotOptions.radialBar.min/max
|
|
70
|
+
{ chart: { type: 'gauge' }, series: [72], labels: ['Progress'] }
|
|
60
71
|
```
|
|
61
72
|
|
|
62
73
|
---
|
|
@@ -86,10 +97,11 @@ chart.destroy() // cleanup
|
|
|
86
97
|
apexcharts # Full bundle (all types + features)
|
|
87
98
|
apexcharts/core # Bare core (must register types + features manually)
|
|
88
99
|
apexcharts/line # line, area, scatter, bubble, rangeArea
|
|
89
|
-
apexcharts/bar # bar, column, rangeBar
|
|
100
|
+
apexcharts/bar # bar, column, rangeBar, funnel, pyramid (v6 aliases)
|
|
90
101
|
apexcharts/candlestick # candlestick, boxPlot
|
|
102
|
+
apexcharts/violin # violin (v6)
|
|
91
103
|
apexcharts/pie # pie, donut, polarArea
|
|
92
|
-
apexcharts/radialBar # radialBar
|
|
104
|
+
apexcharts/radialBar # radialBar, gauge (v6 alias)
|
|
93
105
|
apexcharts/radar # radar
|
|
94
106
|
apexcharts/heatmap # heatmap
|
|
95
107
|
apexcharts/treemap # treemap
|
|
@@ -97,13 +109,28 @@ apexcharts/ssr # Server-side rendering (Node.js)
|
|
|
97
109
|
apexcharts/client # Explicit browser import
|
|
98
110
|
|
|
99
111
|
# Optional features (side-effect imports)
|
|
100
|
-
apexcharts/features/exports
|
|
101
|
-
apexcharts/features/legend
|
|
102
|
-
apexcharts/features/toolbar
|
|
103
|
-
apexcharts/features/annotations
|
|
104
|
-
apexcharts/features/keyboard
|
|
105
|
-
|
|
112
|
+
apexcharts/features/exports # dataURI(), exportToCSV()
|
|
113
|
+
apexcharts/features/legend # Legend component
|
|
114
|
+
apexcharts/features/toolbar # Zoom, pan, download
|
|
115
|
+
apexcharts/features/annotations # X/Y/point annotations
|
|
116
|
+
apexcharts/features/keyboard # Keyboard navigation
|
|
117
|
+
# v6 feature platform (all opt-in):
|
|
118
|
+
apexcharts/features/morph # animated chart-type morphs
|
|
119
|
+
apexcharts/features/drilldown # hierarchical drill-down
|
|
120
|
+
apexcharts/features/history # undo/redo (Rewind)
|
|
121
|
+
apexcharts/features/perspectives # shareable view state
|
|
122
|
+
apexcharts/features/storyboard # scrollytelling
|
|
123
|
+
apexcharts/features/facet # design tokens + OS themes
|
|
124
|
+
apexcharts/features/weave # plugin platform
|
|
125
|
+
apexcharts/features/renderer-canvas # hybrid SVG + canvas renderer (Strata)
|
|
126
|
+
apexcharts/features/marks # custom series types (registerSeriesType)
|
|
127
|
+
apexcharts/features/link # crossfilter / linked views
|
|
128
|
+
apexcharts/features/ink # on-chart annotation authoring
|
|
129
|
+
apexcharts/features/measure # measure / delta ruler
|
|
130
|
+
apexcharts/features/context-menu # right-click context menu
|
|
131
|
+
apexcharts/features/all # All features
|
|
106
132
|
```
|
|
133
|
+
(Cadence easing and real-time streaming are core: no feature import needed.)
|
|
107
134
|
|
|
108
135
|
---
|
|
109
136
|
|
|
@@ -223,10 +250,10 @@ apexcharts/features/all # All features
|
|
|
223
250
|
|
|
224
251
|
| Method | Description |
|
|
225
252
|
|---|---|
|
|
226
|
-
| `ApexCharts.renderToString(opts)` | SVG string (server). |
|
|
227
|
-
| `ApexCharts.renderToHTML(opts)` | HTML wrapper + SVG (server). |
|
|
228
|
-
| `ApexCharts.hydrate(el)` | Hydrate SSR chart (client). |
|
|
229
|
-
| `ApexCharts.hydrateAll()` | Hydrate all SSR charts. |
|
|
253
|
+
| `ApexCharts.renderToString(opts, { width, height })` | SVG string (server). |
|
|
254
|
+
| `ApexCharts.renderToHTML(opts, { width, height })` | HTML wrapper + SVG (server). |
|
|
255
|
+
| `ApexCharts.hydrate(el, clientOpts?)` | Hydrate SSR chart (client). |
|
|
256
|
+
| `ApexCharts.hydrateAll(selector?)` | Hydrate all SSR charts. |
|
|
230
257
|
|
|
231
258
|
---
|
|
232
259
|
|
package/README.md
CHANGED
|
@@ -16,11 +16,14 @@ AI coding skill for building [ApexCharts.js](https://apexcharts.com/) charts and
|
|
|
16
16
|
|
|
17
17
|
AI models frequently generate incorrect ApexCharts code — wrong series data formats, missing `render()` calls, broken formatter signatures, etc. This skill provides structured reference files that help AI assistants generate correct ApexCharts code on the first try.
|
|
18
18
|
|
|
19
|
+
This skill targets **ApexCharts v6** (backward compatible with v5 configs).
|
|
20
|
+
|
|
19
21
|
### Coverage
|
|
20
22
|
|
|
21
|
-
- **
|
|
23
|
+
- **20 chart types**: line, area, bar, pie, donut, radialBar, scatter, bubble, heatmap, candlestick, boxPlot, violin, radar, polarArea, rangeBar, rangeArea, treemap, funnel, pyramid, gauge
|
|
22
24
|
- **Correct data formats** for every chart type
|
|
23
|
-
- **
|
|
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
|
|
24
27
|
- **Tree-shaking** and bundle optimization patterns
|
|
25
28
|
- **SSR** (server-side rendering) and hydration
|
|
26
29
|
- **Framework integration**: React, Vue 3, Angular
|
|
@@ -76,11 +79,12 @@ const barCharts = await readFile(referencePath('bar-charts.md'), 'utf8');
|
|
|
76
79
|
├── .cursorrules # Self-contained version for Cursor/Windsurf
|
|
77
80
|
├── references/
|
|
78
81
|
│ ├── cartesian-charts.md # line, area, scatter, bubble, rangeArea
|
|
79
|
-
│ ├── bar-charts.md # bar, column, rangeBar, timeline/Gantt
|
|
80
|
-
│ ├── financial-charts.md # candlestick, boxPlot
|
|
81
|
-
│ ├── circular-charts.md # pie, donut, polarArea, radialBar
|
|
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
|
|
82
85
|
│ ├── grid-charts.md # heatmap, treemap
|
|
83
86
|
│ ├── radar-charts.md # radar
|
|
87
|
+
│ ├── v6-features.md # v6 feature platform (plugins, canvas, undo/redo, themes, ...)
|
|
84
88
|
│ ├── tree-shaking.md # bundle optimization
|
|
85
89
|
│ ├── ssr.md # server-side rendering
|
|
86
90
|
│ └── framework-wrappers.md # React, Vue, Angular
|
package/SKILL.md
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: apexcharts
|
|
3
3
|
description: >
|
|
4
|
-
AI skill for building ApexCharts.js charts and data visualizations.
|
|
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
|
-
radar, polarArea, rangeBar, rangeArea, treemap). Covers
|
|
8
|
-
formatters, tree-shaking, SSR, and
|
|
7
|
+
violin, radar, polarArea, rangeBar, rangeArea, treemap, funnel, pyramid, gauge). Covers
|
|
8
|
+
correct data formats, lifecycle, formatters, tree-shaking, SSR, and the v6 feature
|
|
9
|
+
platform (plugins, canvas renderer, custom series, undo/redo, shareable views, themes,
|
|
10
|
+
crossfilter, annotation authoring, storyboard, streaming, drilldown). In React /
|
|
9
11
|
Vue / Angular projects, prefer the framework wrapper packages
|
|
10
12
|
(`react-apexcharts`, `vue3-apexcharts`, `ng-apexcharts`) over the core API.
|
|
11
13
|
metadata:
|
|
12
14
|
author: ApexCharts
|
|
13
|
-
version: "
|
|
14
|
-
library_version: "
|
|
15
|
+
version: "2.0.1"
|
|
16
|
+
library_version: "6.2.0"
|
|
15
17
|
category: data-visualization
|
|
16
18
|
tags: [charts, visualization, javascript, typescript, svg, apexcharts]
|
|
17
19
|
docs: https://apexcharts.com/docs/
|
|
@@ -28,6 +30,8 @@ metadata:
|
|
|
28
30
|
>
|
|
29
31
|
> 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`.
|
|
30
32
|
|
|
33
|
+
> **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.
|
|
34
|
+
|
|
31
35
|
## 1. Critical Rules
|
|
32
36
|
|
|
33
37
|
1. **Always call `chart.render()`** after `new ApexCharts(el, options)`. The constructor does not render.
|
|
@@ -42,6 +46,9 @@ metadata:
|
|
|
42
46
|
10. **RadialBar values must be 0–100** (they represent percentages).
|
|
43
47
|
11. **Color hex values must include the `#` prefix** (e.g., `'#FF5733'`, not `'FF5733'`).
|
|
44
48
|
12. **Tree-shaking**: importing `apexcharts/core` gives you a bare class — you must also import chart-type entries and feature entries separately.
|
|
49
|
+
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.
|
|
51
|
+
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.
|
|
45
52
|
|
|
46
53
|
---
|
|
47
54
|
|
|
@@ -62,23 +69,28 @@ This is the most critical reference. Using the wrong data format is the #1 cause
|
|
|
62
69
|
| Range Bar | `'rangeBar'` | `[{ name, data: [{ x, y: [start, end] }] }]` — for timeline/Gantt, use timestamps | `series: [{ name: 'Tasks', data: [{ x: 'Design', y: [1, 5] }] }]` |
|
|
63
70
|
| 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] }] }]` |
|
|
64
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] } }] }]` |
|
|
65
73
|
| Heatmap | `'heatmap'` | `[{ name, data: [{ x, y: number }] }]` — y is the intensity value | `series: [{ name: 'Mon', data: [{ x: '10am', y: 45 }] }]` |
|
|
66
74
|
| Treemap | `'treemap'` | `[{ data: [{ x, y: number }] }]` — y is the area/value | `series: [{ data: [{ x: 'Item A', y: 100 }, { x: 'Item B', y: 60 }] }]` |
|
|
67
75
|
| Radar | `'radar'` | `[{ name, data: [number] }]` + `xaxis: { categories: [...] }` | `series: [{ name: 'Skill', data: [80, 50, 30, 40, 100] }]` |
|
|
76
|
+
| Funnel *(v6)* | `'funnel'` | `[{ name, data: [number] }]` + `xaxis: { categories: [...] }`. Order values **largest→smallest**. | `series: [{ data: [1380, 990, 548, 200] }]` |
|
|
77
|
+
| Pyramid *(v6)* | `'pyramid'` | Same as funnel; order values **smallest→largest** (wide base at bottom). | `series: [{ data: [200, 548, 990, 1380] }]` |
|
|
68
78
|
|
|
69
|
-
### Non-Axis Charts (pie, donut, radialBar, polarArea)
|
|
79
|
+
### Non-Axis Charts (pie, donut, radialBar, polarArea, gauge)
|
|
70
80
|
|
|
71
81
|
These use a **flat number array** for `series`, NOT the object format:
|
|
72
82
|
|
|
73
83
|
```js
|
|
74
84
|
// CORRECT — flat number array + labels
|
|
75
85
|
{
|
|
76
|
-
chart: { type: 'pie' }, // or 'donut', 'polarArea', 'radialBar'
|
|
86
|
+
chart: { type: 'pie' }, // or 'donut', 'polarArea', 'radialBar', 'gauge'
|
|
77
87
|
series: [44, 55, 13, 43, 22],
|
|
78
88
|
labels: ['Team A', 'Team B', 'Team C', 'Team D', 'Team E']
|
|
79
89
|
}
|
|
80
90
|
```
|
|
81
91
|
|
|
92
|
+
**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
|
+
|
|
82
94
|
---
|
|
83
95
|
|
|
84
96
|
## 3. Package / Module Map
|
|
@@ -101,21 +113,37 @@ import ApexCharts from 'apexcharts/column' # same as /bar
|
|
|
101
113
|
import ApexCharts from 'apexcharts/rangeBar' # same as /bar
|
|
102
114
|
import ApexCharts from 'apexcharts/candlestick' # candlestick, boxPlot
|
|
103
115
|
import ApexCharts from 'apexcharts/boxPlot' # same as /candlestick
|
|
116
|
+
import ApexCharts from 'apexcharts/violin' # violin (v6)
|
|
104
117
|
import ApexCharts from 'apexcharts/pie' # pie, donut, polarArea
|
|
105
118
|
import ApexCharts from 'apexcharts/donut' # same as /pie
|
|
106
119
|
import ApexCharts from 'apexcharts/polarArea' # same as /pie
|
|
107
|
-
import ApexCharts from 'apexcharts/radialBar' # radialBar
|
|
120
|
+
import ApexCharts from 'apexcharts/radialBar' # radialBar + gauge (v6)
|
|
108
121
|
import ApexCharts from 'apexcharts/radar' # radar only
|
|
109
122
|
import ApexCharts from 'apexcharts/heatmap' # heatmap only
|
|
110
123
|
import ApexCharts from 'apexcharts/treemap' # treemap only
|
|
124
|
+
# funnel + pyramid (v6) render through the bar engine; use apexcharts/bar
|
|
111
125
|
|
|
112
126
|
# Optional features (side-effect imports — just import, no default export needed)
|
|
113
|
-
import 'apexcharts/features/exports'
|
|
114
|
-
import 'apexcharts/features/legend'
|
|
115
|
-
import 'apexcharts/features/toolbar'
|
|
116
|
-
import 'apexcharts/features/annotations'
|
|
117
|
-
import 'apexcharts/features/keyboard'
|
|
118
|
-
|
|
127
|
+
import 'apexcharts/features/exports' # PNG/SVG/CSV export methods
|
|
128
|
+
import 'apexcharts/features/legend' # Interactive legend component
|
|
129
|
+
import 'apexcharts/features/toolbar' # Toolbar (zoom, pan, download buttons)
|
|
130
|
+
import 'apexcharts/features/annotations' # X/Y/point/text/image annotations
|
|
131
|
+
import 'apexcharts/features/keyboard' # Keyboard navigation (accessibility)
|
|
132
|
+
# v6 feature platform (all opt-in, all tree-shakeable)
|
|
133
|
+
import 'apexcharts/features/morph' # Animated chart-type morphs
|
|
134
|
+
import 'apexcharts/features/drilldown' # Hierarchical drill-down
|
|
135
|
+
import 'apexcharts/features/history' # Undo/redo (Rewind)
|
|
136
|
+
import 'apexcharts/features/perspectives' # Shareable view state
|
|
137
|
+
import 'apexcharts/features/storyboard' # Scrollytelling (includes perspectives)
|
|
138
|
+
import 'apexcharts/features/facet' # Design tokens + OS-aware themes
|
|
139
|
+
import 'apexcharts/features/weave' # Public plugin platform
|
|
140
|
+
import 'apexcharts/features/renderer-canvas' # Hybrid SVG + canvas renderer (Strata)
|
|
141
|
+
import 'apexcharts/features/marks' # Custom series types (registerSeriesType)
|
|
142
|
+
import 'apexcharts/features/link' # Crossfilter / linked views
|
|
143
|
+
import 'apexcharts/features/ink' # On-chart annotation authoring
|
|
144
|
+
import 'apexcharts/features/measure' # Measure / delta ruler
|
|
145
|
+
import 'apexcharts/features/context-menu' # Right-click / long-press context menu
|
|
146
|
+
import 'apexcharts/features/all' # All features at once
|
|
119
147
|
|
|
120
148
|
# SSR (server-side rendering)
|
|
121
149
|
import ApexCharts from 'apexcharts/ssr' # Node.js: renderToString, renderToHTML
|
|
@@ -484,6 +512,19 @@ await chart.updateOptions({ title: { text: 'New Title' } })
|
|
|
484
512
|
| `addEventListener(name, handler)` | Subscribe to chart event. |
|
|
485
513
|
| `removeEventListener(name, handler)` | Unsubscribe from chart event. |
|
|
486
514
|
|
|
515
|
+
### v6 Instance Methods (require the matching feature import)
|
|
516
|
+
|
|
517
|
+
| Method | Feature | Description |
|
|
518
|
+
|---|---|---|
|
|
519
|
+
| `chart.history.undo() / redo() / jump(id) / transaction(fn)` | history | Undo/redo over the command journal. |
|
|
520
|
+
| `chart.perspectives.capture() / toURL() / apply(token)` | perspectives | Serialize / restore the exact view. |
|
|
521
|
+
| `chart.getActiveRenderer()` | renderer-canvas | Returns `'svg' \| 'canvas'` currently in use. |
|
|
522
|
+
| `chart.refreshTokens()` | facet | Re-read `--apx-*` CSS custom properties. |
|
|
523
|
+
| `chart.startMeasure() / stopMeasure() / clearMeasures()` | measure | Drive the measure ruler from code. |
|
|
524
|
+
| `chart.storyboard.bind({ beats }) / goTo() / unbind()` | storyboard | Scroll-driven choreography. |
|
|
525
|
+
| `chart.drillDown(id) / drillUp() / drillToRoot()` | drilldown | Navigate the drill-down hierarchy. |
|
|
526
|
+
| `chart.clearCrossfilter()` | link | Clear active crossfilter selections. |
|
|
527
|
+
|
|
487
528
|
### Static Methods
|
|
488
529
|
|
|
489
530
|
| Method | Description |
|
|
@@ -493,15 +534,21 @@ await chart.updateOptions({ title: { text: 'New Title' } })
|
|
|
493
534
|
| `ApexCharts.merge(target, source)` | Deep-merge objects. |
|
|
494
535
|
| `ApexCharts.use(typeMap)` | Register chart type constructors (tree-shaking). |
|
|
495
536
|
| `ApexCharts.registerFeatures(featureMap)` | Register optional feature modules. |
|
|
537
|
+
| `ApexCharts.registerPlugin(def) / unregisterPlugin(name)` | *(v6, Weave)* Register a reusable plugin. |
|
|
538
|
+
| `ApexCharts.registerSeriesType(name, def) / unregisterSeriesType(name)` | *(v6, Marks)* Register a custom series type. |
|
|
539
|
+
| `ApexCharts.registerTheme(name, def) / unregisterTheme(name)` | *(v6, Facet)* Register a named brand theme. |
|
|
540
|
+
| `ApexCharts.registerEasing(name, fn)` | *(v6, Cadence)* Register a custom easing curve. |
|
|
541
|
+
| `ApexCharts.crossfilter({ id, records }) / getCrossfilter(id)` | *(v6, Link)* Create / fetch a crossfilter engine. |
|
|
542
|
+
| `ApexCharts.perspectives.fromURL(href)` | *(v6)* Decode a perspective token from a URL. |
|
|
496
543
|
|
|
497
544
|
### SSR Static Methods (available with `apexcharts/ssr`)
|
|
498
545
|
|
|
499
546
|
| Method | Description |
|
|
500
547
|
|---|---|
|
|
501
|
-
| `ApexCharts.renderToString(options)` | Render chart to SVG string (Node.js). |
|
|
502
|
-
| `ApexCharts.renderToHTML(options)` | Render
|
|
503
|
-
| `ApexCharts.hydrate(element)` | Hydrate server-rendered chart (browser). |
|
|
504
|
-
| `ApexCharts.hydrateAll()` | Hydrate all server-rendered charts on page. |
|
|
548
|
+
| `ApexCharts.renderToString(options, { width, height, scale })` | Render chart to raw SVG string (Node.js). |
|
|
549
|
+
| `ApexCharts.renderToHTML(options, { width, height, scale, className })` | Render hydration-ready HTML string (Node.js). |
|
|
550
|
+
| `ApexCharts.hydrate(element, clientOptions?)` | Hydrate a server-rendered chart (browser). |
|
|
551
|
+
| `ApexCharts.hydrateAll(selector?, clientOptions?)` | Hydrate all server-rendered charts on page. |
|
|
505
552
|
| `ApexCharts.isHydrated(element)` | Check if element is already hydrated. |
|
|
506
553
|
|
|
507
554
|
---
|
|
@@ -537,6 +584,17 @@ await chart.updateOptions({ title: { text: 'New Title' } })
|
|
|
537
584
|
beforeResetZoom: (chart, options) => {}, // return false to cancel
|
|
538
585
|
scrolled: (chart, { xaxis }) => {},
|
|
539
586
|
selection: (chart, { xaxis, yaxis }) => {},
|
|
587
|
+
|
|
588
|
+
// v6 feature events (fire only when the matching feature is enabled)
|
|
589
|
+
annotationDragged: (chart, options) => {}, // ink
|
|
590
|
+
annotationEdited: (chart, options) => {}, // ink
|
|
591
|
+
annotationStyled: (chart, options) => {}, // ink
|
|
592
|
+
annotationDeleted: (chart, options) => {}, // ink
|
|
593
|
+
measured: (chart, { from, to, dx, dy, percentChange, slope }) => {}, // measure
|
|
594
|
+
beatChange: (chart, beatInfo) => {}, // storyboard
|
|
595
|
+
drillDownStart: (info, chart, options) => {},// drilldown
|
|
596
|
+
drillDownEnd: (info, chart, options) => {}, // drilldown
|
|
597
|
+
drillUp: (info, chart, options) => {}, // drilldown
|
|
540
598
|
}
|
|
541
599
|
}
|
|
542
600
|
}
|
|
@@ -544,18 +602,40 @@ await chart.updateOptions({ title: { text: 'New Title' } })
|
|
|
544
602
|
|
|
545
603
|
---
|
|
546
604
|
|
|
547
|
-
## 9.
|
|
605
|
+
## 9. v6 Feature Platform (opt-in, tree-shakeable)
|
|
606
|
+
|
|
607
|
+
All of the following are new in v6, off by default, and each ships as a `apexcharts/features/*` entry. Full config shapes, APIs, and examples are in `references/v6-features.md`. Quick map:
|
|
608
|
+
|
|
609
|
+
| Feature | Opt-in | One-liner |
|
|
610
|
+
|---|---|---|
|
|
611
|
+
| **Weave** (plugins) | `apexcharts/features/weave` | Publish reusable chart plugins against a stable `ApexCharts.registerPlugin({ name, setup })` API; activate per chart with `plugins: [{ name }]`. |
|
|
612
|
+
| **Strata** (canvas) | `apexcharts/features/renderer-canvas` | `chart: { renderer: 'auto', rendererThreshold }` paints the dense series layer to canvas while axes/tooltips/exports stay SVG. |
|
|
613
|
+
| **Marks** (custom series) | `apexcharts/features/marks` | `ApexCharts.registerSeriesType(name, { renderItem })` for first-class custom marks (lollipop, dumbbell, bullet). Baseline is `scales.y(0)`, **not** `api.zeroY`. |
|
|
614
|
+
| **Rewind** (undo/redo) | `apexcharts/features/history` | `chart: { history: { enabled: true } }`, then `chart.history.undo()/redo()/jump()/transaction()`. |
|
|
615
|
+
| **Perspectives** (view state) | `apexcharts/features/perspectives` | `chart.perspectives.capture()/toURL()/apply()` to serialize and restore the exact view. |
|
|
616
|
+
| **Facet** (themes/tokens) | `apexcharts/features/facet` | `theme: { follow: 'os', name }`, `--apx-*` CSS custom props, `ApexCharts.registerTheme`. |
|
|
617
|
+
| **Cadence** (easing) | core | `chart.animations.easing` accepts a named curve, cubic-bezier array, or function; `ApexCharts.registerEasing`. |
|
|
618
|
+
| **Link** (crossfilter) | `apexcharts/features/link` | `chart: { group, link: { enabled, mode } }` for highlight linking; `ApexCharts.crossfilter({ id, records })` for a filter engine. |
|
|
619
|
+
| **Ink** (annotation authoring) | `apexcharts/features/ink` | `chart: { ink: { enabled: true } }` makes annotations draggable/resizable with a floating editor. |
|
|
620
|
+
| **Measure** (ruler) | `apexcharts/features/measure` | `chart: { measure: { enabled, mode } }`; hold a key and drag to read change/percent/slope. v6.1 adds a toolbar tool (`toolbar.tools.measure`, `toolbar.autoSelected: 'measure'`). |
|
|
621
|
+
| **Context menu** | `apexcharts/features/context-menu` | `chart: { contextMenu: { enabled, items } }` for point-specific right-click actions. |
|
|
622
|
+
| **Storyboard** (scrollytelling) | `apexcharts/features/storyboard` | `chart.storyboard.bind({ beats })` pairs prose sections with saved views. |
|
|
623
|
+
| **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()`. |
|
|
625
|
+
|
|
626
|
+
## 10. Reference Routing Table
|
|
548
627
|
|
|
549
628
|
For detailed chart-family-specific options, data format variants, and full working examples, refer to:
|
|
550
629
|
|
|
551
630
|
| Topic | Reference File |
|
|
552
631
|
|---|---|
|
|
553
632
|
| Line, Area, Scatter, Bubble, Range Area | `references/cartesian-charts.md` |
|
|
554
|
-
| Bar, Column, Range Bar, Timeline/Gantt | `references/bar-charts.md` |
|
|
555
|
-
| Candlestick, Box Plot | `references/financial-charts.md` |
|
|
556
|
-
| Pie, Donut, Polar Area, Radial Bar | `references/circular-charts.md` |
|
|
633
|
+
| 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` |
|
|
557
636
|
| Heatmap, Treemap | `references/grid-charts.md` |
|
|
558
637
|
| Radar | `references/radar-charts.md` |
|
|
638
|
+
| v6 feature platform (plugins, canvas, undo/redo, themes, crossfilter, storyboard, ...) | `references/v6-features.md` |
|
|
559
639
|
| Tree-shaking, Bundle optimization | `references/tree-shaking.md` |
|
|
560
640
|
| Server-side rendering, Hydration | `references/ssr.md` |
|
|
561
641
|
| React, Vue, Angular integration | `references/framework-wrappers.md` |
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apexcharts-skill",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
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
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
- **Column** (`'bar'`) — Vertical column chart (the default for `type: 'bar'`)
|
|
6
6
|
- **Bar** (`'bar'` + `plotOptions.bar.horizontal: true`) — Horizontal bar chart
|
|
7
7
|
- **Range Bar** (`'rangeBar'`) — Bars with start/end values (used for timelines, Gantt charts)
|
|
8
|
+
- **Funnel** (`'funnel'`, **new in v6**): Stage-by-stage drop-off chart
|
|
9
|
+
- **Pyramid** (`'pyramid'`, **new in v6**): A funnel with the wide base at the bottom
|
|
8
10
|
|
|
9
11
|
## Tree-Shakeable Import
|
|
10
12
|
|
|
@@ -12,8 +14,11 @@
|
|
|
12
14
|
import ApexCharts from 'apexcharts/bar'
|
|
13
15
|
// Registers: bar, column, rangeBar
|
|
14
16
|
// Aliases: apexcharts/column, apexcharts/rangeBar
|
|
17
|
+
// Also covers funnel + pyramid (they normalize to the bar engine in v6)
|
|
15
18
|
```
|
|
16
19
|
|
|
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
|
+
|
|
17
22
|
---
|
|
18
23
|
|
|
19
24
|
## Data Formats
|
|
@@ -140,6 +145,43 @@ import ApexCharts from 'apexcharts/bar'
|
|
|
140
145
|
}
|
|
141
146
|
```
|
|
142
147
|
|
|
148
|
+
### Funnel (v6)
|
|
149
|
+
|
|
150
|
+
Values are a flat number array in the standard `[{ name, data }]` wrapper; stage labels go in `xaxis.categories`. Order values **largest → smallest**.
|
|
151
|
+
|
|
152
|
+
```js
|
|
153
|
+
{
|
|
154
|
+
chart: { type: 'funnel', height: 350 },
|
|
155
|
+
series: [{ name: 'Recruitment', data: [1380, 1100, 990, 880, 740, 548, 330, 200] }],
|
|
156
|
+
xaxis: { categories: ['Sourced', 'Screened', 'Assessed', 'HR', 'Technical', 'Verify', 'Offered', 'Hired'] },
|
|
157
|
+
plotOptions: {
|
|
158
|
+
// shape: 'rectangle' (default, centered rectangles) | 'trapezoid' (continuous sloped sides)
|
|
159
|
+
funnel: { shape: 'trapezoid', lastShape: 'flat' }, // lastShape: 'flat' | 'taper' (trapezoid only)
|
|
160
|
+
bar: { borderRadius: 0, barHeight: '80%' } // cosmetic bar props still apply
|
|
161
|
+
},
|
|
162
|
+
dataLabels: {
|
|
163
|
+
enabled: true,
|
|
164
|
+
formatter: (val, opt) => opt.w.globals.labels[opt.dataPointIndex] + ': ' + val
|
|
165
|
+
},
|
|
166
|
+
legend: { show: false }
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Pyramid (v6)
|
|
171
|
+
|
|
172
|
+
Same shape as funnel, but order values **smallest → largest** so the wide base sits at the bottom.
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
{
|
|
176
|
+
chart: { type: 'pyramid', height: 350 },
|
|
177
|
+
series: [{ name: '', data: [200, 330, 548, 740, 880, 990, 1100, 1380] }],
|
|
178
|
+
xaxis: { categories: ['Sweets', 'Processed', 'Fats', 'Meat', 'Legumes', 'Dairy', 'Produce', 'Grains'] },
|
|
179
|
+
plotOptions: { bar: { distributed: true } }, // one color per stage
|
|
180
|
+
dataLabels: { enabled: true, formatter: (val, opt) => opt.w.globals.labels[opt.dataPointIndex] },
|
|
181
|
+
legend: { show: false }
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
143
185
|
---
|
|
144
186
|
|
|
145
187
|
## Key plotOptions.bar Options
|
|
@@ -242,3 +284,5 @@ series: [{
|
|
|
242
284
|
3. **Range Bar with single value instead of array** — `y` must be `[start, end]`, not a single number.
|
|
243
285
|
4. **Timeline without `xaxis.type: 'datetime'`** — date-based range bars need `xaxis: { type: 'datetime' }` to render correctly.
|
|
244
286
|
5. **`distributed: true` with multiple series** — distributed coloring applies to each data point independently. With multiple series, each point gets a unique color which is usually not desired. Use `distributed: true` only with single-series charts.
|
|
287
|
+
6. **Funnel/pyramid value ordering**: funnel expects values ordered largest-to-smallest and pyramid smallest-to-largest. The renderer does not sort for you; unsorted data produces a jagged shape. Stage labels come from `xaxis.categories`, and per-stage labels in `dataLabels.formatter` are read via `opt.w.globals.labels[opt.dataPointIndex]`.
|
|
288
|
+
7. **Reaching for `plotOptions.bar.isFunnel` in v6**: unnecessary. Set `chart.type: 'funnel'` (or `'pyramid'`) and use `plotOptions.funnel` for shape options.
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
- **Pie** (`'pie'`) — Standard pie chart
|
|
6
6
|
- **Donut** (`'donut'`) — Pie chart with hollow center
|
|
7
7
|
- **Polar Area** (`'polarArea'`) — Radial segments with equal angles, varying radius
|
|
8
|
-
- **Radial Bar** (`'radialBar'`)
|
|
8
|
+
- **Radial Bar** (`'radialBar'`): Circular progress chart (one or more concentric tracks)
|
|
9
|
+
- **Gauge** (`'gauge'`, **new in v6**): Single-value gauge with arc/needle shapes, colored bands, and ticks
|
|
9
10
|
|
|
10
11
|
## Tree-Shakeable Import
|
|
11
12
|
|
|
@@ -16,6 +17,7 @@ import ApexCharts from 'apexcharts/pie'
|
|
|
16
17
|
|
|
17
18
|
import ApexCharts from 'apexcharts/radialBar'
|
|
18
19
|
// Registers: radialBar (separate entry point)
|
|
20
|
+
// Also covers gauge (it normalizes to the radialBar engine in v6)
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
---
|
|
@@ -46,6 +48,52 @@ import ApexCharts from 'apexcharts/radialBar'
|
|
|
46
48
|
|
|
47
49
|
**Important:** RadialBar values represent percentages (0–100). Values above 100 will overflow the track.
|
|
48
50
|
|
|
51
|
+
### Gauge (v6)
|
|
52
|
+
|
|
53
|
+
A gauge is a single-value `radialBar` alias. Series is a flat one-element array; the value maps to the `min..max` domain (defaults 0-100). All configuration lives under `plotOptions.radialBar`; there is **no `plotOptions.gauge`**.
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
// Minimal gauge:
|
|
57
|
+
{
|
|
58
|
+
chart: { type: 'gauge', height: 350 },
|
|
59
|
+
series: [72],
|
|
60
|
+
labels: ['Progress']
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
// Needle gauge with colored bands and ticks:
|
|
66
|
+
{
|
|
67
|
+
chart: { type: 'gauge', height: 360 },
|
|
68
|
+
series: [68],
|
|
69
|
+
labels: ['Speed'],
|
|
70
|
+
plotOptions: {
|
|
71
|
+
radialBar: {
|
|
72
|
+
shape: 'needle', // 'arc' (default, filled value-arc) | 'needle' (rotating pointer)
|
|
73
|
+
startAngle: -135, endAngle: 135,
|
|
74
|
+
min: 0, max: 100, // value-to-angle domain
|
|
75
|
+
bands: [ // colored threshold segments in the min..max domain
|
|
76
|
+
{ from: 0, to: 30, color: '#FF4560' },
|
|
77
|
+
{ from: 30, to: 70, color: '#FEB019' },
|
|
78
|
+
{ from: 70, to: 100, color: '#00E396' }
|
|
79
|
+
],
|
|
80
|
+
bandsStyle: { strokeWidth: '50%', gap: 1 },
|
|
81
|
+
ticks: {
|
|
82
|
+
show: true,
|
|
83
|
+
major: { count: 11, length: 8, width: 2, color: '#334155', placement: 'outside' },
|
|
84
|
+
minor: { count: 1, length: 4, width: 1, color: '#94A3B8', placement: 'outside' },
|
|
85
|
+
labels: { show: true, offset: 6, fontSize: '11px' }
|
|
86
|
+
},
|
|
87
|
+
needle: { color: '#0F172A', length: '60%', baseWidth: 6, tipWidth: 1 },
|
|
88
|
+
hollow: { size: '70%' },
|
|
89
|
+
dataLabels: { name: { show: false }, value: { offsetY: 32, fontSize: '28px', fontWeight: 700 } }
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
A plain radialBar is effectively a gauge with `shape: 'arc'`. A semi-circle gauge is `startAngle: -90, endAngle: 90`.
|
|
96
|
+
|
|
49
97
|
---
|
|
50
98
|
|
|
51
99
|
## Key plotOptions
|
|
@@ -216,3 +264,5 @@ plotOptions: {
|
|
|
216
264
|
4. **Donut center labels not showing** — must set `plotOptions.pie.donut.labels.show: true` explicitly.
|
|
217
265
|
5. **`total.formatter` signature** — receives `w` (the full chart config object), NOT a simple value. Access `w.globals.seriesTotals` for the array of current values.
|
|
218
266
|
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
|
+
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
|
+
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.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
# Financial Charts Reference — ApexCharts
|
|
1
|
+
# Financial & Statistical Charts Reference — ApexCharts
|
|
2
2
|
|
|
3
3
|
## Chart Types Covered
|
|
4
4
|
|
|
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
|
+
- **Violin** (`'violin'`, **new in v6**): Statistical distribution chart showing a density curve per category, optionally with the raw sample points overlaid as jitter
|
|
7
8
|
|
|
8
9
|
## Tree-Shakeable Import
|
|
9
10
|
|
|
@@ -11,6 +12,9 @@
|
|
|
11
12
|
import ApexCharts from 'apexcharts/candlestick'
|
|
12
13
|
// Registers: candlestick, boxPlot
|
|
13
14
|
// Alias: apexcharts/boxPlot
|
|
15
|
+
|
|
16
|
+
import ApexCharts from 'apexcharts/violin'
|
|
17
|
+
// Registers: violin (separate entry point, new in v6)
|
|
14
18
|
```
|
|
15
19
|
|
|
16
20
|
---
|
|
@@ -68,6 +72,57 @@ The `y` value must be an array of exactly 5 numbers: `[min, Q1, median, Q3, max]
|
|
|
68
72
|
}
|
|
69
73
|
```
|
|
70
74
|
|
|
75
|
+
### Violin: Density Profile (v6)
|
|
76
|
+
|
|
77
|
+
Each point is `{ x, y: { density, points } }`:
|
|
78
|
+
|
|
79
|
+
- `density` (**required**): an array of `[value, weight]` pairs describing the precomputed density/KDE profile.
|
|
80
|
+
- `points` (optional): a flat array of raw observations, rendered as jitter dots.
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
{
|
|
84
|
+
chart: { type: 'violin', height: 420 },
|
|
85
|
+
series: [{
|
|
86
|
+
name: 'Session duration',
|
|
87
|
+
data: [
|
|
88
|
+
{
|
|
89
|
+
x: 'Direct',
|
|
90
|
+
y: {
|
|
91
|
+
density: [[20, 0.02], [30, 0.08], [40, 0.18], [50, 0.10], [60, 0.03]], // [value, weight]
|
|
92
|
+
points: [22, 31, 38, 41, 47, 52, 58] // raw observations
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
x: 'Referral',
|
|
97
|
+
y: {
|
|
98
|
+
density: [[25, 0.03], [35, 0.12], [45, 0.20], [55, 0.09], [65, 0.02]],
|
|
99
|
+
points: [27, 34, 44, 48, 53, 61]
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
}],
|
|
104
|
+
plotOptions: {
|
|
105
|
+
violin: {
|
|
106
|
+
bandwidthScale: 1, // multiplies the density-derived half-width
|
|
107
|
+
normalize: 'individual', // 'individual' (each violin to its own peak) | 'group' (shared scale)
|
|
108
|
+
points: { show: false } // set show:true to overlay the raw points as jitter
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Orientation and per-category color come from `plotOptions.bar`** (violin reuses the bar renderer):
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
plotOptions: {
|
|
118
|
+
bar: { horizontal: true, distributed: true }, // horizontal violins, one color each
|
|
119
|
+
violin: {
|
|
120
|
+
normalize: 'group',
|
|
121
|
+
points: { show: true, shape: 'circle', size: 3, jitter: 0.9, strokeWidth: 0 }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
71
126
|
---
|
|
72
127
|
|
|
73
128
|
## Key plotOptions
|
|
@@ -155,3 +210,5 @@ plotOptions: {
|
|
|
155
210
|
3. **Using simple numeric array** — `data: [10, 20, 30]` does NOT work for candlestick/boxPlot. Each point requires an array in `y`.
|
|
156
211
|
4. **Missing `xaxis.type: 'datetime'`** — candlestick charts with date x-values need `xaxis: { type: 'datetime' }` to format dates correctly.
|
|
157
212
|
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. The `density` profile is precomputed (ApexCharts does not run a KDE for you); `points` for the raw-sample jitter overlay is optional.
|
|
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`.
|
package/references/ssr.md
CHANGED
|
@@ -22,37 +22,43 @@ import ApexCharts from 'apexcharts/client'
|
|
|
22
22
|
|
|
23
23
|
## Server-Side API
|
|
24
24
|
|
|
25
|
-
### renderToString(options)
|
|
25
|
+
### renderToString(options, ssrOptions?)
|
|
26
26
|
|
|
27
|
-
Returns a raw SVG string suitable for embedding
|
|
27
|
+
Returns a raw SVG string suitable for embedding. Pass width/height in the **second** argument (SSR has no DOM to measure).
|
|
28
28
|
|
|
29
29
|
```js
|
|
30
30
|
import ApexCharts from 'apexcharts/ssr'
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
32
|
+
// renderToString(options, { width?, height?, scale? })
|
|
33
|
+
const svgString = await ApexCharts.renderToString(
|
|
34
|
+
{
|
|
35
|
+
chart: { type: 'line' },
|
|
36
|
+
series: [{ name: 'Sales', data: [30, 40, 35, 50] }],
|
|
37
|
+
xaxis: { categories: ['Q1', 'Q2', 'Q3', 'Q4'] }
|
|
38
|
+
},
|
|
39
|
+
{ width: 600, height: 350 }
|
|
40
|
+
)
|
|
37
41
|
|
|
38
42
|
// svgString is raw <svg>...</svg> markup
|
|
39
43
|
```
|
|
40
44
|
|
|
41
|
-
### renderToHTML(options)
|
|
45
|
+
### renderToHTML(options, ssrOptions?)
|
|
42
46
|
|
|
43
47
|
Returns an HTML string with a wrapper `<div>` containing the SVG, ready for hydration:
|
|
44
48
|
|
|
45
49
|
```js
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
// renderToHTML(options, { width?, height?, scale?, className? })
|
|
51
|
+
const htmlString = await ApexCharts.renderToHTML(
|
|
52
|
+
{
|
|
53
|
+
chart: {
|
|
54
|
+
type: 'bar',
|
|
55
|
+
id: 'my-chart' // id is important for hydration targeting
|
|
56
|
+
},
|
|
57
|
+
series: [{ data: [44, 55, 41, 67] }],
|
|
58
|
+
xaxis: { categories: ['A', 'B', 'C', 'D'] }
|
|
52
59
|
},
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
})
|
|
60
|
+
{ width: 600, height: 350 }
|
|
61
|
+
)
|
|
56
62
|
|
|
57
63
|
// htmlString is <div id="my-chart" data-apexcharts>...<svg>...</svg></div>
|
|
58
64
|
```
|
|
@@ -63,19 +69,19 @@ const htmlString = await ApexCharts.renderToHTML({
|
|
|
63
69
|
|
|
64
70
|
After the server-rendered HTML is in the DOM, hydrate it to make it interactive:
|
|
65
71
|
|
|
66
|
-
### hydrate(element)
|
|
72
|
+
### hydrate(element, clientOptions?)
|
|
67
73
|
|
|
68
74
|
```js
|
|
69
75
|
import ApexCharts from 'apexcharts'
|
|
70
76
|
|
|
71
|
-
// Hydrate a specific chart element
|
|
77
|
+
// Hydrate a specific chart element (optionally merge client-only options)
|
|
72
78
|
const chart = ApexCharts.hydrate(document.querySelector('#my-chart'))
|
|
73
79
|
```
|
|
74
80
|
|
|
75
|
-
### hydrateAll()
|
|
81
|
+
### hydrateAll(selector?, clientOptions?)
|
|
76
82
|
|
|
77
83
|
```js
|
|
78
|
-
// Hydrate all server-rendered charts on the page
|
|
84
|
+
// Hydrate all server-rendered charts on the page (optionally scope by selector)
|
|
79
85
|
ApexCharts.hydrateAll()
|
|
80
86
|
```
|
|
81
87
|
|
|
@@ -101,11 +107,14 @@ import ApexCharts from 'apexcharts/ssr'
|
|
|
101
107
|
const app = express()
|
|
102
108
|
|
|
103
109
|
app.get('/', async (req, res) => {
|
|
104
|
-
const chartHTML = await ApexCharts.renderToHTML(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
110
|
+
const chartHTML = await ApexCharts.renderToHTML(
|
|
111
|
+
{
|
|
112
|
+
chart: { type: 'line', id: 'sales-chart' },
|
|
113
|
+
series: [{ name: 'Sales', data: [30, 40, 35, 50, 49, 60] }],
|
|
114
|
+
xaxis: { categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'] }
|
|
115
|
+
},
|
|
116
|
+
{ width: 600, height: 350 }
|
|
117
|
+
)
|
|
109
118
|
|
|
110
119
|
res.send(`
|
|
111
120
|
<!DOCTYPE html>
|
|
@@ -136,11 +145,14 @@ app.listen(3000)
|
|
|
136
145
|
import ApexCharts from 'apexcharts/ssr'
|
|
137
146
|
|
|
138
147
|
export default async function Page() {
|
|
139
|
-
const chartHTML = await ApexCharts.renderToHTML(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
148
|
+
const chartHTML = await ApexCharts.renderToHTML(
|
|
149
|
+
{
|
|
150
|
+
chart: { type: 'line', id: 'my-chart' },
|
|
151
|
+
series: [{ data: [10, 20, 30] }],
|
|
152
|
+
xaxis: { categories: ['A', 'B', 'C'] }
|
|
153
|
+
},
|
|
154
|
+
{ width: 600, height: 350 }
|
|
155
|
+
)
|
|
144
156
|
|
|
145
157
|
return (
|
|
146
158
|
<>
|
|
@@ -176,11 +188,14 @@ export default function HydrateCharts() {
|
|
|
176
188
|
// Server-side
|
|
177
189
|
const chartHTML = await useAsyncData('chart', async () => {
|
|
178
190
|
const ApexCharts = (await import('apexcharts/ssr')).default
|
|
179
|
-
return await ApexCharts.renderToHTML(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
191
|
+
return await ApexCharts.renderToHTML(
|
|
192
|
+
{
|
|
193
|
+
chart: { type: 'bar', id: 'my-chart' },
|
|
194
|
+
series: [{ data: [44, 55, 41] }],
|
|
195
|
+
xaxis: { categories: ['A', 'B', 'C'] }
|
|
196
|
+
},
|
|
197
|
+
{ width: 600, height: 350 }
|
|
198
|
+
)
|
|
184
199
|
})
|
|
185
200
|
|
|
186
201
|
// Client-side hydration
|
|
@@ -197,5 +212,5 @@ onMounted(async () => {
|
|
|
197
212
|
|
|
198
213
|
1. **Using `apexcharts` in Node.js without SSR methods** — the default export auto-resolves based on environment, but `renderToString` is only available via `apexcharts/ssr`.
|
|
199
214
|
2. **Forgetting to hydrate on the client** — server-rendered charts are static SVGs. Without `hydrate()`, they have no interactivity (no tooltips, zoom, click events).
|
|
200
|
-
3. **Missing
|
|
215
|
+
3. **Missing width/height**: SSR has no DOM to measure. Pass explicit dimensions in the **second** argument: `renderToString(options, { width, height })` / `renderToHTML(options, { width, height })`.
|
|
201
216
|
4. **Hydrating before DOM is ready** — call `hydrate()` after the server-rendered HTML is in the DOM (use `onMounted`, `useEffect`, or `DOMContentLoaded`).
|
|
@@ -6,7 +6,7 @@ ApexCharts supports three import strategies with different bundle sizes:
|
|
|
6
6
|
|
|
7
7
|
| Strategy | Import | Includes |
|
|
8
8
|
|---|---|---|
|
|
9
|
-
| Full bundle | `import ApexCharts from 'apexcharts'` | All
|
|
9
|
+
| Full bundle | `import ApexCharts from 'apexcharts'` | All chart types + all features |
|
|
10
10
|
| Per-type entry | `import ApexCharts from 'apexcharts/line'` | Specific chart family + core (no optional features) |
|
|
11
11
|
| Bare core | `import ApexCharts from 'apexcharts/core'` | Core class only — must manually register everything |
|
|
12
12
|
|
|
@@ -28,14 +28,17 @@ Each entry point registers a family of related chart types:
|
|
|
28
28
|
| `apexcharts/rangeBar` | same as /bar |
|
|
29
29
|
| `apexcharts/candlestick` | candlestick, boxPlot |
|
|
30
30
|
| `apexcharts/boxPlot` | same as /candlestick |
|
|
31
|
+
| `apexcharts/violin` | violin *(new in v6)* |
|
|
31
32
|
| `apexcharts/pie` | pie, donut, polarArea |
|
|
32
33
|
| `apexcharts/donut` | same as /pie |
|
|
33
34
|
| `apexcharts/polarArea` | same as /pie |
|
|
34
|
-
| `apexcharts/radialBar` | radialBar |
|
|
35
|
+
| `apexcharts/radialBar` | radialBar, **gauge** *(v6 alias)* |
|
|
35
36
|
| `apexcharts/radar` | radar |
|
|
36
37
|
| `apexcharts/heatmap` | heatmap |
|
|
37
38
|
| `apexcharts/treemap` | treemap |
|
|
38
39
|
|
|
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.
|
|
41
|
+
|
|
39
42
|
### Using Multiple Chart Types
|
|
40
43
|
|
|
41
44
|
```js
|
|
@@ -57,9 +60,22 @@ Features are optional modules that add functionality. When using per-type entrie
|
|
|
57
60
|
| Annotations | `import 'apexcharts/features/annotations'` | X/Y/point/text/image annotations |
|
|
58
61
|
| Exports | `import 'apexcharts/features/exports'` | `dataURI()`, `getSvgString()`, `exportToCSV()` |
|
|
59
62
|
| Keyboard | `import 'apexcharts/features/keyboard'` | Keyboard navigation (accessibility) |
|
|
63
|
+
| Morph *(v6)* | `import 'apexcharts/features/morph'` | Animated chart-type morphs |
|
|
64
|
+
| Drilldown *(v6)* | `import 'apexcharts/features/drilldown'` | Hierarchical drill-down |
|
|
65
|
+
| History / Rewind *(v6)* | `import 'apexcharts/features/history'` | Undo/redo (`chart.history`) |
|
|
66
|
+
| Perspectives *(v6)* | `import 'apexcharts/features/perspectives'` | Shareable view state |
|
|
67
|
+
| Storyboard *(v6)* | `import 'apexcharts/features/storyboard'` | Scrollytelling (includes perspectives) |
|
|
68
|
+
| Facet *(v6)* | `import 'apexcharts/features/facet'` | Design tokens + OS-aware themes |
|
|
69
|
+
| Weave *(v6)* | `import 'apexcharts/features/weave'` | Public plugin platform |
|
|
70
|
+
| Renderer / Strata *(v6)* | `import 'apexcharts/features/renderer-canvas'` | Hybrid SVG + canvas renderer |
|
|
71
|
+
| Marks *(v6)* | `import 'apexcharts/features/marks'` | Custom series types (`registerSeriesType`) |
|
|
72
|
+
| Link *(v6)* | `import 'apexcharts/features/link'` | Crossfilter / linked views |
|
|
73
|
+
| Ink *(v6)* | `import 'apexcharts/features/ink'` | On-chart annotation authoring |
|
|
74
|
+
| Measure *(v6)* | `import 'apexcharts/features/measure'` | Measure / delta ruler |
|
|
75
|
+
| Context menu *(v6)* | `import 'apexcharts/features/context-menu'` | Right-click / long-press context menu |
|
|
60
76
|
| All | `import 'apexcharts/features/all'` | All of the above |
|
|
61
77
|
|
|
62
|
-
**Important:** Tooltip is always included in core
|
|
78
|
+
**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.
|
|
63
79
|
|
|
64
80
|
### What Happens If You Forget a Feature
|
|
65
81
|
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
# v6 Feature Platform: ApexCharts
|
|
2
|
+
|
|
3
|
+
ApexCharts v6 adds an opt-in, tree-shakeable feature platform on top of the v5 core. **Every v5 config keeps working unchanged.** Each feature below is off by default and ships as its own `apexcharts/features/*` entry, so it only enters your bundle when you import it. When using the full `apexcharts` bundle, all features are already present.
|
|
4
|
+
|
|
5
|
+
Two behaviors changed *on by default* (both respect `prefers-reduced-motion`):
|
|
6
|
+
|
|
7
|
+
1. **Coherent variable-length data transitions**: updates that add/remove data points animate as one coordinated motion instead of popping. Appended bars grow from the baseline, removed bars shrink and fade, line/area fills reshape over the union of old and new points, and markers/bubbles/axis labels ride along. Scatter and bubble now animate on dynamic updates for the first time. Disable per chart with `chart.animations.dynamicAnimation.enabled: false`; auto-skipped above `chart.animations.largeDatasetThreshold` (default 1000) and under `prefers-reduced-motion`.
|
|
8
|
+
2. **Native-feeling mobile gestures**: two-finger pinch-zoom, two-finger pan, and kinetic inertia after a flick, with axis rails so a vertical swipe still scrolls the page. Configure via `chart.zoom.pinch` (default `true`) and `chart.pan.inertia` (default `true`, `friction` default `0.92`).
|
|
9
|
+
|
|
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
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Weave: public plugin platform
|
|
15
|
+
|
|
16
|
+
`import 'apexcharts/features/weave'`
|
|
17
|
+
|
|
18
|
+
Publish reusable chart plugins to npm against a stable, versioned API. A plugin draws into its own sandboxed layer and subscribes to lifecycle hooks; it never touches raw internal state.
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import ApexCharts from 'apexcharts'
|
|
22
|
+
import 'apexcharts/features/weave'
|
|
23
|
+
|
|
24
|
+
ApexCharts.registerPlugin({
|
|
25
|
+
name: 'watermark',
|
|
26
|
+
apiVersion: 1,
|
|
27
|
+
setup(api) {
|
|
28
|
+
api.on('draw', () => {
|
|
29
|
+
const layer = api.layer({ z: 'front', className: 'wm' }) // z: 'front' | 'behind'
|
|
30
|
+
layer.text({ x: 10, y: 20, text: 'ACME', size: '12px', color: '#999' })
|
|
31
|
+
})
|
|
32
|
+
},
|
|
33
|
+
destroy(api) {},
|
|
34
|
+
})
|
|
35
|
+
// ApexCharts.unregisterPlugin('watermark') // for tests / hot reload
|
|
36
|
+
|
|
37
|
+
// Activate per chart:
|
|
38
|
+
const options = { plugins: [{ name: 'watermark', options: { /* frozen, live */ }, order: 0 }] }
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The `setup(api)` facade:
|
|
42
|
+
|
|
43
|
+
- `api.on(hook, fn)` / `api.off(hook, fn)`: hooks: `'afterParse' | 'afterScales' | 'draw' | 'afterUpdate' | 'destroy'`.
|
|
44
|
+
- `api.layer(opts?)`: a plugin-owned drawing surface (`path`, `line`, `rect`, `circle`, `text`, `clear`); call it inside draw handlers only, layers are wiped each pass.
|
|
45
|
+
- `api.scales` (readonly): `x(v)`, `y(v, axis?)`, `domainX`, `domainY(axis?)`, `gridWidth`, `gridHeight`, `ratios`.
|
|
46
|
+
- `api.data` (readonly): `[{ name?, hidden, color?, points: [{ x, y }] }]`.
|
|
47
|
+
- `api.theme`: `{ mode, foreColor, seriesColor(i), token(name) }`.
|
|
48
|
+
- `api.store`: per-instance mutable state bag.
|
|
49
|
+
- `api.emit(name, detail?)`: dispatches `plugin:<name>:<event>` on the chart; `api.chart`, `api.el`, `api.name`, `api.version`, `api.options` round out the facade.
|
|
50
|
+
|
|
51
|
+
`apiVersion` gates the contract so raw internals can keep changing safely.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Strata: hybrid SVG + canvas renderer
|
|
56
|
+
|
|
57
|
+
`import 'apexcharts/features/renderer-canvas'`
|
|
58
|
+
|
|
59
|
+
Break the SVG node ceiling without leaving SVG behind. Below a threshold the output is identical SVG; above it, only the series layer becomes a `<canvas>` while axes, grid, tooltips, annotations, and exports stay SVG.
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
import ApexCharts from 'apexcharts'
|
|
63
|
+
import 'apexcharts/features/renderer-canvas'
|
|
64
|
+
|
|
65
|
+
const options = {
|
|
66
|
+
chart: {
|
|
67
|
+
renderer: 'auto', // 'svg' | 'canvas' | 'auto'
|
|
68
|
+
rendererThreshold: 5000, // point count above which 'auto' picks canvas
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
// chart.getActiveRenderer() // => 'svg' | 'canvas'
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Canvas is live for line, area, bar, column, scatter, and candlestick, with shared tooltip, crosshair, zoom, pan, hover/legend dimming, and PNG/SVG export all working. It falls back to SVG automatically for canvas-unsupported features (pattern/image fills, color-matrix filters). Per-point selection visuals and keyboard traversal on canvas remain SVG-only for now.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Marks: composable custom series types
|
|
79
|
+
|
|
80
|
+
`import 'apexcharts/features/marks'`
|
|
81
|
+
|
|
82
|
+
Register a `renderItem(ctx)` function and get a first-class series: events, shared tooltip, legend, and keyboard navigation all work with no extra wiring. Dumbbell, lollipop, and bullet ship as samples.
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
import ApexCharts from 'apexcharts'
|
|
86
|
+
import 'apexcharts/features/marks'
|
|
87
|
+
|
|
88
|
+
ApexCharts.registerSeriesType('lollipop', {
|
|
89
|
+
// dataType?: 'xy' (default) | 'rangeXY' | 'custom'
|
|
90
|
+
// yExtent?: (datum, i) => number | number[] // folds extra values into the y-scale
|
|
91
|
+
// tooltip?: (datum) => number | number[] | string
|
|
92
|
+
renderItem(ctx) {
|
|
93
|
+
const baseline = ctx.scales.y(0) // IMPORTANT: baseline is scales.y(0), NOT api.zeroY
|
|
94
|
+
ctx.api.line({ x1: ctx.x, y1: baseline, x2: ctx.x, y2: ctx.y, stroke: ctx.color, width: 2 })
|
|
95
|
+
ctx.api.circle({ cx: ctx.x, cy: ctx.y, r: 6, fill: ctx.color })
|
|
96
|
+
},
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
const options = {
|
|
100
|
+
chart: { type: 'lollipop' },
|
|
101
|
+
series: [{ name: 'Signups', data: [{ x: 'Jan', y: 41 }, { x: 'Feb', y: 58 }] }],
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**`renderItem` context** (`ctx`): `{ datum, x, y, scales, api, seriesIndex, dataPointIndex, color }`: `x`/`y` are resolved pixels for the datum, `color` is the series palette color.
|
|
106
|
+
|
|
107
|
+
**`ctx.api` primitives**: `api.path({ d, stroke, width, fill, opacity, dash, lineCap })`, `api.line({ x1, y1, x2, y2, stroke, width, dash })`, `api.rect({ x, y, w, h, r, fill, stroke, strokeWidth, opacity })`, `api.circle({ cx, cy, r, fill, stroke, strokeWidth })`, `api.text({ x, y, text, anchor, size, color, weight })`.
|
|
108
|
+
|
|
109
|
+
**`ctx.scales`**: `scales.x(value)`, `scales.xAt(index, value)`, `scales.y(value, axis?)`, `scales.gridWidth`, `scales.gridHeight`, `scales.band` (pixel width of one x step / band). There is **no `api.zeroY`**: use `scales.y(0)` for the baseline.
|
|
110
|
+
|
|
111
|
+
Dumbbell uses `dataType: 'rangeXY'` (datum `y` is `[start, end]`, both bounds folded into the axis); bullet uses `yExtent` to fold `target`/top-band into the y-scale. Built-in type names are guarded against shadowing.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Rewind: history and undo/redo
|
|
116
|
+
|
|
117
|
+
`import 'apexcharts/features/history'`
|
|
118
|
+
|
|
119
|
+
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
|
+
|
|
121
|
+
```js
|
|
122
|
+
const options = {
|
|
123
|
+
chart: { history: { enabled: true, maxDepth: 50, coalesceMs: 300, keyboard: true } },
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
chart.history.undo(animate?) // and .redo(animate?)
|
|
127
|
+
chart.history.canUndo() // and .canRedo() -> boolean
|
|
128
|
+
chart.history.jump(id, animate?)
|
|
129
|
+
chart.history.clear()
|
|
130
|
+
await chart.history.transaction(() => { /* batched edits */ }, { label: 'batch' })
|
|
131
|
+
chart.history.entries() // [{ id, label, at }]
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Perspectives: shareable view state
|
|
137
|
+
|
|
138
|
+
`import 'apexcharts/features/perspectives'`
|
|
139
|
+
|
|
140
|
+
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
|
+
|
|
142
|
+
```js
|
|
143
|
+
const token = chart.perspectives.capture() // { v, view, options? }
|
|
144
|
+
const str = chart.perspectives.encode(token)
|
|
145
|
+
const url = chart.perspectives.toURL() // href with #apex=<token>
|
|
146
|
+
chart.perspectives.apply(token, { animate: true, mergeOptions: {} })
|
|
147
|
+
const id = chart.perspectives.save('Q3 zoom') // -> id
|
|
148
|
+
chart.perspectives.list() // [{ id, name, token }]
|
|
149
|
+
chart.perspectives.delete(id)
|
|
150
|
+
|
|
151
|
+
// static:
|
|
152
|
+
ApexCharts.perspectives.fromURL(location.href) // -> token | null
|
|
153
|
+
ApexCharts.perspectives.decode(str)
|
|
154
|
+
|
|
155
|
+
// config: control which options travel with the token
|
|
156
|
+
const options = { chart: { perspectives: { serializeOptions: ['colors', 'title'] } } }
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Facet: design tokens and OS-aware themes
|
|
162
|
+
|
|
163
|
+
`import 'apexcharts/features/facet'`
|
|
164
|
+
|
|
165
|
+
Charts read `--apx-*` CSS custom properties from the cascade, follow the OS light/dark and contrast preferences with no JS, and can reference named brand themes.
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
import ApexCharts from 'apexcharts'
|
|
169
|
+
import 'apexcharts/features/facet'
|
|
170
|
+
|
|
171
|
+
ApexCharts.registerTheme('brand', {
|
|
172
|
+
mode: 'dark', // 'light' | 'dark'
|
|
173
|
+
palette: ['#4f46e5', '#0ea5e9'],
|
|
174
|
+
tokens: { accent: '#4f46e5', grid: '#333', surface: '#111' },
|
|
175
|
+
})
|
|
176
|
+
// ApexCharts.unregisterTheme('brand')
|
|
177
|
+
|
|
178
|
+
const options = {
|
|
179
|
+
theme: {
|
|
180
|
+
follow: 'os', // 'os' | false: tracks prefers-color-scheme + prefers-contrast
|
|
181
|
+
name: 'brand', // a registered theme
|
|
182
|
+
tokens: true, // read --apx-* CSS vars (default true)
|
|
183
|
+
},
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
```css
|
|
188
|
+
:root { --apx-accent: #4f46e5; --apx-grid: #e5e7eb; --apx-surface: #fff; --apx-series-1: #4f46e5; }
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
`await chart.refreshTokens()` re-reads the cascade after a runtime token change that does not itself trigger a render.
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Cadence: pluggable easing
|
|
196
|
+
|
|
197
|
+
Core (no feature import).
|
|
198
|
+
|
|
199
|
+
`chart.animations.easing` accepts a named curve, a cubic-bezier array, or a function. The default (`easeInOutSine`) is unchanged, so existing charts animate exactly as before.
|
|
200
|
+
|
|
201
|
+
```js
|
|
202
|
+
const options = {
|
|
203
|
+
chart: {
|
|
204
|
+
animations: {
|
|
205
|
+
easing: 'easeOutBack', // or [0.34, 1.56, 0.64, 1], or (t) => t * t
|
|
206
|
+
dynamicAnimation: { enabled: true, speed: 350, easing: 'linear' },
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
ApexCharts.registerEasing('myBounce', (t) => 1 - Math.pow(1 - t, 3))
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Built-in curve names: `linear`, `easeInSine`, `easeOutSine`, `easeInOutSine`, `easeInQuad`, `easeOutQuad`, `easeInOutQuad`, `easeInCubic`, `easeOutCubic`, `easeInOutCubic`, `easeOutBack`, `easeInOutBack`. Anything else (elastic, bounce, ...) must be registered via `registerEasing`.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Link: crossfilter and cross-chart coordination
|
|
219
|
+
|
|
220
|
+
`import 'apexcharts/features/link'`
|
|
221
|
+
|
|
222
|
+
Coordinate a group of charts without wiring.
|
|
223
|
+
|
|
224
|
+
```js
|
|
225
|
+
// Highlight mode: brushing one chart dims non-matching marks in the others (no redraw):
|
|
226
|
+
const a = {
|
|
227
|
+
chart: {
|
|
228
|
+
group: 'sales',
|
|
229
|
+
link: { enabled: true, mode: 'highlight', dimOpacity: 0.2 }, // mode: 'highlight' | 'filter'
|
|
230
|
+
selection: { enabled: true }, // required for brushing
|
|
231
|
+
},
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Crossfilter engine: categorical click-filters, range brushes, shared data table, 2D matrix target:
|
|
235
|
+
const cf = ApexCharts.crossfilter({ id: 'sales', records: rows })
|
|
236
|
+
// ApexCharts.getCrossfilter('sales'); chart.clearCrossfilter()
|
|
237
|
+
|
|
238
|
+
// Per-chart filter binding (presence of `dimension` selects filter mode):
|
|
239
|
+
const b = {
|
|
240
|
+
chart: {
|
|
241
|
+
link: {
|
|
242
|
+
enabled: true,
|
|
243
|
+
id: 'sales',
|
|
244
|
+
dimension: (row) => row.region, // key extractor; [xKey, yKey] for a matrix
|
|
245
|
+
reduce: 'count', // 'count' | { sum, avg, min, max } | (rows) => number
|
|
246
|
+
type: 'category', // 'category' | 'range' | 'matrix'
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Ink: direct-manipulation annotation authoring
|
|
255
|
+
|
|
256
|
+
`import 'apexcharts/features/ink'`
|
|
257
|
+
|
|
258
|
+
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
|
+
|
|
260
|
+
```js
|
|
261
|
+
const options = {
|
|
262
|
+
chart: {
|
|
263
|
+
ink: {
|
|
264
|
+
enabled: true,
|
|
265
|
+
palette: true, // show the "add note" tool palette
|
|
266
|
+
snap: true, // snap to gridlines
|
|
267
|
+
noteColors: ['#e91e63', '#3f51b5'], // optional palette override
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
}
|
|
271
|
+
// Fires: annotationDragged, annotationEdited, annotationStyled, annotationDeleted
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Measure: delta ruler
|
|
277
|
+
|
|
278
|
+
`import 'apexcharts/features/measure'`
|
|
279
|
+
|
|
280
|
+
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
|
+
|
|
282
|
+
```js
|
|
283
|
+
const options = {
|
|
284
|
+
chart: {
|
|
285
|
+
measure: {
|
|
286
|
+
enabled: true,
|
|
287
|
+
mode: 'span', // 'span' = finance-style vertical band; 'free' = diagonal ruler
|
|
288
|
+
key: 'm',
|
|
289
|
+
pinOnRelease: true,
|
|
290
|
+
},
|
|
291
|
+
events: {
|
|
292
|
+
measured: (chart, { from, to, dx, dy, percentChange, slope }) => {},
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
}
|
|
296
|
+
// Or drive from code: chart.startMeasure(), chart.stopMeasure(), chart.clearMeasures()
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Styling resolves through `--apx-measure-*` tokens.
|
|
300
|
+
|
|
301
|
+
### Toolbar tool (v6.1)
|
|
302
|
+
|
|
303
|
+
Since 6.1 the ruler is also a built-in toolbar tool, so it can be armed with a click instead of holding the measure key. The button appears automatically whenever `chart.measure.enabled` is true and the `measure` feature is bundled.
|
|
304
|
+
|
|
305
|
+
```js
|
|
306
|
+
const options = {
|
|
307
|
+
chart: {
|
|
308
|
+
measure: { enabled: true },
|
|
309
|
+
toolbar: {
|
|
310
|
+
autoSelected: 'measure', // pre-select the ruler on load (also accepts 'zoom' | 'pan' | 'selection')
|
|
311
|
+
tools: { measure: true }, // default; false keeps it key-only; a string supplies a custom SVG icon
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
- `toolbar.tools.measure` is `boolean | string` (like the other tools). `toolbar.autoSelected` now also accepts `'measure'` so the plot loads armed with no key held and no click. The `m` key still works.
|
|
318
|
+
- Selecting the ruler is mutually exclusive with zoom / pan / selection. The `locale.toolbar.measure` string labels the button.
|
|
319
|
+
- **Behavior change (v6.1, on by default):** clicking an already-selected zoom / pan / selection / measure toolbar icon now toggles it *off*, leaving the chart with no active tool (previously those buttons were one-way).
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Context menu: Radial Actions
|
|
324
|
+
|
|
325
|
+
`import 'apexcharts/features/context-menu'`
|
|
326
|
+
|
|
327
|
+
Right-click or long-press a data point for actions that operate at that exact point.
|
|
328
|
+
|
|
329
|
+
```js
|
|
330
|
+
const options = {
|
|
331
|
+
chart: {
|
|
332
|
+
contextMenu: {
|
|
333
|
+
enabled: true,
|
|
334
|
+
// built-in ids (default) + custom items:
|
|
335
|
+
items: ['annotate', 'xline', 'yline', 'measure', {
|
|
336
|
+
id: 'copy',
|
|
337
|
+
label: 'Copy value',
|
|
338
|
+
onClick: (chart, { x, y, seriesIndex, dataPointIndex, clientX, clientY }) => {},
|
|
339
|
+
}],
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Built-in `annotate` / `xline` / `yline` items are ink-managed when the ink feature is bundled (they open the floating editor and undo via Rewind).
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Storyboard: scroll-driven choreography (scrollytelling)
|
|
350
|
+
|
|
351
|
+
`import 'apexcharts/features/storyboard'` (includes Perspectives)
|
|
352
|
+
|
|
353
|
+
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
|
+
|
|
355
|
+
```js
|
|
356
|
+
chart.storyboard.bind({
|
|
357
|
+
beats: [
|
|
358
|
+
{ selector: '[data-apex-beat="1"]', view: { window: { xaxis: { min: 0, max: 10 } } } },
|
|
359
|
+
{ selector: '[data-apex-beat="2"]', view: { collapsed: [1] }, options: { chart: { type: 'area' } } },
|
|
360
|
+
],
|
|
361
|
+
scroller: window, // Element | selector; default viewport
|
|
362
|
+
offset: 0.5, // 0..1 trigger line
|
|
363
|
+
})
|
|
364
|
+
chart.storyboard.goTo('intro', { animate: true }) // beat index or key
|
|
365
|
+
chart.storyboard.current() // { index, key } | null
|
|
366
|
+
chart.storyboard.unbind()
|
|
367
|
+
// Fires: beatChange
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Real-time streaming: constant-velocity scroll
|
|
373
|
+
|
|
374
|
+
Core (the scroll animation needs no opt-in; `chart.streaming` bounds memory).
|
|
375
|
+
|
|
376
|
+
Rolling-window updates scroll at constant velocity instead of warping in place. Any update that continues the previous window (`appendData`, or a shifted fixed-length `updateSeries`) translates smoothly.
|
|
377
|
+
|
|
378
|
+
```js
|
|
379
|
+
const options = { chart: { streaming: { enabled: true, maxPoints: 100000 } } }
|
|
380
|
+
// appendData() trims each series to maxPoints (or the visible xaxis.range window)
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## Drilldown: hierarchical drill-down
|
|
386
|
+
|
|
387
|
+
`import 'apexcharts/features/drilldown'` (add `import 'apexcharts/features/morph'` for animated cross-type transitions)
|
|
388
|
+
|
|
389
|
+
Data points reference a child level via a `drilldown` id; clicking drills in, with an optional breadcrumb.
|
|
390
|
+
|
|
391
|
+
```js
|
|
392
|
+
import 'apexcharts/features/drilldown'
|
|
393
|
+
import 'apexcharts/features/morph' // optional, animated type morphs
|
|
394
|
+
|
|
395
|
+
const options = {
|
|
396
|
+
series: [{ data: [
|
|
397
|
+
{ x: '2021', y: 480, drilldown: '2021' },
|
|
398
|
+
{ x: '2022', y: 530, drilldown: '2022' },
|
|
399
|
+
] }],
|
|
400
|
+
drilldown: {
|
|
401
|
+
enabled: true,
|
|
402
|
+
breadcrumb: { show: true, position: 'top-right', rootLabel: 'All Years' },
|
|
403
|
+
animation: { enabled: true, zoomFromPoint: false, speed: 260 },
|
|
404
|
+
series: [
|
|
405
|
+
{ id: '2021', name: '2021 by Channel', data: [/* ... */], chart: { type: 'bar' } },
|
|
406
|
+
],
|
|
407
|
+
// or resolve lazily:
|
|
408
|
+
onDrillDown: (ctx) => ({ id: ctx.point.drilldown, name: '...', data: [] }),
|
|
409
|
+
},
|
|
410
|
+
chart: {
|
|
411
|
+
events: {
|
|
412
|
+
drillDownStart: (info, chart, options) => {},
|
|
413
|
+
drillDownEnd: (info, chart, options) => {},
|
|
414
|
+
drillUp: (info, chart, options) => {},
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
chart.drillDown(id) // Promise
|
|
420
|
+
chart.drillUp()
|
|
421
|
+
chart.drillToRoot()
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Common Pitfalls
|
|
427
|
+
|
|
428
|
+
1. **Forgetting the feature import**: every v6 feature is off until you `import 'apexcharts/features/<name>'` (or use the full `apexcharts` bundle). Enabling the config alone does nothing if the feature isn't in the bundle.
|
|
429
|
+
2. **Using `api.zeroY` in a custom mark**: it does not exist. Use `ctx.scales.y(0)` for the baseline.
|
|
430
|
+
3. **Expecting `mode: 'filter'` on `chart.link` without records**: highlight mode needs `chart.selection.enabled: true`; the crossfilter engine needs `ApexCharts.crossfilter({ id, records })` or a `dimension` extractor.
|
|
431
|
+
4. **`largeDatasetThreshold` is under `chart.animations`**, not `chart` directly.
|
|
432
|
+
5. **Assuming the canvas renderer supports everything**: pattern/image fills and per-point selection visuals fall back to (or stay) SVG.
|