apexcharts-skill 2.0.0 → 2.1.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/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). Covers
7
+ violin, radar, polarArea, rangeBar, rangeArea, treemap, funnel, pyramid, gauge, sunburst,
8
+ 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.0"
16
- library_version: "6.1.0"
16
+ version: "2.1.0"
17
+ library_version: "6.7.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
 
@@ -76,14 +79,14 @@ This is the most critical reference. Using the wrong data format is the #1 cause
76
79
  | Funnel *(v6)* | `'funnel'` | `[{ name, data: [number] }]` + `xaxis: { categories: [...] }`. Order values **largest→smallest**. | `series: [{ data: [1380, 990, 548, 200] }]` |
77
80
  | Pyramid *(v6)* | `'pyramid'` | Same as funnel; order values **smallest→largest** (wide base at bottom). | `series: [{ data: [200, 548, 990, 1380] }]` |
78
81
 
79
- ### Non-Axis Charts (pie, donut, radialBar, polarArea, gauge)
82
+ ### Non-Axis Charts (pie, donut, radialBar, polarArea, gauge, unit, waffle)
80
83
 
81
84
  These use a **flat number array** for `series`, NOT the object format:
82
85
 
83
86
  ```js
84
87
  // CORRECT — flat number array + labels
85
88
  {
86
- chart: { type: 'pie' }, // or 'donut', 'polarArea', 'radialBar', 'gauge'
89
+ chart: { type: 'pie' }, // or 'donut', 'polarArea', 'radialBar', 'gauge', 'unit', 'waffle'
87
90
  series: [44, 55, 13, 43, 22],
88
91
  labels: ['Team A', 'Team B', 'Team C', 'Team D', 'Team E']
89
92
  }
@@ -91,6 +94,29 @@ These use a **flat number array** for `series`, NOT the object format:
91
94
 
92
95
  **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
96
 
97
+ **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`.
98
+
99
+ ### Hierarchical Charts (sunburst)
100
+
101
+ **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:
102
+
103
+ ```js
104
+ {
105
+ chart: { type: 'sunburst' },
106
+ series: [{
107
+ data: [
108
+ { x: 'Mobile', y: 55, children: [
109
+ { x: 'iOS', y: 30, children: [{ x: 'iOS 17', y: 18 }, { x: 'iOS 16', y: 9 }] },
110
+ { x: 'Android', y: 23 }
111
+ ] },
112
+ { x: 'Desktop', y: 33, children: [{ x: 'Windows', y: 20 }, { x: 'macOS', y: 10 }] }
113
+ ]
114
+ }]
115
+ }
116
+ ```
117
+
118
+ Configure the centre hole, corner rounding, and inter-arc gap through `plotOptions.sunburst` (see `references/circular-charts.md`).
119
+
94
120
  ---
95
121
 
96
122
  ## 3. Package / Module Map
@@ -121,6 +147,8 @@ import ApexCharts from 'apexcharts/radialBar' # radialBar + gauge (v6)
121
147
  import ApexCharts from 'apexcharts/radar' # radar only
122
148
  import ApexCharts from 'apexcharts/heatmap' # heatmap only
123
149
  import ApexCharts from 'apexcharts/treemap' # treemap only
150
+ import ApexCharts from 'apexcharts/sunburst' # sunburst (v6.7, hierarchical)
151
+ import ApexCharts from 'apexcharts/unit' # unit + waffle (v6.6, premium)
124
152
  # funnel + pyramid (v6) render through the bar engine; use apexcharts/bar
125
153
 
126
154
  # Optional features (side-effect imports — just import, no default export needed)
@@ -531,6 +559,7 @@ await chart.updateOptions({ title: { text: 'New Title' } })
531
559
  |---|---|
532
560
  | `ApexCharts.exec(chartID, fn, ...args)` | Call method on chart by its `chart.id`. |
533
561
  | `ApexCharts.getChartByID(chartID)` | Get chart instance by id. |
562
+ | `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
563
  | `ApexCharts.merge(target, source)` | Deep-merge objects. |
535
564
  | `ApexCharts.use(typeMap)` | Register chart type constructors (tree-shaking). |
536
565
  | `ApexCharts.registerFeatures(featureMap)` | Register optional feature modules. |
@@ -632,7 +661,7 @@ For detailed chart-family-specific options, data format variants, and full worki
632
661
  | Line, Area, Scatter, Bubble, Range Area | `references/cartesian-charts.md` |
633
662
  | Bar, Column, Range Bar, Timeline/Gantt, Funnel, Pyramid | `references/bar-charts.md` |
634
663
  | Candlestick, Box Plot, Violin | `references/financial-charts.md` |
635
- | Pie, Donut, Polar Area, Radial Bar, Gauge | `references/circular-charts.md` |
664
+ | Pie, Donut, Polar Area, Radial Bar, Gauge, Sunburst, Unit, Waffle | `references/circular-charts.md` |
636
665
  | Heatmap, Treemap | `references/grid-charts.md` |
637
666
  | Radar | `references/radar-charts.md` |
638
667
  | 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.0",
3
+ "version": "2.1.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",
@@ -213,6 +213,28 @@ plotOptions: {
213
213
  }
214
214
  ```
215
215
 
216
+ ### Bar Chart Race (v6.4)
217
+
218
+ 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`.
219
+
220
+ ```js
221
+ const options = {
222
+ chart: {
223
+ type: 'bar',
224
+ animations: { dynamicAnimation: { speed: 800 } },
225
+ },
226
+ plotOptions: { bar: { horizontal: true } },
227
+ dataLabels: {
228
+ enabled: true,
229
+ animate: { enabled: true }, // value labels ride to the new rank instead of snapping
230
+ countUp: { enabled: true }, // and count up/down from the previous value (formatter runs each frame)
231
+ },
232
+ }
233
+ // On each frame, re-sort your data and call updateOptions (or updateSeries) with the
234
+ // new series and categories. Bars, category labels, and value labels animate together.
235
+ // Rotated axis labels ride correctly too.
236
+ ```
237
+
216
238
  ### Goals / Target Markers
217
239
 
218
240
  ```js
@@ -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)
10
12
 
11
13
  ## Tree-Shakeable Import
12
14
 
@@ -18,6 +20,12 @@ 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.
21
29
  ```
22
30
 
23
31
  ---
@@ -94,6 +102,104 @@ A gauge is a single-value `radialBar` alias. Series is a flat one-element array;
94
102
 
95
103
  A plain radialBar is effectively a gauge with `shape: 'arc'`. A semi-circle gauge is `startAngle: -90, endAngle: 90`.
96
104
 
105
+ ### Sunburst (v6.7)
106
+
107
+ 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`.
108
+
109
+ ```js
110
+ {
111
+ chart: { type: 'sunburst', height: 380 },
112
+ series: [{
113
+ data: [
114
+ { x: 'Mobile', y: 55, children: [
115
+ { x: 'iOS', y: 30, children: [
116
+ { x: 'iOS 17', y: 18 },
117
+ { x: 'iOS 16', y: 9 }
118
+ ] },
119
+ { x: 'Android', y: 23 }
120
+ ] },
121
+ { x: 'Desktop', y: 33, children: [
122
+ { x: 'Windows', y: 20 },
123
+ { x: 'macOS', y: 10 }
124
+ ] }
125
+ ]
126
+ }],
127
+ plotOptions: {
128
+ sunburst: {
129
+ innerSize: '25%', // centre hole radius as a % of max radius (or px)
130
+ borderRadius: 5, // round the arc corners (px), same semantics as pie.borderRadius
131
+ spacing: 1, // gap between adjacent arcs (px), same semantics as pie.spacing
132
+ startAngle: 0,
133
+ endAngle: 360,
134
+ leaf: 'extend', // 'extend' draws a shallow branch's leaf to the rim | 'stop'
135
+ partition: 'normalize', // angular partition of a parent's wedge among children: 'normalize' | 'strict'
136
+ tint: 0, // per-depth lightening of the parent colour (0 = same, 1 = white)
137
+ zoomOnClick: true, // click a wedge to zoom into its branch (breadcrumb to go back). Default true
138
+ dataLabels: {
139
+ show: true,
140
+ minAngleToShow: 5, // hide the label on any arc narrower than this (degrees)
141
+ style: { fontSize: '12px', colors: ['#fff'] }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ 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.
149
+
150
+ ### Unit / Waffle (v6.6, premium)
151
+
152
+ 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.
153
+
154
+ Data is the same flat number array + `labels` shape as pie:
155
+
156
+ ```js
157
+ {
158
+ chart: { type: 'unit', height: 360 },
159
+ series: [276, 266, 3],
160
+ labels: ['For', 'Against', 'Abstain'],
161
+ plotOptions: { unit: { layout: 'grouped' } }
162
+ }
163
+ ```
164
+
165
+ **Layouts** via `plotOptions.unit.layout`:
166
+
167
+ - `grouped` (default): one phyllotaxis blob per category, laid out in a row.
168
+ - `packed`: one shared blob, coloured by group (`sortByGroup: true` nests the minority in the centre).
169
+ - `columns`: each category is a vertical bar built from stacked dots (a waffle column).
170
+ - `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).
171
+ - `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).
172
+ - `arc` (**v6.7**): a parliament / hemicycle, seats in concentric arced rows across an annulus, filled in category order.
173
+
174
+ **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`.
175
+
176
+ `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.
177
+
178
+ ```js
179
+ {
180
+ chart: { type: 'waffle', height: 360 },
181
+ series: [35, 23, 15, 9, 8, 6, 4],
182
+ labels: ['Coal', 'Gas', 'Hydro', 'Nuclear', 'Wind', 'Solar', 'Other'],
183
+ plotOptions: { unit: { grid: { columns: 10, total: 100 } } }
184
+ }
185
+ ```
186
+
187
+ A parliament (hemicycle) seat chart:
188
+
189
+ ```js
190
+ {
191
+ chart: { type: 'unit', height: 320 },
192
+ series: [120, 95, 60, 25],
193
+ labels: ['Party A', 'Party B', 'Party C', 'Party D'],
194
+ plotOptions: {
195
+ unit: {
196
+ layout: 'arc',
197
+ arc: { startAngle: -90, endAngle: 90, innerRadiusRatio: 0.4, rows: 'auto' }
198
+ }
199
+ }
200
+ }
201
+ ```
202
+
97
203
  ---
98
204
 
99
205
  ## Key plotOptions
@@ -111,6 +217,9 @@ plotOptions: {
111
217
 
112
218
  customScale: 1, // scale the pie (0.5 = half size)
113
219
 
220
+ borderRadius: 0, // (v6.7) round each slice's corners (px). Applies to pie, donut, polarArea
221
+ spacing: 0, // (v6.7) gap between adjacent slices (px). Applies to pie, donut, polarArea
222
+
114
223
  dataLabels: {
115
224
  offset: 0, // move labels away from center
116
225
  minAngleToShowLabel: 10 // hide labels on tiny slices
@@ -266,3 +375,5 @@ plotOptions: {
266
375
  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
376
  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
377
  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.
378
+ 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.
379
+ 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.
@@ -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).
@@ -36,6 +36,8 @@ Each entry point registers a family of related chart types:
36
36
  | `apexcharts/radar` | radar |
37
37
  | `apexcharts/heatmap` | heatmap |
38
38
  | `apexcharts/treemap` | treemap |
39
+ | `apexcharts/sunburst` | sunburst *(new in v6.7, free)* |
40
+ | `apexcharts/unit` | unit, **waffle** *(new in v6.6, premium: watermarked until licensed)* |
39
41
 
40
42
  **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
43
 
@@ -11,6 +11,45 @@ Also new by default: **`render()` is idempotent**: a repeated `render()` (e.g. a
11
11
 
12
12
  ---
13
13
 
14
+ ## Licensing: premium features and the trial watermark
15
+
16
+ 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.
17
+
18
+ **The premium set (watermarked until entitled):**
19
+
20
+ - `storyboard` (scrollytelling)
21
+ - `link` (crossfilter / linked views)
22
+ - `ink` (annotation authoring)
23
+ - `measure` (delta ruler)
24
+ - `context-menu` (`contextMenu`)
25
+ - `perspectives` (shareable view state)
26
+ - `history` (undo/redo, Rewind)
27
+ - the `unit` / `waffle` chart type (premium since **6.6.0**, the first premium chart type)
28
+
29
+ **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).
30
+
31
+ ### Setting a license
32
+
33
+ ```js
34
+ // Static: applies to every chart on the page. Call before render().
35
+ ApexCharts.setLicense('APEX-...')
36
+
37
+ // Per-chart: overrides the static key and window.Apex.license for this chart.
38
+ const options = { chart: { license: 'APEX-...' } }
39
+ ```
40
+
41
+ Both are typed: `ApexCharts.setLicense(key: string)` (static) and `chart.license?: string`.
42
+
43
+ - **In use, not bundled.** Importing a premium module without actually enabling it does not watermark; only *using* it does.
44
+ - **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.
45
+ - **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.
46
+
47
+ ### Plan entitlement (6.7.0 behavior change)
48
+
49
+ 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.
50
+
51
+ ---
52
+
14
53
  ## Weave: public plugin platform
15
54
 
16
55
  `import 'apexcharts/features/weave'`
@@ -116,6 +155,8 @@ Dumbbell uses `dataType: 'rangeXY'` (datum `y` is `[start, end]`, both bounds fo
116
155
 
117
156
  `import 'apexcharts/features/history'`
118
157
 
158
+ **Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
159
+
119
160
  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
161
 
121
162
  ```js
@@ -137,6 +178,8 @@ chart.history.entries() // [{ id, label, at }]
137
178
 
138
179
  `import 'apexcharts/features/perspectives'`
139
180
 
181
+ **Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
182
+
140
183
  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
184
 
142
185
  ```js
@@ -219,6 +262,8 @@ Built-in curve names: `linear`, `easeInSine`, `easeOutSine`, `easeInOutSine`, `e
219
262
 
220
263
  `import 'apexcharts/features/link'`
221
264
 
265
+ **Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
266
+
222
267
  Coordinate a group of charts without wiring.
223
268
 
224
269
  ```js
@@ -255,6 +300,8 @@ const b = {
255
300
 
256
301
  `import 'apexcharts/features/ink'`
257
302
 
303
+ **Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
304
+
258
305
  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
306
 
260
307
  ```js
@@ -277,6 +324,8 @@ const options = {
277
324
 
278
325
  `import 'apexcharts/features/measure'`
279
326
 
327
+ **Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
328
+
280
329
  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
330
 
282
331
  ```js
@@ -324,6 +373,8 @@ const options = {
324
373
 
325
374
  `import 'apexcharts/features/context-menu'`
326
375
 
376
+ **Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
377
+
327
378
  Right-click or long-press a data point for actions that operate at that exact point.
328
379
 
329
380
  ```js
@@ -350,6 +401,8 @@ Built-in `annotate` / `xline` / `yline` items are ink-managed when the ink featu
350
401
 
351
402
  `import 'apexcharts/features/storyboard'` (includes Perspectives)
352
403
 
404
+ **Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
405
+
353
406
  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
407
 
355
408
  ```js
@@ -423,6 +476,34 @@ chart.drillToRoot()
423
476
 
424
477
  ---
425
478
 
479
+ ## Point annotation tooltips (6.7.0)
480
+
481
+ `import 'apexcharts/features/annotations'` (free, part of the standard annotations module)
482
+
483
+ 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`:
484
+
485
+ ```js
486
+ const options = {
487
+ annotations: {
488
+ points: [{
489
+ x: 'Mar',
490
+ y: 62,
491
+ marker: { size: 6, fillColor: '#FF4560' },
492
+ label: { text: 'Peak' },
493
+ tooltip: {
494
+ enabled: true,
495
+ text: 'All-time high: 62', // string, or an array joined with line breaks; falls back to label.text
496
+ // formatter: (opts) => `<b>${opts.annotation.label.text}</b>` // HTML, takes precedence over text
497
+ },
498
+ }],
499
+ },
500
+ }
501
+ ```
502
+
503
+ `tooltip.formatter` receives `{ annotation, seriesIndex, id, ... }` and returns HTML.
504
+
505
+ ---
506
+
426
507
  ## Common Pitfalls
427
508
 
428
509
  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.