apexcharts-skill 2.2.0 → 3.0.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/.cursorrules +57 -19
- package/README.md +14 -10
- package/SKILL.md +139 -57
- package/index.js +1 -1
- package/package.json +1 -1
- package/references/bar-charts.md +124 -4
- package/references/cartesian-charts.md +77 -1
- package/references/circular-charts.md +48 -1
- package/references/{v6-features.md → feature-platform.md} +121 -23
- package/references/financial-charts.md +68 -0
- package/references/tree-shaking.md +116 -28
package/references/bar-charts.md
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
- **Range Bar** (`'rangeBar'`) — Bars with start/end values (used for timelines, Gantt charts)
|
|
8
8
|
- **Funnel** (`'funnel'`, **new in v6**): Stage-by-stage drop-off chart
|
|
9
9
|
- **Pyramid** (`'pyramid'`, **new in v6**): A funnel with the wide base at the bottom
|
|
10
|
+
- **Waterfall** (`'waterfall'`, **new in v7.1**): Deltas that accumulate into a running total
|
|
11
|
+
- **Dumbbell** (`'dumbbell'`, **new in v7.1**): Two or more measures per category, joined by a connector
|
|
10
12
|
|
|
11
13
|
## Tree-Shakeable Import
|
|
12
14
|
|
|
@@ -14,10 +16,16 @@
|
|
|
14
16
|
import ApexCharts from 'apexcharts/bar'
|
|
15
17
|
// Registers: bar, column, rangeBar
|
|
16
18
|
// Aliases: apexcharts/column, apexcharts/rangeBar
|
|
17
|
-
// Also covers funnel + pyramid (they normalize to the bar engine
|
|
19
|
+
// Also covers funnel + pyramid (they normalize to the bar engine)
|
|
20
|
+
|
|
21
|
+
// waterfall and dumbbell (v7.1) each add a feature module on top of the bar engine:
|
|
22
|
+
import ApexCharts from 'apexcharts/waterfall' // == apexcharts/bar + features/waterfall
|
|
23
|
+
import ApexCharts from 'apexcharts/dumbbell' // == apexcharts/bar + features/dumbbell
|
|
18
24
|
```
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
Both are **Tier 1**, so the default `apexcharts` bundle already has them and no import is needed there.
|
|
27
|
+
|
|
28
|
+
**Alias 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
29
|
|
|
22
30
|
**Histogram (v6.9):** `chart.type: 'histogram'` also renders through the bar pathway, but its series carry raw observations that the chart bins itself, and the binning needs the stats feature (`apexcharts/histogram` entry, or `apexcharts/features/stats` alongside `apexcharts/bar`). It is documented with the other statistical charts in `references/financial-charts.md`.
|
|
23
31
|
|
|
@@ -184,6 +192,105 @@ Same shape as funnel, but order values **smallest → largest** so the wide base
|
|
|
184
192
|
}
|
|
185
193
|
```
|
|
186
194
|
|
|
195
|
+
### Waterfall (v7.1)
|
|
196
|
+
|
|
197
|
+
`chart.type: 'waterfall'` **accumulates the running total for you**. The series holds the **deltas**; a row flagged `isSubtotal` or `isTotal` draws the running total from zero at that position and carries **no `y` of its own**. Connectors bridge each bar's finish to the next one's start, and rising, falling and total bars take their own colors.
|
|
198
|
+
|
|
199
|
+
```js
|
|
200
|
+
{
|
|
201
|
+
chart: { type: 'waterfall', height: 350 },
|
|
202
|
+
series: [{
|
|
203
|
+
name: 'Operating income',
|
|
204
|
+
data: [
|
|
205
|
+
{ x: 'Net revenue', y: 8786000 },
|
|
206
|
+
{ x: 'Cost of sales', y: -2786000 },
|
|
207
|
+
{ x: 'Gross profit', isSubtotal: true }, // no y: measured for you
|
|
208
|
+
{ x: 'Operating expenses', y: -1786000 },
|
|
209
|
+
{ x: 'Operating income', isTotal: true }, // no y: sum from zero
|
|
210
|
+
],
|
|
211
|
+
}],
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Row shape** (`ApexWaterfallPoint`, every field optional so a series can mix the two kinds freely):
|
|
216
|
+
|
|
217
|
+
| Field | Meaning |
|
|
218
|
+
|---|---|
|
|
219
|
+
| `x` | Category label, timestamp, or `Date` |
|
|
220
|
+
| `y` | The **step**: the signed amount it moves the running total by. Omit on a subtotal / total row. |
|
|
221
|
+
| `isSubtotal` | Sum of the steps since the previous subtotal / total bar |
|
|
222
|
+
| `isTotal` | Sum of every step from zero |
|
|
223
|
+
| `fillColor` | Overrides the semantic fill for this row |
|
|
224
|
+
|
|
225
|
+
**`plotOptions.waterfall`:**
|
|
226
|
+
|
|
227
|
+
```js
|
|
228
|
+
plotOptions: {
|
|
229
|
+
waterfall: {
|
|
230
|
+
colors: {
|
|
231
|
+
positive: '#00A86F', // a step that raises the running total
|
|
232
|
+
negative: '#FF4560', // a step that lowers it
|
|
233
|
+
subtotal: undefined, // defaults to the series color from the active palette
|
|
234
|
+
total: undefined, // same default, so running totals stay distinct from steps
|
|
235
|
+
},
|
|
236
|
+
connectors: {
|
|
237
|
+
show: true, // without them the floating columns read as unrelated bars
|
|
238
|
+
color: undefined, // defaults to grid.borderColor, so it is theme-aware
|
|
239
|
+
strokeWidth: 1,
|
|
240
|
+
strokeDashArray: 3,
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
A datum's own `fillColor` always wins over `plotOptions.waterfall.colors`.
|
|
247
|
+
|
|
248
|
+
### Dumbbell (v7.1)
|
|
249
|
+
|
|
250
|
+
`chart.type: 'dumbbell'` compares two or more measures per category. **Each series is one measure**, and the chart joins them with a connector per category. You do not zip the values into `[low, high]` pairs.
|
|
251
|
+
|
|
252
|
+
```js
|
|
253
|
+
{
|
|
254
|
+
chart: { type: 'dumbbell', height: 350 },
|
|
255
|
+
series: [
|
|
256
|
+
{ name: '2020', data: [{ x: 'Backend', y: 92 }, { x: 'Frontend', y: 78 }] },
|
|
257
|
+
{ name: '2025', data: [{ x: 'Backend', y: 118 }, { x: 'Frontend', y: 96 }] },
|
|
258
|
+
],
|
|
259
|
+
plotOptions: { bar: { horizontal: true } }, // rows; omit for columns
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
The connector's thickness is `plotOptions.bar.barHeight` (rows) or `columnWidth` (columns), and the size of the marked ends is `markers.size`: they are the bar and its markers, so they are configured as such.
|
|
264
|
+
|
|
265
|
+
**`plotOptions.bar.dumbbell`:**
|
|
266
|
+
|
|
267
|
+
```js
|
|
268
|
+
plotOptions: {
|
|
269
|
+
bar: {
|
|
270
|
+
dumbbell: {
|
|
271
|
+
connector: {
|
|
272
|
+
color: undefined, // undefined = a gradient between the two endpoint colours,
|
|
273
|
+
// resolved per row so a row where the measures cross runs the right way
|
|
274
|
+
opacity: 0.55, // the join is context for the marked ends, not a third mark
|
|
275
|
+
},
|
|
276
|
+
dataLabels: {
|
|
277
|
+
enabled: true, // default on for chart.type 'dumbbell', off for the bare isDumbbell flag
|
|
278
|
+
offset: 6, // px clear of the marked end, outward from the connector
|
|
279
|
+
colorFromMarker: true,
|
|
280
|
+
// formatter(value, { seriesIndex, dataPointIndex, endpointIndex, w })
|
|
281
|
+
// NOTE: defaults to the value axis' label formatter, NOT dataLabels.formatter
|
|
282
|
+
// (on a range bar that one reads out end - start, which is the gap, not the endpoint)
|
|
283
|
+
},
|
|
284
|
+
tooltip: { differenceLabel: 'Difference' },
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
With three or more measures only the two extremes are labelled: anything between them sits on the connector, where a label has nowhere to go that is not over the line or over its neighbour.
|
|
291
|
+
|
|
292
|
+
**Versus the older range-bar form.** `plotOptions.bar.isDumbbell` on a `rangeBar` with `y: [lo, hi]` pairs still works and is a different chart: one series, endpoint colours from `plotOptions.bar.dumbbellColors` (`[[startColor, endColor]]`). `chart.type: 'dumbbell'` takes one series per measure and colours each dot after the series it belongs to, from `colors`. Prefer the type unless you already have paired data.
|
|
293
|
+
|
|
187
294
|
---
|
|
188
295
|
|
|
189
296
|
## Key plotOptions.bar Options
|
|
@@ -197,7 +304,7 @@ plotOptions: {
|
|
|
197
304
|
distributed: false, // true = different color per data point
|
|
198
305
|
borderRadius: 4, // rounded corners (number or object)
|
|
199
306
|
borderRadiusApplication: 'end', // 'end' | 'around'
|
|
200
|
-
borderRadiusWhenStacked
|
|
307
|
+
// borderRadiusWhenStacked was REMOVED in v7.0, see the note below
|
|
201
308
|
|
|
202
309
|
dataLabels: {
|
|
203
310
|
position: 'top', // 'top' | 'center' | 'bottom'
|
|
@@ -215,6 +322,14 @@ plotOptions: {
|
|
|
215
322
|
}
|
|
216
323
|
```
|
|
217
324
|
|
|
325
|
+
**⚠️ `borderRadiusWhenStacked` was removed in v7.0.** Rounded corners on a stacked bar are no longer a setting: corner ownership follows the **outer edge** of the stack, which is what `'last'` approximated and what `'all'` got wrong on any stack whose last series was empty. An unknown option is ignored, so leaving it in a config is harmless but does nothing. Delete it. Related v7.0 fixes: a stacked bar's bottom cap is now the top-rounded path mirrored (caps no longer invert or pop when a series collapses and rises again), and grouped stacked charts resolve caps per group rather than chart-wide, so every group gets its own bottom and top radius.
|
|
326
|
+
|
|
327
|
+
**⚠️ `dataLabels.animate.enabled` now defaults to `true` (v7.0), bar/column only.** Labels ride to their new position on a data-change update instead of snapping there, so they reflow on the same clock as the bars, markers and axis ticks. A label that has not moved is a per-label no-op; speed and easing follow `chart.animations.dynamicAnimation`. For the pre-v7 behavior:
|
|
328
|
+
|
|
329
|
+
```js
|
|
330
|
+
dataLabels: { animate: { enabled: false } }
|
|
331
|
+
```
|
|
332
|
+
|
|
218
333
|
### Bar Chart Race (v6.4)
|
|
219
334
|
|
|
220
335
|
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`.
|
|
@@ -309,4 +424,9 @@ series: [{
|
|
|
309
424
|
4. **Timeline without `xaxis.type: 'datetime'`** — date-based range bars need `xaxis: { type: 'datetime' }` to render correctly.
|
|
310
425
|
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.
|
|
311
426
|
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]`.
|
|
312
|
-
7. **Reaching for `plotOptions.bar.isFunnel
|
|
427
|
+
7. **Reaching for `plotOptions.bar.isFunnel`**: unnecessary. Set `chart.type: 'funnel'` (or `'pyramid'`) and use `plotOptions.funnel` for shape options.
|
|
428
|
+
8. **Pre-computing the running total for a waterfall** *(v7.1)*: the series carries the **deltas**; the chart accumulates. Feeding it cumulative values draws each bar from zero to the total, which is a column chart with extra steps.
|
|
429
|
+
9. **Giving a waterfall subtotal row a `y`** *(v7.1)*: `isSubtotal` / `isTotal` rows are measured for you. Supply `x` and the flag, nothing else.
|
|
430
|
+
10. **Zipping dumbbell values into `y: [lo, hi]`** *(v7.1)*: that is the older `plotOptions.bar.isDumbbell` range-bar form. `chart.type: 'dumbbell'` wants one series per measure, each with plain `{ x, y }` points.
|
|
431
|
+
11. **Setting `borderRadiusWhenStacked`**: removed in v7.0. The option is ignored; stacked corner ownership follows the stack's outer edge automatically.
|
|
432
|
+
12. **Expecting data labels to snap on update** *(v7.0)*: `dataLabels.animate.enabled` now defaults to `true` on bar/column. Set it to `false` for the old behavior.
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
- **Scatter** (`'scatter'`) — Individual data points plotted by X/Y coordinates
|
|
8
8
|
- **Bubble** (`'bubble'`) — Scatter with variable-size bubbles (requires z value)
|
|
9
9
|
- **Range Area** (`'rangeArea'`) — Area chart showing a range between two values
|
|
10
|
+
- **Streamgraph** (`'streamgraph'`, **new in v7.1**): Series stacked as flowing bands around a chosen baseline
|
|
10
11
|
|
|
11
12
|
## Tree-Shakeable Import
|
|
12
13
|
|
|
@@ -14,8 +15,13 @@
|
|
|
14
15
|
import ApexCharts from 'apexcharts/line'
|
|
15
16
|
// Registers: line, area, scatter, bubble, rangeArea
|
|
16
17
|
// Aliases: apexcharts/area, apexcharts/scatter, apexcharts/bubble, apexcharts/rangeArea
|
|
18
|
+
|
|
19
|
+
// streamgraph (v7.1) adds a feature module on top of the rangeArea engine:
|
|
20
|
+
import ApexCharts from 'apexcharts/streamgraph' // == apexcharts/rangeArea + features/streamgraph
|
|
17
21
|
```
|
|
18
22
|
|
|
23
|
+
Streamgraph is **Tier 1**, so the default `apexcharts` bundle already has it and no import is needed there.
|
|
24
|
+
|
|
19
25
|
---
|
|
20
26
|
|
|
21
27
|
## Data Formats (Detailed)
|
|
@@ -124,6 +130,62 @@ Always use XY format:
|
|
|
124
130
|
}
|
|
125
131
|
```
|
|
126
132
|
|
|
133
|
+
### Streamgraph (v7.1)
|
|
134
|
+
|
|
135
|
+
`chart.type: 'streamgraph'` stacks the series as flowing bands around a baseline chosen to keep the whole picture readable. Series format is the same as area; **the stacking is the chart's job, so do not set `chart.stacked`**.
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
{
|
|
139
|
+
chart: { type: 'streamgraph', height: 350 },
|
|
140
|
+
series: [
|
|
141
|
+
{ name: 'Drama', data: [{ x: '2024-01-01', y: 32 }, { x: '2024-02-01', y: 41 }] },
|
|
142
|
+
{ name: 'Comedy', data: [{ x: '2024-01-01', y: 18 }, { x: '2024-02-01', y: 26 }] },
|
|
143
|
+
],
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Curves are `monotoneCubic` by default so a band never overshoots its data, each band's name is drawn inside it sized to the room that band actually has, and hovering a band fades the others. The legend and tooltip work as on any axis chart.
|
|
148
|
+
|
|
149
|
+
**`plotOptions.streamgraph`:**
|
|
150
|
+
|
|
151
|
+
```js
|
|
152
|
+
plotOptions: {
|
|
153
|
+
streamgraph: {
|
|
154
|
+
offset: 'wiggle', // where the baseline goes:
|
|
155
|
+
// 'wiggle' (default) minimizes total weighted slope, so thick bands stay level
|
|
156
|
+
// 'silhouette' centres the stack on one horizontal line
|
|
157
|
+
// 'zero' an ordinary stacked area, on the zero line
|
|
158
|
+
// 'expand' normalizes each column to its own total (composition, not volume)
|
|
159
|
+
|
|
160
|
+
order: 'inside-out', // stacking order, bottom first:
|
|
161
|
+
// 'inside-out' (default) puts early-peaking series in the middle and fans
|
|
162
|
+
// later peaks outward, each to whichever side is thinner
|
|
163
|
+
// 'inverse' the series order, reversed
|
|
164
|
+
// 'none' the series order as given
|
|
165
|
+
|
|
166
|
+
hover: { show: true, opacity: 0.35 }, // what the OTHER bands drop to; much above ~0.5 and the
|
|
167
|
+
// hovered band stops reading as picked out
|
|
168
|
+
|
|
169
|
+
labels: {
|
|
170
|
+
show: true,
|
|
171
|
+
minWidth: 24, // a band narrower than this many px is left unlabelled rather than
|
|
172
|
+
// given a name truncated past the point of being a name
|
|
173
|
+
minFontSize: 9,
|
|
174
|
+
maxFontSize: 30,
|
|
175
|
+
style: {
|
|
176
|
+
fontSize: 'auto', // sizes each name to its band, bounded by min/maxFontSize.
|
|
177
|
+
// Give a literal ('12px') to draw every name at the same size.
|
|
178
|
+
fontWeight: 600,
|
|
179
|
+
colors: undefined, // per-series override; by default each label takes black or white,
|
|
180
|
+
// whichever reads on its own band
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
`offset: 'wiggle'` with `order: 'inside-out'` is the classic streamgraph, and the pair is what keeps it readable: the middle of the stack moves least under a wiggle baseline. A faded band's name is recoloured to `chart.foreColor` rather than faded with it, because the name takes black or white by the contrast of the band at full strength.
|
|
188
|
+
|
|
127
189
|
---
|
|
128
190
|
|
|
129
191
|
## Key Options
|
|
@@ -242,6 +304,20 @@ xaxis: {
|
|
|
242
304
|
|
|
243
305
|
1. **Bubble chart without z value** — renders with zero-size bubbles. Always provide `z` in data.
|
|
244
306
|
2. **Using `xaxis.categories` with `{ x, y }` data** — categories are silently ignored when data contains x values. Choose one approach.
|
|
245
|
-
3. **Datetime axis with string dates
|
|
307
|
+
3. **Datetime axis with string dates**: pass timestamps (`new Date(...).getTime()`) or `Date` objects, not raw strings like `'January 2024'`. Since v6.10 a `Date` object `x` is accepted by the types and keeps millisecond resolution (previously milliseconds were truncated, collapsing points within the same second). **Since v7.1 a `Date` x also works on a non-datetime axis**; before that it only worked when the axis was `datetime` and stringified into garbage anywhere else, and an invalid `Date` slipped through unnoticed. Both are handled now.
|
|
246
308
|
4. **`stroke.curve: 'smooth'` on sparse data** — can produce visual artifacts. Use `'monotoneCubic'` for mathematically smoother interpolation.
|
|
247
309
|
5. **Range Area with single value instead of array** — `y` must be `[low, high]`, not a single number.
|
|
310
|
+
6. **Setting `chart.stacked` on a streamgraph** *(v7.1)*: the chart owns its own stacking, baseline and band order through `plotOptions.streamgraph`. Reach for `offset: 'zero'` if what you actually want is a plain stacked area.
|
|
311
|
+
7. **A series that starts with nulls used to mis-target the tooltip**: the hovered index resolved against the drawn points rather than the data, so the tooltip read the wrong point. Fixed in v7.1.
|
|
312
|
+
8. **`autoScaleYaxis` scaling to points nobody can see**: before v7.1, zooming let one point just outside the window size the whole axis, and a series with nothing in the window still contributed. Fixed in v7.1; stacked charts now also scale to the stacked totals inside the window rather than to individual series.
|
|
313
|
+
|
|
314
|
+
## Axis and layout fixes worth knowing (v7.0 / v7.1)
|
|
315
|
+
|
|
316
|
+
These need no config change; they matter because a workaround you carried from an earlier version may now be unnecessary.
|
|
317
|
+
|
|
318
|
+
- **Logarithmic axis geometry, and `tickAmount` on a log scale** *(v7.0)*. Log-scale positions were computed against the wrong domain, and `tickAmount` was ignored outright on a log axis. Both fixed, so `yaxis: { logarithmic: true, tickAmount: n }` now does what it says.
|
|
319
|
+
- **Bar width came from the smallest gap inside one series** *(fixed v7.1)*. A single series with one tight pair of x values shrank every bar on the chart. A bar's slot now comes from the axis, the union of gaps across all series.
|
|
320
|
+
- **Stacked baselines resolve by x, not by position in the array** *(fixed v7.0)*. Two series stacked on ragged data lined up by ordinal, so a series with a missing point stacked onto the wrong neighbour.
|
|
321
|
+
- **A container resize arriving mid-animation was lost for good** *(fixed v7.1)*. The ResizeObserver fires once per resize and the handler dropped that callback while an animation ran, so a chart in a collapsing sidebar kept its old size.
|
|
322
|
+
- **Annotations on a chart with no data** *(fixed v7.0)*. Placement was gated chart-wide on `dataPoints`, so an empty chart dropped every annotation including y-axis ones that are always placeable. Gating is now per annotation.
|
|
323
|
+
- **A tooltip inside Shadow DOM followed the wrong element** *(fixed v7.0)*. Reading `e.target` after a deferred hover gets the shadow host, not the hovered mark.
|
|
@@ -29,8 +29,13 @@ import ApexCharts from 'apexcharts/unit'
|
|
|
29
29
|
|
|
30
30
|
import { heart, outlined, glyphs, preview } from 'apexcharts/unit-shapes'
|
|
31
31
|
// Unit-chart shape kit (v6.10), named exports tree-shaken per shape. See "Unit shapes" below.
|
|
32
|
+
|
|
33
|
+
import { person, registerMarks } from 'apexcharts/pictograms'
|
|
34
|
+
// Pictogram glyph collection (v7.0), one drawn mark per unit. See "Pictograms" below.
|
|
32
35
|
```
|
|
33
36
|
|
|
37
|
+
All of these are **Tier 1** (in the default `apexcharts` bundle). Nothing in the circular family is Tier 2.
|
|
38
|
+
|
|
34
39
|
---
|
|
35
40
|
|
|
36
41
|
## Data Format
|
|
@@ -152,7 +157,7 @@ Colours, `stroke`, `legend`, and `title` behave as they do on pie and donut. A s
|
|
|
152
157
|
|
|
153
158
|
### Unit / Waffle (v6.6, premium)
|
|
154
159
|
|
|
155
|
-
A `unit` chart renders one discrete mark for every unit of value instead of a single bar or slice, so "37 of 200" reads as a countable quantity. It is a **non-axis** chart (dispatched like pie or treemap) and is **premium**: it renders fully in trial mode with an `APEXCHARTS` watermark until an entitled license is set (see `references/
|
|
160
|
+
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/feature-platform.md`). On every update each mark tweens from its old position to its new one, so re-grouping, filtering, or a changing count re-forms the marks.
|
|
156
161
|
|
|
157
162
|
Data is the same flat number array + `labels` shape as pie:
|
|
158
163
|
|
|
@@ -219,6 +224,45 @@ registerShapes([...]) // register so positions: '<name>' resolves by
|
|
|
219
224
|
|
|
220
225
|
Every shape carries metadata on `shape` (category, kind, and `minUnits`: the count below which it stops being recognisable; asking for fewer logs a console warning naming the shape). From a script tag, `dist/unit-shapes.js` exposes the kit as the global `ApexUnitShapes` with every shape pre-registered, so `positions: 'heart'` works by name.
|
|
221
226
|
|
|
227
|
+
### Pictograms (`apexcharts/pictograms`, v7.0)
|
|
228
|
+
|
|
229
|
+
A **shape** is where the units go; a **pictogram** is what one unit looks like. They are independent, so `positions: heart` with `shape: 'pictogram'` arranges glyphs into a heart, and every other pairing is equally valid.
|
|
230
|
+
|
|
231
|
+
```js
|
|
232
|
+
import ApexCharts from 'apexcharts'
|
|
233
|
+
import { person, registerMarks } from 'apexcharts/pictograms'
|
|
234
|
+
|
|
235
|
+
registerMarks([person]) // so pictogram.mark: 'person' resolves by name
|
|
236
|
+
|
|
237
|
+
const options = {
|
|
238
|
+
chart: { type: 'unit' },
|
|
239
|
+
series: [120, 80],
|
|
240
|
+
labels: ['Employed', 'Unemployed'],
|
|
241
|
+
plotOptions: {
|
|
242
|
+
unit: {
|
|
243
|
+
shape: 'pictogram',
|
|
244
|
+
pictogram: {
|
|
245
|
+
mark: 'person', // a registered name, a { path, viewBox?, fillRule? } object,
|
|
246
|
+
// raw path data, or an array (one per series).
|
|
247
|
+
// A datum's own `mark` overrides all of it, so one crowd can mix glyphs.
|
|
248
|
+
fit: 'contain', // which side of the glyph binds to the dot's box: 'contain' | 'width' | 'height'
|
|
249
|
+
scale: 1, // nudge for glyphs that read light
|
|
250
|
+
padding: 0, // 0..0.9 of the pitch, opening the lattice up
|
|
251
|
+
fallback: 'circle', // drawn when a mark cannot be resolved
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
A glyph is drawn as one `<path>` per unit, filled in that unit's own colour: no request, no decode, no recolour filter, which is why `'pictogram'` is the shape that scales to thousands of units. There is deliberately **no size**: a glyph is fitted to the box the dot itself would have occupied, so `plotOptions.unit.size` and `spacing` size a pictogram exactly as they size a dot.
|
|
259
|
+
|
|
260
|
+
**Shipped glyphs** (each a named export, so import the one you use): `person`, `house`, `heart`, `tree`, `droplet`, `star`, `car`, `bag`, `book`, `cup`, `bulb`, `plane`. `catalog` is every glyph and ships all of them, so avoid it in an app bundle.
|
|
261
|
+
|
|
262
|
+
**Custom glyphs:** `definePictogram({ name, path, viewBox?, fillRule?, category?, source? })` builds one, `registerMarks(defs)` registers them by name, `unregisterMarks(names)` removes them, and `registeredMarkNames()` lists what resolves. Any glyph also has `.with(overrides)` for a variant with some metadata replaced.
|
|
263
|
+
|
|
264
|
+
**Versus `shape: 'image'`:** `'image'` fetches a raster or multi-colour icon (`plotOptions.unit.image.src`, with `tint: true` to recolour a monochrome icon to the category colour). Use it for multi-colour marks that should keep their own colours; use `'pictogram'` for anything that has to scale or follow the palette.
|
|
265
|
+
|
|
222
266
|
**Outer name labels (v6.10):** a shape packed with several categories can name them in the margin with a leader line to their own dots (the pie/donut outer-label mechanism), instead of needing a legend:
|
|
223
267
|
|
|
224
268
|
```js
|
|
@@ -445,3 +489,6 @@ plotOptions: {
|
|
|
445
489
|
10. **Expecting `unit` / `waffle` without a license to be watermark-free**: they are premium and render an `APEXCHARTS` watermark until an entitled `premium`/`enterprise` license is set. Sunburst, by contrast, is free.
|
|
446
490
|
11. **Slice click behavior changed (v6.9)**: clicking a pie/donut slice now slides it out along its own mid-angle (`plotOptions.pie.expandOffset`, default 10 px) instead of darkening it and redrawing it at a larger radius, and hover traces an outline band (`plotOptions.pie.hoverOutline`) instead of lightening the fill. Set `expandOffset: 0` to keep slices in place; set `states.hover.filter.type: 'none'` to suppress the hover band.
|
|
447
491
|
12. **Unit shapes below `minUnits`**: each `apexcharts/unit-shapes` shape declares the minimum dot count at which it still reads. Feeding fewer units logs a console warning naming the shape; pick a simpler shape or raise `unitValue` so the count lands above the threshold.
|
|
492
|
+
13. **Confusing a shape with a pictogram** *(v7.0)*: `plotOptions.unit.positions` (from `apexcharts/unit-shapes`) is **where** the units go; `plotOptions.unit.shape: 'pictogram'` + `pictogram.mark` (from `apexcharts/pictograms`) is **what one unit looks like**. They compose freely.
|
|
493
|
+
14. **Setting a size on a pictogram** *(v7.0)*: there is no `pictogram.size`. A glyph is fitted to the box the dot would have occupied, so use `plotOptions.unit.size` and `spacing`. Use `pictogram.scale` only to nudge a glyph that reads light.
|
|
494
|
+
15. **Pie / radial charts pinned to the top of a tall container** *(fixed v7.1)*: the centre came from `min(width, height)`, so a tall, narrow container put the circle at the top with the leftover space below it. The circle now centres in the height it actually has. If you carried a manual `offsetY` to work around this, remove it.
|
|
@@ -1,8 +1,35 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Feature Platform: ApexCharts
|
|
2
2
|
|
|
3
|
-
ApexCharts
|
|
3
|
+
ApexCharts ships an opt-in feature platform on top of the chart core. **Every v5 and v6 config keeps working unchanged in v7**, apart from the two v7.0 breaking changes noted below. Each feature is off by default in config terms and ships as its own `apexcharts/features/*` entry.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## ⚠️ Read first: two bundle tiers (v7.0)
|
|
6
|
+
|
|
7
|
+
Whether you need the `features/*` import depends on the feature's **tier**, and this changed in v7.0.
|
|
8
|
+
|
|
9
|
+
- **Tier 1** is in the default `import ApexCharts from 'apexcharts'` bundle: `exports`, `legend`, `toolbar`, `annotations`, `keyboard`, `morph`, `drilldown`, `weave`, `marks`, `facet`, `stats`, and the v7.1 `waterfall` / `dumbbell` / `streamgraph` chart types. Import these only if you started from `apexcharts/core` or a per-type entry.
|
|
10
|
+
- **Tier 2 is not in any bundle.** Nine features (`trellis`, `storyboard`, `perspectives`, `ink`, `renderer-canvas`, `link`, `measure`, `history`, `context-menu`) plus the `raincloud` chart type require an explicit import **whatever entry point you used**, the full bundle included.
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
import ApexCharts from 'apexcharts'
|
|
14
|
+
import 'apexcharts/features/trellis' // Tier 2: required even here
|
|
15
|
+
```
|
|
16
|
+
```html
|
|
17
|
+
<script src=".../dist/apexcharts.js"></script>
|
|
18
|
+
<script src=".../dist/features/trellis.js"></script>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Nothing fails silently: each Tier 2 module warns in the console when its configuration is present but the module is not, and names both import routes. Where the chart can still draw something sensible it does and says what it did: a trellis renders as a single chart, `renderer: 'canvas'` falls back to SVG. `apexcharts/features/all` is the **Tier 1** set and is not a shortcut past this.
|
|
22
|
+
|
|
23
|
+
Why: 24% of the 6.10.0 default bundle was licence-gated premium code that an unlicensed user could only run watermarked, and everybody downloaded it. The default bundle went 291,654 B gzipped (6.10.0) to 252,005 B (7.0.0), and 264,326 B in 7.1.0 with the three new free chart types. See `references/tree-shaking.md` for the full tier table and per-module sizes.
|
|
24
|
+
|
|
25
|
+
## Two v7.0 breaking changes
|
|
26
|
+
|
|
27
|
+
1. **`plotOptions.bar.borderRadiusWhenStacked` is removed.** Rounded corners on a stacked bar are no longer a setting: corner ownership follows the **outer edge** of the stack, which is what `'last'` approximated and what `'all'` got wrong on any stack whose last series was empty. An unknown option is ignored, so leaving it in place is harmless but does nothing.
|
|
28
|
+
2. **`dataLabels.animate.enabled` now defaults to `true`** (bar and column only). Labels ride to their new position on a data-change update instead of snapping there, so they reflow on the same clock as the bars, markers and axis ticks. Speed and easing follow `chart.animations.dynamicAnimation`. A label that has not moved is a per-label no-op. Set `dataLabels: { animate: { enabled: false } }` for the old behavior.
|
|
29
|
+
|
|
30
|
+
## Behaviors that are on by default
|
|
31
|
+
|
|
32
|
+
Carried over from v6, both respecting `prefers-reduced-motion`:
|
|
6
33
|
|
|
7
34
|
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
35
|
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`).
|
|
@@ -18,10 +45,11 @@ Two update behaviors worth knowing (both 6.9/6.10):
|
|
|
18
45
|
|
|
19
46
|
## Licensing: premium features and the trial watermark
|
|
20
47
|
|
|
21
|
-
Introduced in **6.5.0**, tightened in **6.7.0**. Not every
|
|
48
|
+
Introduced in **6.5.0**, tightened in **6.7.0**. Not every feature is free. Eight feature modules plus two chart types are **premium** and run under a lightweight, offline license check. They keep working fully without a key (trial mode), but the chart shows an unobtrusive `APEXCHARTS` watermark until an entitled license is set.
|
|
22
49
|
|
|
23
50
|
**The premium set (watermarked until entitled):**
|
|
24
51
|
|
|
52
|
+
- `trellis` (small multiples, premium since **7.0.0**)
|
|
25
53
|
- `storyboard` (scrollytelling)
|
|
26
54
|
- `link` (crossfilter / linked views)
|
|
27
55
|
- `ink` (annotation authoring)
|
|
@@ -30,8 +58,11 @@ Introduced in **6.5.0**, tightened in **6.7.0**. Not every v6 feature is free. S
|
|
|
30
58
|
- `perspectives` (shareable view state)
|
|
31
59
|
- `history` (undo/redo, Rewind)
|
|
32
60
|
- the `unit` / `waffle` chart type (premium since **6.6.0**, the first premium chart type)
|
|
61
|
+
- the `raincloud` chart type (premium since **7.1.0**)
|
|
62
|
+
|
|
63
|
+
**Everything else is free and never gated**: every other chart type (`sunburst`, and the v7.1 `waterfall` / `dumbbell` / `streamgraph`), and every other module (Weave, Strata / canvas, Marks, Facet / themes, Cadence, drilldown, streaming, exports, legend, toolbar, annotations, keyboard, stats).
|
|
33
64
|
|
|
34
|
-
**
|
|
65
|
+
**Premium and Tier 2 are independent axes.** Premium is about the watermark; Tier 2 is about the bundle. `renderer-canvas` is Tier 2 and free. `waterfall`, `dumbbell` and `streamgraph` are Tier 1 and free. `unit` / `waffle` is premium but Tier 1 (it is a chart type in the default bundle). `trellis` and `raincloud` are both.
|
|
35
66
|
|
|
36
67
|
### Setting a license
|
|
37
68
|
|
|
@@ -55,9 +86,73 @@ As of **6.7.0** the premium features clear the watermark only on a `premium` or
|
|
|
55
86
|
|
|
56
87
|
---
|
|
57
88
|
|
|
89
|
+
## Trellis: small multiples that agree to the pixel (7.0)
|
|
90
|
+
|
|
91
|
+
`import 'apexcharts/features/trellis'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
92
|
+
|
|
93
|
+
One dataset split into a grid of real charts that share a scale, a legend, a toolbar and a crosshair. Setting `trellis.by` makes the chart a trellis **host**: the series array is split into one panel per facet-key value, every panel is a real chart of the host's `chart.type`, and the trellis owns everything shared.
|
|
94
|
+
|
|
95
|
+
```js
|
|
96
|
+
import ApexCharts from 'apexcharts'
|
|
97
|
+
import 'apexcharts/features/trellis'
|
|
98
|
+
|
|
99
|
+
new ApexCharts(el, {
|
|
100
|
+
chart: { type: 'line' },
|
|
101
|
+
series: [
|
|
102
|
+
{ name: 'Revenue', region: 'North', data: north },
|
|
103
|
+
{ name: 'Revenue', region: 'South', data: south },
|
|
104
|
+
],
|
|
105
|
+
trellis: { by: 'region', minPanelWidth: 260 },
|
|
106
|
+
}).render()
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`trellis.by` is the whole configuration. The grid owns the y domain (the union across panels), the x window, and a column count computed from `minPanelWidth` alone. **A series carrying no facet key repeats in every panel**, which is how you get a reference line.
|
|
110
|
+
|
|
111
|
+
**In TypeScript**, use the typed `facet` field rather than an arbitrary key, or the series objects will not typecheck:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
series: [
|
|
115
|
+
{ name: 'Revenue', facet: 'North', data: north },
|
|
116
|
+
{ name: 'Revenue', facet: 'South', data: south },
|
|
117
|
+
],
|
|
118
|
+
trellis: { by: 'facet', minPanelWidth: 260 },
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Facet accessors.** `by` is a key name on each series object (`facet` is the blessed typed field; any other key name works from plain JS) or a function `(series, index) => key`, which works from either. For a 2-D grid use `row` × `column` instead of `by`: every (row, column) combination in row-major order at a fixed column count, column labels once across the top, row labels once down the left. A series carrying only the row key repeats across that row.
|
|
122
|
+
|
|
123
|
+
**Tidy-row input.** `trellis.data` takes a row table instead of `series`, pivoted by the `by` / `x` / `y` / `seriesBy` **column names**. Rows win over `series` when both are given; duplicate (panel, series, x) rows keep the last and warn, so aggregate first.
|
|
124
|
+
|
|
125
|
+
| Option | Default | Notes |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| `columns` | `'auto'` | `'auto'` fits `minPanelWidth` columns into the container. |
|
|
128
|
+
| `minPanelWidth` | `220` | Drives `'auto'` columns and the responsive collapse. |
|
|
129
|
+
| `gap` / `aspectRatio` / `panelHeight` | `12` / `1.6` / none | `panelHeight` wins over `aspectRatio` and `chart.height`. |
|
|
130
|
+
| `order` | `'first-seen'` | Also `'asc'`, `'desc'`, an explicit `string[]`, or a comparator. |
|
|
131
|
+
| `limit` | none | Render only the first N panels (warns about the rest). |
|
|
132
|
+
| `virtualize` | `'auto'` | Mounts only panels intersecting the viewport (plus one row) once the grid exceeds **64 panels**. An unmounted cell keeps its header and a fixed-height skeleton so page height never shifts; a remount restores its zoom window. **`getPanel(key)` returns `null` for an unmounted panel.** |
|
|
133
|
+
| `scales` | `{ x: 'shared', y: 'shared' }` | `y` also takes `'independent-row'` / `'independent-column'` in a 2-D grid. Non-shared `y` still renders pixel-aligned panels. |
|
|
134
|
+
| `emptyPanels` | `'placeholder'` | Missing (row, column) combos: a real empty panel with `noData.text`, or `'skip'` (tinted blank) or `'hide'`. |
|
|
135
|
+
| `axes.labels` | `'edges'` | y labels on the first column, x labels on each column's bottom panel. Label *space* is always reserved everywhere so panels stay aligned. Also `'all'` / `'none'`. |
|
|
136
|
+
| `legend` / `toolbar` | `'shared'` | One legend (toggles a series name in every panel) and one zoom/pan/reset toolbar. `'none'` to drop. |
|
|
137
|
+
| `tooltip` | `'panel'` | Card in the hovered panel while the crosshair sweeps all. `'sync'` = a card per panel; `'grid'` = one card near the cursor with a row per panel, composed from the panels' own tooltips so every formatter is honored. |
|
|
138
|
+
| `zoom` | `'sync'` | A zoom in any panel moves every panel. |
|
|
139
|
+
| `promote` | `true` | Clicking a header expands that panel to full width with an "All panels" breadcrumb. |
|
|
140
|
+
| `radiusByTotal` | `false` | Pie/donut/polarArea only: scale each panel's radius so its **area** is proportional to the panel's total. Equal-size pies cannot encode magnitude, so set this on a pie trellis. |
|
|
141
|
+
| `targetTicks` | `3` | Tick-interval target for the shared nice y scale, so a small panel wears few labels. |
|
|
142
|
+
| `header` | shown | `{ show, formatter(key, { dimension, index, count }), style }`. |
|
|
143
|
+
| `panel` | none | `(key, { index, seriesNames }) => ApexOptions`, a per-panel override applied last. |
|
|
144
|
+
|
|
145
|
+
**API.** `chart.getPanels()` returns the panels in grid order; `chart.getPanel(key)` returns one panel's own ApexCharts instance (the escape hatch to every per-chart API the trellis does not re-expose); `chart.promotePanel(key)` / `chart.restorePanels()` drive the promotion from code. `ApexCharts.trellis(el, options)` is the imperative constructor and throws if the feature is not imported.
|
|
146
|
+
|
|
147
|
+
**Annotations** take `scope`: absent or `'trellis'` draws in every panel through each panel's own scale, a key or array of keys restricts it.
|
|
148
|
+
|
|
149
|
+
**Per-type guardrails** keep a shared frame honest: histograms share a bin frame, violins a bandwidth, heatmaps one colour scale and a single gradient legend.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
58
153
|
## Weave: public plugin platform
|
|
59
154
|
|
|
60
|
-
`import 'apexcharts/features/weave'
|
|
155
|
+
`import 'apexcharts/features/weave'`: Tier 1 (already in the default bundle).
|
|
61
156
|
|
|
62
157
|
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.
|
|
63
158
|
|
|
@@ -98,7 +193,7 @@ The `setup(api)` facade:
|
|
|
98
193
|
|
|
99
194
|
## Strata: hybrid SVG + canvas renderer
|
|
100
195
|
|
|
101
|
-
`import 'apexcharts/features/renderer-canvas'
|
|
196
|
+
`import 'apexcharts/features/renderer-canvas'`: **Tier 2** (not in the default bundle). Free.
|
|
102
197
|
|
|
103
198
|
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.
|
|
104
199
|
|
|
@@ -121,7 +216,7 @@ Canvas is live for line, area, bar, column, scatter, and candlestick, with share
|
|
|
121
216
|
|
|
122
217
|
## Marks: composable custom series types
|
|
123
218
|
|
|
124
|
-
`import 'apexcharts/features/marks'
|
|
219
|
+
`import 'apexcharts/features/marks'`: Tier 1 (already in the default bundle).
|
|
125
220
|
|
|
126
221
|
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.
|
|
127
222
|
|
|
@@ -158,7 +253,7 @@ Dumbbell uses `dataType: 'rangeXY'` (datum `y` is `[start, end]`, both bounds fo
|
|
|
158
253
|
|
|
159
254
|
## Rewind: history and undo/redo
|
|
160
255
|
|
|
161
|
-
`import 'apexcharts/features/history'
|
|
256
|
+
`import 'apexcharts/features/history'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
162
257
|
|
|
163
258
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
164
259
|
|
|
@@ -181,7 +276,7 @@ chart.history.entries() // [{ id, label, at }]
|
|
|
181
276
|
|
|
182
277
|
## Perspectives: shareable view state
|
|
183
278
|
|
|
184
|
-
`import 'apexcharts/features/perspectives'
|
|
279
|
+
`import 'apexcharts/features/perspectives'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
185
280
|
|
|
186
281
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
187
282
|
|
|
@@ -208,7 +303,7 @@ const options = { chart: { perspectives: { serializeOptions: ['colors', 'title']
|
|
|
208
303
|
|
|
209
304
|
## Facet: design tokens and OS-aware themes
|
|
210
305
|
|
|
211
|
-
`import 'apexcharts/features/facet'
|
|
306
|
+
`import 'apexcharts/features/facet'`: Tier 1 (already in the default bundle).
|
|
212
307
|
|
|
213
308
|
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.
|
|
214
309
|
|
|
@@ -265,7 +360,7 @@ Built-in curve names: `linear`, `easeInSine`, `easeOutSine`, `easeInOutSine`, `e
|
|
|
265
360
|
|
|
266
361
|
## Link: crossfilter and cross-chart coordination
|
|
267
362
|
|
|
268
|
-
`import 'apexcharts/features/link'
|
|
363
|
+
`import 'apexcharts/features/link'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
269
364
|
|
|
270
365
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
271
366
|
|
|
@@ -303,7 +398,7 @@ const b = {
|
|
|
303
398
|
|
|
304
399
|
## Ink: direct-manipulation annotation authoring
|
|
305
400
|
|
|
306
|
-
`import 'apexcharts/features/ink'
|
|
401
|
+
`import 'apexcharts/features/ink'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
307
402
|
|
|
308
403
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
309
404
|
|
|
@@ -327,7 +422,7 @@ const options = {
|
|
|
327
422
|
|
|
328
423
|
## Measure: delta ruler
|
|
329
424
|
|
|
330
|
-
`import 'apexcharts/features/measure'
|
|
425
|
+
`import 'apexcharts/features/measure'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
331
426
|
|
|
332
427
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
333
428
|
|
|
@@ -376,7 +471,7 @@ const options = {
|
|
|
376
471
|
|
|
377
472
|
## Context menu: Radial Actions
|
|
378
473
|
|
|
379
|
-
`import 'apexcharts/features/context-menu'
|
|
474
|
+
`import 'apexcharts/features/context-menu'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
380
475
|
|
|
381
476
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
382
477
|
|
|
@@ -404,7 +499,7 @@ Built-in `annotate` / `xline` / `yline` items are ink-managed when the ink featu
|
|
|
404
499
|
|
|
405
500
|
## Storyboard: scroll-driven choreography (scrollytelling)
|
|
406
501
|
|
|
407
|
-
`import 'apexcharts/features/storyboard'` (
|
|
502
|
+
`import 'apexcharts/features/storyboard'` (registers Perspectives too): **Tier 2** (not in the default bundle) and **premium**.
|
|
408
503
|
|
|
409
504
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
410
505
|
|
|
@@ -442,7 +537,7 @@ const options = { chart: { streaming: { enabled: true, maxPoints: 100000 } } }
|
|
|
442
537
|
|
|
443
538
|
## Drilldown: hierarchical drill-down
|
|
444
539
|
|
|
445
|
-
`import 'apexcharts/features/drilldown'` (add `import 'apexcharts/features/morph'` for animated cross-type transitions)
|
|
540
|
+
`import 'apexcharts/features/drilldown'` (add `import 'apexcharts/features/morph'` for animated cross-type transitions): both Tier 1 (already in the default bundle).
|
|
446
541
|
|
|
447
542
|
Data points reference a child level via a `drilldown` id; clicking drills in, with an optional breadcrumb. Since **v6.9** drilldown also works on **line and area** charts, and levels can be resolved **async** against a backend.
|
|
448
543
|
|
|
@@ -494,7 +589,7 @@ chart.drillToRoot()
|
|
|
494
589
|
|
|
495
590
|
## Stats: raw-sample statistics (6.9.0)
|
|
496
591
|
|
|
497
|
-
`import 'apexcharts/features/stats'
|
|
592
|
+
`import 'apexcharts/features/stats'`: Tier 1 (already in the default bundle).
|
|
498
593
|
|
|
499
594
|
Free. The statistics behind three things, kept out of core so they cost nothing unless used:
|
|
500
595
|
|
|
@@ -536,8 +631,11 @@ const options = {
|
|
|
536
631
|
|
|
537
632
|
## Common Pitfalls
|
|
538
633
|
|
|
539
|
-
1. **
|
|
540
|
-
2. **
|
|
541
|
-
3. **
|
|
542
|
-
4.
|
|
543
|
-
5. **
|
|
634
|
+
1. **Assuming the full bundle still carries everything *(the #1 v6 → v7 mistake)*.** In v6, `import ApexCharts from 'apexcharts'` was enough for every feature. In v7 the nine Tier 2 features and the `raincloud` type need their own import on top of it. Read the console: each one names both routes when its config is present without it.
|
|
635
|
+
2. **Forgetting the feature import on a tree-shaken build**: a Tier 1 feature is in the default bundle but not in `apexcharts/core` or a per-type entry, so those builds still need `import 'apexcharts/features/<name>'`.
|
|
636
|
+
3. **Reaching for `apexcharts/features/all` to fix either of the above**: it is the Tier 1 set only, by design (`tests/unit/feature-tier-budget.spec.js` upstream fails the build if a Tier 2 feature reappears in it).
|
|
637
|
+
4. **Using `api.zeroY` in a custom mark**: it does not exist. Use `ctx.scales.y(0)` for the baseline.
|
|
638
|
+
5. **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.
|
|
639
|
+
6. **Two different `largeDatasetThreshold` options.** `chart.animations.largeDatasetThreshold` (default 1000) skips update animations; `markers.largeDatasetThreshold` *(v7.0, default 0 = off)* batches a series' markers into one path. Neither lives on `chart` directly.
|
|
640
|
+
7. **Assuming the canvas renderer supports everything**: pattern/image fills and per-point selection visuals fall back to (or stay) SVG.
|
|
641
|
+
8. **Calling `getPanel(key)` on a virtualized trellis**: it returns `null` for a panel that is not currently mounted (grids over 64 panels virtualize by default).
|