apexcharts-skill 2.1.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 +156 -59
- package/index.js +1 -1
- package/package.json +1 -1
- package/references/bar-charts.md +126 -4
- package/references/cartesian-charts.md +77 -1
- package/references/circular-charts.md +119 -4
- package/references/{v6-features.md → feature-platform.md} +153 -25
- package/references/financial-charts.md +179 -5
- package/references/grid-charts.md +50 -0
- package/references/tree-shaking.md +121 -28
|
@@ -1,22 +1,55 @@
|
|
|
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`).
|
|
9
36
|
|
|
10
37
|
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
38
|
|
|
39
|
+
Two update behaviors worth knowing (both 6.9/6.10):
|
|
40
|
+
|
|
41
|
+
- **Function-valued options are compared by identity (6.10)**: `update()` skips a redundant render by comparing the incoming options with the previous ones. Passing a *different* function (a new `dataLabels.formatter`, custom tooltip, `plotOptions.unit.positions`) gets the render it asked for; passing the *same* function twice still skips. Building a fresh closure on every update means a render every time.
|
|
42
|
+
- **A type change re-chooses type defaults (6.9)**: `updateOptions({ chart: { type } })` now re-picks the defaults that decide what a chart reads, says, hit-tests, or offers as interaction (e.g. a boxPlot-to-violin switch gets the right tooltip formatter). Deliberate paint choices and anything you set yourself are never re-chosen.
|
|
43
|
+
|
|
12
44
|
---
|
|
13
45
|
|
|
14
46
|
## Licensing: premium features and the trial watermark
|
|
15
47
|
|
|
16
|
-
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.
|
|
17
49
|
|
|
18
50
|
**The premium set (watermarked until entitled):**
|
|
19
51
|
|
|
52
|
+
- `trellis` (small multiples, premium since **7.0.0**)
|
|
20
53
|
- `storyboard` (scrollytelling)
|
|
21
54
|
- `link` (crossfilter / linked views)
|
|
22
55
|
- `ink` (annotation authoring)
|
|
@@ -25,8 +58,11 @@ Introduced in **6.5.0**, tightened in **6.7.0**. Not every v6 feature is free. S
|
|
|
25
58
|
- `perspectives` (shareable view state)
|
|
26
59
|
- `history` (undo/redo, Rewind)
|
|
27
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**)
|
|
28
62
|
|
|
29
|
-
**Everything else is free and never gated**: every other chart type (
|
|
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).
|
|
64
|
+
|
|
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.
|
|
30
66
|
|
|
31
67
|
### Setting a license
|
|
32
68
|
|
|
@@ -50,9 +86,73 @@ As of **6.7.0** the premium features clear the watermark only on a `premium` or
|
|
|
50
86
|
|
|
51
87
|
---
|
|
52
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
|
+
|
|
53
153
|
## Weave: public plugin platform
|
|
54
154
|
|
|
55
|
-
`import 'apexcharts/features/weave'
|
|
155
|
+
`import 'apexcharts/features/weave'`: Tier 1 (already in the default bundle).
|
|
56
156
|
|
|
57
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.
|
|
58
158
|
|
|
@@ -93,7 +193,7 @@ The `setup(api)` facade:
|
|
|
93
193
|
|
|
94
194
|
## Strata: hybrid SVG + canvas renderer
|
|
95
195
|
|
|
96
|
-
`import 'apexcharts/features/renderer-canvas'
|
|
196
|
+
`import 'apexcharts/features/renderer-canvas'`: **Tier 2** (not in the default bundle). Free.
|
|
97
197
|
|
|
98
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.
|
|
99
199
|
|
|
@@ -116,7 +216,7 @@ Canvas is live for line, area, bar, column, scatter, and candlestick, with share
|
|
|
116
216
|
|
|
117
217
|
## Marks: composable custom series types
|
|
118
218
|
|
|
119
|
-
`import 'apexcharts/features/marks'
|
|
219
|
+
`import 'apexcharts/features/marks'`: Tier 1 (already in the default bundle).
|
|
120
220
|
|
|
121
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.
|
|
122
222
|
|
|
@@ -153,7 +253,7 @@ Dumbbell uses `dataType: 'rangeXY'` (datum `y` is `[start, end]`, both bounds fo
|
|
|
153
253
|
|
|
154
254
|
## Rewind: history and undo/redo
|
|
155
255
|
|
|
156
|
-
`import 'apexcharts/features/history'
|
|
256
|
+
`import 'apexcharts/features/history'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
157
257
|
|
|
158
258
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
159
259
|
|
|
@@ -176,7 +276,7 @@ chart.history.entries() // [{ id, label, at }]
|
|
|
176
276
|
|
|
177
277
|
## Perspectives: shareable view state
|
|
178
278
|
|
|
179
|
-
`import 'apexcharts/features/perspectives'
|
|
279
|
+
`import 'apexcharts/features/perspectives'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
180
280
|
|
|
181
281
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
182
282
|
|
|
@@ -203,7 +303,7 @@ const options = { chart: { perspectives: { serializeOptions: ['colors', 'title']
|
|
|
203
303
|
|
|
204
304
|
## Facet: design tokens and OS-aware themes
|
|
205
305
|
|
|
206
|
-
`import 'apexcharts/features/facet'
|
|
306
|
+
`import 'apexcharts/features/facet'`: Tier 1 (already in the default bundle).
|
|
207
307
|
|
|
208
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.
|
|
209
309
|
|
|
@@ -260,7 +360,7 @@ Built-in curve names: `linear`, `easeInSine`, `easeOutSine`, `easeInOutSine`, `e
|
|
|
260
360
|
|
|
261
361
|
## Link: crossfilter and cross-chart coordination
|
|
262
362
|
|
|
263
|
-
`import 'apexcharts/features/link'
|
|
363
|
+
`import 'apexcharts/features/link'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
264
364
|
|
|
265
365
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
266
366
|
|
|
@@ -298,7 +398,7 @@ const b = {
|
|
|
298
398
|
|
|
299
399
|
## Ink: direct-manipulation annotation authoring
|
|
300
400
|
|
|
301
|
-
`import 'apexcharts/features/ink'
|
|
401
|
+
`import 'apexcharts/features/ink'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
302
402
|
|
|
303
403
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
304
404
|
|
|
@@ -322,7 +422,7 @@ const options = {
|
|
|
322
422
|
|
|
323
423
|
## Measure: delta ruler
|
|
324
424
|
|
|
325
|
-
`import 'apexcharts/features/measure'
|
|
425
|
+
`import 'apexcharts/features/measure'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
326
426
|
|
|
327
427
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
328
428
|
|
|
@@ -371,7 +471,7 @@ const options = {
|
|
|
371
471
|
|
|
372
472
|
## Context menu: Radial Actions
|
|
373
473
|
|
|
374
|
-
`import 'apexcharts/features/context-menu'
|
|
474
|
+
`import 'apexcharts/features/context-menu'`: **Tier 2** (not in the default bundle) and **premium**.
|
|
375
475
|
|
|
376
476
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
377
477
|
|
|
@@ -399,7 +499,7 @@ Built-in `annotate` / `xline` / `yline` items are ink-managed when the ink featu
|
|
|
399
499
|
|
|
400
500
|
## Storyboard: scroll-driven choreography (scrollytelling)
|
|
401
501
|
|
|
402
|
-
`import 'apexcharts/features/storyboard'` (
|
|
502
|
+
`import 'apexcharts/features/storyboard'` (registers Perspectives too): **Tier 2** (not in the default bundle) and **premium**.
|
|
403
503
|
|
|
404
504
|
**Premium** (watermarked in trial mode until an entitled license is set, see Licensing above).
|
|
405
505
|
|
|
@@ -437,9 +537,9 @@ const options = { chart: { streaming: { enabled: true, maxPoints: 100000 } } }
|
|
|
437
537
|
|
|
438
538
|
## Drilldown: hierarchical drill-down
|
|
439
539
|
|
|
440
|
-
`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).
|
|
441
541
|
|
|
442
|
-
Data points reference a child level via a `drilldown` id; clicking drills in, with an optional breadcrumb.
|
|
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.
|
|
443
543
|
|
|
444
544
|
```js
|
|
445
545
|
import 'apexcharts/features/drilldown'
|
|
@@ -457,14 +557,23 @@ const options = {
|
|
|
457
557
|
series: [
|
|
458
558
|
{ id: '2021', name: '2021 by Channel', data: [/* ... */], chart: { type: 'bar' } },
|
|
459
559
|
],
|
|
460
|
-
// or resolve lazily:
|
|
461
|
-
onDrillDown: (ctx) => ({ id: ctx.point.drilldown, name: '...', data:
|
|
560
|
+
// or resolve lazily; may return a Promise (v6.9):
|
|
561
|
+
onDrillDown: async (ctx) => ({ id: ctx.point.drilldown, name: '...', data: await fetchLevel(ctx) }),
|
|
562
|
+
loading: { show: true, text: 'Loading' }, // (v6.9) overlay while an async level resolves;
|
|
563
|
+
// false disables it. role="status", aria-live="polite",
|
|
564
|
+
// spinner flattens to a pulse under prefers-reduced-motion
|
|
565
|
+
cache: true, // (v6.9) cache onDrillDown results by id (default true);
|
|
566
|
+
// clear with the drilldown module's clearCache()
|
|
567
|
+
// (v6.9) line/area only: the dot marking a drillable point when the chart
|
|
568
|
+
// draws no markers. Only drillable points get one, so it reads as "these open".
|
|
569
|
+
marker: { show: true, size: 6, shape: 'circle', fillColor: undefined, strokeColor: '#fff' },
|
|
462
570
|
},
|
|
463
571
|
chart: {
|
|
464
572
|
events: {
|
|
465
573
|
drillDownStart: (info, chart, options) => {},
|
|
466
574
|
drillDownEnd: (info, chart, options) => {},
|
|
467
575
|
drillUp: (info, chart, options) => {},
|
|
576
|
+
drillDownError: ({ id, error }, chart, options) => {}, // (v6.9) async level failed
|
|
468
577
|
},
|
|
469
578
|
},
|
|
470
579
|
}
|
|
@@ -474,6 +583,22 @@ chart.drillUp()
|
|
|
474
583
|
chart.drillToRoot()
|
|
475
584
|
```
|
|
476
585
|
|
|
586
|
+
**Async failure semantics (v6.9):** a failed fetch never strands the view. On a throw, a rejection, or a resolver returning something without a `data` array, the chart stays where it was, the breadcrumb is untouched, nothing is cached, and `drillDownError` fires. A second click while one resolve is in flight is ignored rather than starting a second request.
|
|
587
|
+
|
|
588
|
+
---
|
|
589
|
+
|
|
590
|
+
## Stats: raw-sample statistics (6.9.0)
|
|
591
|
+
|
|
592
|
+
`import 'apexcharts/features/stats'`: Tier 1 (already in the default bundle).
|
|
593
|
+
|
|
594
|
+
Free. The statistics behind three things, kept out of core so they cost nothing unless used:
|
|
595
|
+
|
|
596
|
+
- **Histogram binning**: `chart.type: 'histogram'` bins raw observations (the `apexcharts/histogram` entry includes this feature automatically).
|
|
597
|
+
- **Raw samples for boxPlot and violin**: a datum supplying `points: [number]` instead of a summary `y` gets its quartiles (R type 7) or KDE density computed.
|
|
598
|
+
- **`chart.rowSeries(opts?)`**: returns the rows behind the chart's marks as a unit-chart series (one cluster per mark), or `null` when the type has no row source. `chart.updateOptions({ chart: { type: 'unit' }, series: chart.rowSeries() })` opens a summary into its observations; with the `morph` feature loaded each dot leaves from the part of the mark that stood for it.
|
|
599
|
+
|
|
600
|
+
Full data shapes and options are in `references/financial-charts.md`. The full `apexcharts` bundle includes it.
|
|
601
|
+
|
|
477
602
|
---
|
|
478
603
|
|
|
479
604
|
## Point annotation tooltips (6.7.0)
|
|
@@ -506,8 +631,11 @@ const options = {
|
|
|
506
631
|
|
|
507
632
|
## Common Pitfalls
|
|
508
633
|
|
|
509
|
-
1. **
|
|
510
|
-
2. **
|
|
511
|
-
3. **
|
|
512
|
-
4.
|
|
513
|
-
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).
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
- **Candlestick** (`'candlestick'`) — OHLC (Open, High, Low, Close) financial chart
|
|
6
6
|
- **Box Plot** (`'boxPlot'`) — Statistical distribution chart showing min, Q1, median, Q3, max
|
|
7
7
|
- **Violin** (`'violin'`, **new in v6**): Statistical distribution chart showing a density curve per category, optionally with the raw sample points overlaid as jitter
|
|
8
|
+
- **Histogram** (`'histogram'`, **new in v6.9**): Bins raw observations into columns; the series carries the sample, the chart does the aggregating
|
|
9
|
+
- **Raincloud** (`'raincloud'`, **new in v7.1, premium, Tier 2**): A distribution shown three ways at once: a half-violin for the shape, a box for the summary, and the observations themselves as "rain" underneath
|
|
8
10
|
|
|
9
11
|
## Tree-Shakeable Import
|
|
10
12
|
|
|
@@ -15,8 +17,23 @@ import ApexCharts from 'apexcharts/candlestick'
|
|
|
15
17
|
|
|
16
18
|
import ApexCharts from 'apexcharts/violin'
|
|
17
19
|
// Registers: violin (separate entry point, new in v6)
|
|
20
|
+
|
|
21
|
+
import ApexCharts from 'apexcharts/histogram'
|
|
22
|
+
// Registers: histogram (v6.9), the bar engine plus the stats feature
|
|
23
|
+
|
|
24
|
+
import ApexCharts from 'apexcharts/raincloud'
|
|
25
|
+
// Registers: raincloud (v7.1), the violin engine plus the raincloud feature
|
|
26
|
+
|
|
27
|
+
// The statistics (histogram binning, boxPlot/violin raw-sample summaries,
|
|
28
|
+
// rowSeries()) live behind one optional feature. apexcharts/histogram already
|
|
29
|
+
// includes it; boxPlot/violin raw samples need it explicitly when tree-shaking:
|
|
30
|
+
import 'apexcharts/features/stats'
|
|
18
31
|
```
|
|
19
32
|
|
|
33
|
+
**⚠️ Raincloud is Tier 2 (v7.1).** Unlike every other chart type, it is **not in the default `apexcharts` bundle**. On the full bundle add `import 'apexcharts/raincloud'` (or `import 'apexcharts/features/raincloud'`); from a script tag add `dist/features/raincloud.js` after `apexcharts.js`. It is also premium, so it renders an `APEXCHARTS` watermark until an entitled license is set.
|
|
34
|
+
|
|
35
|
+
**Raw samples (v6.9):** boxPlot, violin, and histogram can all take the raw observations and compute the statistics themselves (quartiles for boxPlot, KDE density for violin, bin counts for histogram). Precomputed summaries keep working exactly as before. With the full `apexcharts` bundle the stats feature is always present; with tree-shaking entries it must be imported (without it, a raw-sample boxPlot/violin datum has nothing to summarize and a histogram warns and draws nothing).
|
|
36
|
+
|
|
20
37
|
---
|
|
21
38
|
|
|
22
39
|
## Data Formats
|
|
@@ -72,11 +89,39 @@ The `y` value must be an array of exactly 5 numbers: `[min, Q1, median, Q3, max]
|
|
|
72
89
|
}
|
|
73
90
|
```
|
|
74
91
|
|
|
92
|
+
### Box Plot: Raw Sample (v6.9)
|
|
93
|
+
|
|
94
|
+
Instead of a five-number `y`, a datum may supply the raw observations in `points` and the library computes the summary (quartiles interpolate between ranks, R type 7). Requires `apexcharts/features/stats` when tree-shaking. `points` is the same field used for the jitter-dot overlay, so the sample lives in one place whether you summarize it or the library does.
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
{
|
|
98
|
+
chart: { type: 'boxPlot', height: 350 },
|
|
99
|
+
series: [{
|
|
100
|
+
data: [
|
|
101
|
+
{ x: 'Phone', points: [1.2, 1.9, 3.4, 2.2, 2.8, 4.1, 1.7] },
|
|
102
|
+
{ x: 'Tablet', points: [2.4, 3.1, 3.9, 2.9, 4.6, 3.3] }
|
|
103
|
+
]
|
|
104
|
+
}],
|
|
105
|
+
plotOptions: {
|
|
106
|
+
boxPlot: {
|
|
107
|
+
whiskers: 'minmax', // 'minmax' (default): whiskers reach the extremes, nothing hidden
|
|
108
|
+
// 'tukey': stop at the last observation within 1.5 × IQR of each quartile
|
|
109
|
+
points: { show: true } // overlay the observations as jitter dots
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
- `whiskers` only applies when the summary is **derived** from `points`; a precomputed five-number `y` is drawn exactly as given.
|
|
116
|
+
- With `whiskers: 'tukey'`, observations beyond the fence fall outside the whisker, so pair it with `points: { show: true }` or they become invisible.
|
|
117
|
+
- `plotOptions.boxPlot.points` also takes `shape` (`'circle'` | `'square'`), `size`, `jitter` (0..1 fraction of the box half-width), `maxPoints` (cap per box, stride-thinned beyond), `opacity`, `fillColor` (`'series-dark'` default | `'series'` | any color), `strokeColor`, `strokeWidth`, and a value-driven `colorScale: { colors, min, max, steps }`.
|
|
118
|
+
- A datum with both `y` and `points` draws the given summary and overlays the points as jitter.
|
|
119
|
+
|
|
75
120
|
### Violin: Density Profile (v6)
|
|
76
121
|
|
|
77
122
|
Each point is `{ x, y: { density, points } }`:
|
|
78
123
|
|
|
79
|
-
- `density
|
|
124
|
+
- `density`: an array of `[value, weight]` pairs describing the precomputed density/KDE profile. Drawn exactly as given.
|
|
80
125
|
- `points` (optional): a flat array of raw observations, rendered as jitter dots.
|
|
81
126
|
|
|
82
127
|
```js
|
|
@@ -111,6 +156,32 @@ Each point is `{ x, y: { density, points } }`:
|
|
|
111
156
|
}
|
|
112
157
|
```
|
|
113
158
|
|
|
159
|
+
### Violin: Raw Sample (v6.9)
|
|
160
|
+
|
|
161
|
+
A datum may instead supply only the raw observations (in `points`, no `y`) and the library derives the density itself via kernel density estimation. Requires `apexcharts/features/stats` when tree-shaking. `plotOptions.violin.kde` tunes the estimation; it is ignored when a precomputed `density` profile is given.
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
{
|
|
165
|
+
chart: { type: 'violin', height: 420 },
|
|
166
|
+
series: [{
|
|
167
|
+
name: 'Session duration',
|
|
168
|
+
data: [
|
|
169
|
+
{ x: 'Direct', points: [22, 31, 38, 41, 47, 52, 58, 33, 40] },
|
|
170
|
+
{ x: 'Referral', points: [27, 34, 44, 48, 53, 61, 39] }
|
|
171
|
+
]
|
|
172
|
+
}],
|
|
173
|
+
plotOptions: {
|
|
174
|
+
violin: {
|
|
175
|
+
kde: {
|
|
176
|
+
bandwidth: undefined, // kernel width in value units; unset = Silverman's rule of thumb
|
|
177
|
+
resolution: 64 // density samples per violin (default 64)
|
|
178
|
+
},
|
|
179
|
+
points: { show: true } // the same sample doubles as the jitter overlay
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
114
185
|
**Orientation and per-category color come from `plotOptions.bar`** (violin reuses the bar renderer):
|
|
115
186
|
|
|
116
187
|
```js
|
|
@@ -123,6 +194,103 @@ plotOptions: {
|
|
|
123
194
|
}
|
|
124
195
|
```
|
|
125
196
|
|
|
197
|
+
### Histogram (v6.9)
|
|
198
|
+
|
|
199
|
+
The series carries **raw observations** (a flat number array, or `{ y }` objects), one number per event; the chart chooses the bin width and counts them. It renders through the bar pathway (like funnel, pyramid, gauge, and waffle), so stacking, zoom, export, and animation all work on the bins. Import from `apexcharts/histogram`, or add `import 'apexcharts/features/stats'` alongside `apexcharts/bar`; the full `apexcharts` bundle already includes it. Without the stats feature the chart warns and draws nothing.
|
|
200
|
+
|
|
201
|
+
```js
|
|
202
|
+
{
|
|
203
|
+
chart: { type: 'histogram', height: 350 },
|
|
204
|
+
series: [{ name: 'Latency', data: [102, 87, 143, 91, 118, 95, 132, 88, 107] }],
|
|
205
|
+
plotOptions: {
|
|
206
|
+
histogram: {
|
|
207
|
+
bins: 'auto', // 'auto' | 'fd' | 'sturges' | 'scott' | 'rice' | 'sqrt' | number (fixed count)
|
|
208
|
+
// 'auto' takes the narrower of Freedman-Diaconis and Sturges
|
|
209
|
+
binWidth: undefined, // explicit bin width in value units; wins over `bins` when the
|
|
210
|
+
// boundaries carry meaning (decades, 5-minute buckets)
|
|
211
|
+
range: undefined, // [min, max] to bin over instead of the data's own extent
|
|
212
|
+
normalize: 'count', // 'count' | 'relative' (percent of series total) | 'density' (total area = 1)
|
|
213
|
+
cumulative: false, // running total across bins (a CDF)
|
|
214
|
+
overlap: true // multi-series: draw each series across the full bin (overlay).
|
|
215
|
+
// false = side-by-side grouped bars per bin
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
- **All series share one set of bin edges** derived from their combined extent, so two distributions stay comparable instead of putting different bars at the same x.
|
|
222
|
+
- `overlap: true` (the default with multiple series) also softens the fill and drops the bin separator stroke so the overlapping region reads; both remain overridable. A single series is unaffected either way.
|
|
223
|
+
- Do NOT pass pre-aggregated counts; that is a plain `bar` chart. The histogram's job is the binning.
|
|
224
|
+
|
|
225
|
+
### Raincloud (v7.1, premium, Tier 2)
|
|
226
|
+
|
|
227
|
+
`chart.type: 'raincloud'` shows a distribution three ways at once: the **half-violin** is the shape, the **box** is the summary, and the **rain** underneath is the observations themselves. You hand it the raw values and it does the rest.
|
|
228
|
+
|
|
229
|
+
```js
|
|
230
|
+
import ApexCharts from 'apexcharts'
|
|
231
|
+
import 'apexcharts/raincloud' // Tier 2: required even on the full bundle
|
|
232
|
+
|
|
233
|
+
new ApexCharts(el, {
|
|
234
|
+
chart: { type: 'raincloud', height: 350 },
|
|
235
|
+
series: [{
|
|
236
|
+
name: 'Weight gain',
|
|
237
|
+
data: [
|
|
238
|
+
{ x: 'Control', points: [3.1, 4.7, 2.9, 5.2, 3.8, 4.1] },
|
|
239
|
+
{ x: 'Treatment', points: [6.4, 7.1, 5.8, 6.9, 7.6, 6.2] },
|
|
240
|
+
],
|
|
241
|
+
}],
|
|
242
|
+
}).render()
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Raincloud is a **preset over the violin engine**, so it is configured through `plotOptions.violin`. The type sets three of those defaults for you:
|
|
246
|
+
|
|
247
|
+
| `plotOptions.violin` key | Raincloud preset | Plain violin default |
|
|
248
|
+
|---|---|---|
|
|
249
|
+
| `side` | `'right'` (or `'top'` when horizontal), a half-violin | `'both'` |
|
|
250
|
+
| `box.show` | `true` (the "umbrella") | `false` |
|
|
251
|
+
| `box.whiskers` | `'tukey'` (1.5×IQR fences clamped to the data) | `'minmax'` |
|
|
252
|
+
| `points.position` | `'left'` (or `'bottom'` when horizontal), the "rain" gets its own lane | `'center'` |
|
|
253
|
+
|
|
254
|
+
Everything else is the violin surface, so override it there:
|
|
255
|
+
|
|
256
|
+
```js
|
|
257
|
+
plotOptions: {
|
|
258
|
+
violin: {
|
|
259
|
+
box: {
|
|
260
|
+
width: '15%', // fraction of the category slot reserved for the box lane
|
|
261
|
+
capWidth: 0.5, // whisker cap length, 0..1 of the box lane width
|
|
262
|
+
fillColor: undefined,// defaults to the series colour
|
|
263
|
+
strokeWidth: 1,
|
|
264
|
+
},
|
|
265
|
+
points: {
|
|
266
|
+
laneWidth: '40%', // fraction of the category slot for the off-centre lane
|
|
267
|
+
jitter: 0.5, // 0..1 of the half-width to scatter within
|
|
268
|
+
size: 3,
|
|
269
|
+
maxPoints: undefined,// cap per violin; observations beyond it are stride-thinned
|
|
270
|
+
fillColor: 'series-dark', // or 'series', or any literal colour
|
|
271
|
+
strokeColor: '#fff',
|
|
272
|
+
strokeWidth: 1,
|
|
273
|
+
},
|
|
274
|
+
kde: { bandwidth: undefined, resolution: 64 },
|
|
275
|
+
normalize: 'individual', // or 'group' to keep widths proportional across categories
|
|
276
|
+
},
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
The rain **is** the outlier display, so the box draws no outlier dots of its own. Off-centre dots ignore `constrainToViolin`. A `y.summary` supplied by hand as `[whiskerLow, q1, median, q3, whiskerHigh]` is drawn exactly as given rather than derived.
|
|
281
|
+
|
|
282
|
+
**The alias rewrites `chart.type` to `'violin'` at runtime.** Code that reads the live config (a formatter reading `w.config.chart.type`, a `chart.getState()` consumer, a plugin) sees `'violin'`, not `'raincloud'`; the requested type is kept on `chart.requestedType`. Branch on `requestedType` if you need to tell a raincloud from a plain violin. This is also how licensing distinguishes them: plain violins are free and never watermark.
|
|
283
|
+
|
|
284
|
+
### `rowSeries()`: the rows behind a summary mark (v6.9)
|
|
285
|
+
|
|
286
|
+
A histogram bin, a box, and a violin all stand for rows the chart is already holding. `chart.rowSeries()` returns them as a unit-chart series (one cluster per mark, one datum per row), so a summary can be opened into its observations:
|
|
287
|
+
|
|
288
|
+
```js
|
|
289
|
+
chart.updateOptions({ chart: { type: 'unit' }, series: chart.rowSeries() })
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Returns `null` when the current type has no row source or the stats feature is not loaded. `chart.rowSeries({ maxRows })` caps the dots produced (default 3000); past the cap every cluster is thinned by one shared stride so relative sizes survive. With the `morph` feature loaded, each dot animates out of the part of the mark that stood for it.
|
|
293
|
+
|
|
126
294
|
---
|
|
127
295
|
|
|
128
296
|
## Key plotOptions
|
|
@@ -206,9 +374,15 @@ plotOptions: {
|
|
|
206
374
|
## Family-Specific Pitfalls
|
|
207
375
|
|
|
208
376
|
1. **Wrong OHLC order** — must be `[Open, High, Low, Close]`, not `[High, Low, Open, Close]` or any other order.
|
|
209
|
-
2. **Box Plot with wrong array length** — must be exactly 5 values `[min, Q1, median, Q3, max]`. Fewer or more values cause rendering errors.
|
|
210
|
-
3. **Using simple numeric array** — `data: [10, 20, 30]` does NOT work for candlestick/boxPlot. Each point requires an array in `y
|
|
377
|
+
2. **Box Plot with wrong array length** — a summary `y` must be exactly 5 values `[min, Q1, median, Q3, max]`. Fewer or more values cause rendering errors. (Since v6.9 the alternative is no `y` at all: put the raw sample in `points` and the summary is computed.)
|
|
378
|
+
3. **Using simple numeric array** — `data: [10, 20, 30]` does NOT work for candlestick/boxPlot. Each point requires an array in `y` (or, for boxPlot since v6.9, a raw sample in `points`). For a distribution of a flat number array, use `chart.type: 'histogram'` instead.
|
|
211
379
|
4. **Missing `xaxis.type: 'datetime'`** — candlestick charts with date x-values need `xaxis: { type: 'datetime' }` to format dates correctly.
|
|
212
380
|
5. **Confusing candlestick with boxPlot** — candlestick is 4 values (OHLC), boxPlot is 5 values (five-number summary). They share the same entry point but have different data shapes.
|
|
213
|
-
6. **Violin with a plain numeric `y`**: violin points need `y: { density: [[value, weight], ...] }`, not a number.
|
|
214
|
-
7. **Violin orientation set on the wrong namespace**: horizontal violins and per-violin colors come from `plotOptions.bar` (`horizontal`, `distributed`), while `bandwidthScale`, `normalize`, and `points` live under `plotOptions.violin`.
|
|
381
|
+
6. **Violin with a plain numeric `y`**: violin points need `y: { density: [[value, weight], ...] }` or (v6.9) raw observations in `points`, not a single number. With a precomputed `density` profile it is drawn exactly as given; with raw `points` the KDE runs for you (stats feature required when tree-shaking).
|
|
382
|
+
7. **Violin orientation set on the wrong namespace**: horizontal violins and per-violin colors come from `plotOptions.bar` (`horizontal`, `distributed`), while `bandwidthScale`, `kde`, `normalize`, and `points` live under `plotOptions.violin`.
|
|
383
|
+
8. **Feeding a histogram pre-binned counts**: the series must carry raw observations. If you already have counts per bucket, use a `bar` chart; a histogram would bin your counts as if they were measurements.
|
|
384
|
+
9. **`whiskers: 'tukey'` on a precomputed boxPlot summary**: `plotOptions.boxPlot.whiskers` only applies when the summary is derived from `points`. A five-number `y` is drawn exactly as given.
|
|
385
|
+
10. **Raw samples with tree-shaking but no stats feature**: `apexcharts/candlestick` and `apexcharts/violin` alone cannot summarize `points`. Add `import 'apexcharts/features/stats'` (the `apexcharts/histogram` entry and the full bundle already include it).
|
|
386
|
+
11. **Expecting `raincloud` to work on the full bundle** *(v7.1)*: it is the one chart type that is Tier 2. `import ApexCharts from 'apexcharts'` alone gives you a console warning and no raincloud. Add `import 'apexcharts/raincloud'`.
|
|
387
|
+
12. **Looking for `plotOptions.raincloud`**: there is none. Raincloud is a preset over the violin engine, so configure it through `plotOptions.violin` (`side`, `box`, `points`, `kde`, `normalize`).
|
|
388
|
+
13. **Giving a raincloud a `y`**: it takes the raw sample per category: `data: [{ x, points: [number] }]`. A precomputed `y.summary` is honored for the box, but the density and the rain need the observations.
|
|
@@ -133,6 +133,55 @@ Flat list of `{ x, y }` where `x` is the label and `y` is the value (determines
|
|
|
133
133
|
}
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
+
### Nested Treemap (v6.9)
|
|
137
|
+
|
|
138
|
+
A datum may carry `children` to any depth; every branch is drawn as a real container with a header strip and its children inset below it, and a container's area is exactly the sum of its children. A branch normally omits `y` and takes the sum of its children; a leaf supplies one. Flat inputs are untouched and render identically to before.
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
{
|
|
142
|
+
chart: { type: 'treemap', height: 400 },
|
|
143
|
+
series: [{
|
|
144
|
+
data: [
|
|
145
|
+
{ x: 'Technology', children: [
|
|
146
|
+
{ x: 'Software', children: [
|
|
147
|
+
{ x: 'Acme Corp', y: 120 },
|
|
148
|
+
{ x: 'Initech', y: 80 }
|
|
149
|
+
] },
|
|
150
|
+
{ x: 'Hardware', y: 95 }
|
|
151
|
+
] },
|
|
152
|
+
{ x: 'Energy', children: [
|
|
153
|
+
{ x: 'Solar Co', y: 60 },
|
|
154
|
+
{ x: 'Wind Ltd', y: 45 }
|
|
155
|
+
] }
|
|
156
|
+
]
|
|
157
|
+
}]
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Nested-specific options under `plotOptions.treemap`:
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
plotOptions: {
|
|
165
|
+
treemap: {
|
|
166
|
+
nested: {
|
|
167
|
+
enabled: true, // 'auto' behavior: parents appear as soon as the data is nested;
|
|
168
|
+
// false forces the flat two-level layout
|
|
169
|
+
drilldownAsLevels: false // read `drilldown: '<id>'` ids on data points as extra levels
|
|
170
|
+
// instead of as click targets for the drilldown feature.
|
|
171
|
+
// Default false ("descend on click" is the historical meaning)
|
|
172
|
+
},
|
|
173
|
+
parents: { // how branch containers are drawn once the data is nested
|
|
174
|
+
show: 'auto' // 'auto' (on when the data carries children) | true | false
|
|
175
|
+
// plus header/label styling and a tooltip.formatter receiving
|
|
176
|
+
// { name, value, depth, leafCount, percentOfParent, percentOfTotal, node, w }
|
|
177
|
+
},
|
|
178
|
+
levels: [ /* per-depth overrides of `parents`, indexed from the outermost drawn group */ ]
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The hierarchy resolver is shared with sunburst, including the `drilldown: '<id>'` adapter (opted into via `nested.drilldownAsLevels`).
|
|
184
|
+
|
|
136
185
|
---
|
|
137
186
|
|
|
138
187
|
## Key plotOptions
|
|
@@ -239,3 +288,4 @@ plotOptions: {
|
|
|
239
288
|
2. **Inconsistent x-values across heatmap series** — all series should have the same set of x-values to form a proper grid. Missing cells show as gaps.
|
|
240
289
|
3. **Treemap with negative values** — treemap `y` values must be positive (they represent area). Negative values cause rendering issues.
|
|
241
290
|
4. **Confusing heatmap `y` with position** — in heatmap data `{ x, y }`, the `y` is the VALUE (color intensity), NOT the y-axis position. The series `name` determines the row.
|
|
291
|
+
5. **Nested treemap branch carrying its own `y` (v6.9)**: a branch node normally omits `y`; its area is the sum of its children. Only leaves supply values. Flattening a hierarchy by hand is no longer necessary; pass `children` instead.
|