apexcharts-skill 1.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.
@@ -0,0 +1,198 @@
1
+ # Grid Charts Reference — ApexCharts
2
+
3
+ ## Chart Types Covered
4
+
5
+ - **Heatmap** (`'heatmap'`) — Color-coded grid cells representing data intensity
6
+ - **Treemap** (`'treemap'`) — Nested rectangles with area proportional to value
7
+
8
+ ## Tree-Shakeable Import
9
+
10
+ ```js
11
+ import ApexCharts from 'apexcharts/heatmap' # heatmap only
12
+ import ApexCharts from 'apexcharts/treemap' # treemap only
13
+ ```
14
+
15
+ ---
16
+
17
+ ## Data Formats
18
+
19
+ ### Heatmap
20
+
21
+ Each series is a row; each data point is a cell. The `y` value determines the color intensity.
22
+
23
+ ```js
24
+ {
25
+ chart: { type: 'heatmap', height: 350 },
26
+ series: [
27
+ {
28
+ name: 'Monday',
29
+ data: [
30
+ { x: '9am', y: 20 },
31
+ { x: '10am', y: 45 },
32
+ { x: '11am', y: 80 },
33
+ { x: '12pm', y: 65 }
34
+ ]
35
+ },
36
+ {
37
+ name: 'Tuesday',
38
+ data: [
39
+ { x: '9am', y: 35 },
40
+ { x: '10am', y: 60 },
41
+ { x: '11am', y: 40 },
42
+ { x: '12pm', y: 55 }
43
+ ]
44
+ }
45
+ ]
46
+ }
47
+ ```
48
+
49
+ ### Treemap
50
+
51
+ Flat list of `{ x, y }` where `x` is the label and `y` is the value (determines area).
52
+
53
+ ```js
54
+ {
55
+ chart: { type: 'treemap', height: 350 },
56
+ series: [{
57
+ data: [
58
+ { x: 'New York', y: 218 },
59
+ { x: 'Los Angeles', y: 149 },
60
+ { x: 'Chicago', y: 106 },
61
+ { x: 'Houston', y: 92 },
62
+ { x: 'Phoenix', y: 65 }
63
+ ]
64
+ }]
65
+ }
66
+ ```
67
+
68
+ ### Treemap with Groups (multiple series)
69
+
70
+ ```js
71
+ {
72
+ chart: { type: 'treemap', height: 350 },
73
+ series: [
74
+ {
75
+ name: 'Fruits',
76
+ data: [
77
+ { x: 'Apple', y: 100 },
78
+ { x: 'Banana', y: 80 },
79
+ { x: 'Orange', y: 60 }
80
+ ]
81
+ },
82
+ {
83
+ name: 'Vegetables',
84
+ data: [
85
+ { x: 'Carrot', y: 70 },
86
+ { x: 'Potato', y: 90 }
87
+ ]
88
+ }
89
+ ]
90
+ }
91
+ ```
92
+
93
+ ---
94
+
95
+ ## Key plotOptions
96
+
97
+ ### Heatmap
98
+
99
+ ```js
100
+ plotOptions: {
101
+ heatmap: {
102
+ radius: 0, // border radius of cells
103
+ enableShades: true, // shade intensity based on value
104
+ shadeIntensity: 0.5, // shade range (0-1)
105
+ distributed: false, // different color per series
106
+
107
+ colorScale: {
108
+ ranges: [
109
+ { from: 0, to: 30, color: '#00A100', name: 'Low' },
110
+ { from: 31, to: 60, color: '#128FD9', name: 'Medium' },
111
+ { from: 61, to: 100, color: '#FFB200', name: 'High' }
112
+ ],
113
+ inverse: false,
114
+ min: undefined, // override auto-detected min
115
+ max: undefined // override auto-detected max
116
+ },
117
+
118
+ useFillColorAsStroke: false
119
+ }
120
+ }
121
+ ```
122
+
123
+ ### Treemap
124
+
125
+ ```js
126
+ plotOptions: {
127
+ treemap: {
128
+ enableShades: true,
129
+ shadeIntensity: 0.5,
130
+ distributed: false, // true = different color per cell
131
+
132
+ colorScale: {
133
+ ranges: [
134
+ { from: 0, to: 50, color: '#CD363A' },
135
+ { from: 51, to: 100, color: '#52B12C' }
136
+ ]
137
+ },
138
+
139
+ useFillColorAsStroke: false
140
+ }
141
+ }
142
+ ```
143
+
144
+ ---
145
+
146
+ ## Complete Working Example — Heatmap
147
+
148
+ ```html
149
+ <div id="chart"></div>
150
+ <script type="module">
151
+ import ApexCharts from 'apexcharts'
152
+
153
+ // Generate sample heatmap data
154
+ function generateData(count, range) {
155
+ const hours = ['9am', '10am', '11am', '12pm', '1pm', '2pm', '3pm', '4pm', '5pm']
156
+ return hours.slice(0, count).map(hour => ({
157
+ x: hour,
158
+ y: Math.floor(Math.random() * (range.max - range.min + 1)) + range.min
159
+ }))
160
+ }
161
+
162
+ const options = {
163
+ chart: { type: 'heatmap', height: 350 },
164
+ series: [
165
+ { name: 'Monday', data: generateData(9, { min: 0, max: 90 }) },
166
+ { name: 'Tuesday', data: generateData(9, { min: 0, max: 90 }) },
167
+ { name: 'Wednesday', data: generateData(9, { min: 0, max: 90 }) },
168
+ { name: 'Thursday', data: generateData(9, { min: 0, max: 90 }) },
169
+ { name: 'Friday', data: generateData(9, { min: 0, max: 90 }) }
170
+ ],
171
+ plotOptions: {
172
+ heatmap: {
173
+ colorScale: {
174
+ ranges: [
175
+ { from: 0, to: 30, color: '#00A100', name: 'Low' },
176
+ { from: 31, to: 60, color: '#128FD9', name: 'Medium' },
177
+ { from: 61, to: 90, color: '#FFB200', name: 'High' }
178
+ ]
179
+ }
180
+ }
181
+ },
182
+ dataLabels: { enabled: true },
183
+ title: { text: 'Office Activity Heatmap' }
184
+ }
185
+
186
+ const chart = new ApexCharts(document.querySelector('#chart'), options)
187
+ await chart.render()
188
+ </script>
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Family-Specific Pitfalls
194
+
195
+ 1. **Heatmap with simple numeric arrays** — `data: [10, 20, 30]` does NOT work. Each point must be `{ x, y }` where `y` is the intensity value.
196
+ 2. **Inconsistent x-values across heatmap series** — all series should have the same set of x-values to form a proper grid. Missing cells show as gaps.
197
+ 3. **Treemap with negative values** — treemap `y` values must be positive (they represent area). Negative values cause rendering issues.
198
+ 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.
@@ -0,0 +1,97 @@
1
+ # Radar Charts Reference — ApexCharts
2
+
3
+ ## Chart Types Covered
4
+
5
+ - **Radar** (`'radar'`) — Spider/web chart comparing multiple variables across categories
6
+
7
+ ## Tree-Shakeable Import
8
+
9
+ ```js
10
+ import ApexCharts from 'apexcharts/radar'
11
+ // Registers: radar only
12
+ ```
13
+
14
+ ---
15
+
16
+ ## Data Format
17
+
18
+ Radar charts use the axis-chart series format with simple numeric arrays. Categories define the spoke labels.
19
+
20
+ ```js
21
+ {
22
+ chart: { type: 'radar', height: 350 },
23
+ series: [
24
+ { name: 'Player A', data: [80, 50, 30, 40, 100, 20] },
25
+ { name: 'Player B', data: [60, 70, 90, 50, 40, 60] }
26
+ ],
27
+ xaxis: {
28
+ categories: ['Speed', 'Strength', 'Agility', 'Endurance', 'Accuracy', 'Teamwork']
29
+ }
30
+ }
31
+ ```
32
+
33
+ **Important:** The number of values in each `data` array must match the number of `categories`.
34
+
35
+ ---
36
+
37
+ ## Key plotOptions
38
+
39
+ ```js
40
+ plotOptions: {
41
+ radar: {
42
+ size: undefined, // radar chart radius (auto-calculated if undefined)
43
+ offsetX: 0,
44
+ offsetY: 0,
45
+
46
+ polygons: {
47
+ strokeColors: '#e8e8e8', // polygon border color
48
+ strokeWidth: 1,
49
+ connectorColors: '#e8e8e8', // spoke line color
50
+
51
+ fill: {
52
+ colors: undefined // alternating fill colors for concentric rings
53
+ // e.g., ['#f8f8f8', '#fff'] for zebra striping
54
+ }
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ ---
61
+
62
+ ## Complete Working Example
63
+
64
+ ```html
65
+ <div id="chart"></div>
66
+ <script type="module">
67
+ import ApexCharts from 'apexcharts'
68
+
69
+ const options = {
70
+ chart: { type: 'radar', height: 400 },
71
+ series: [
72
+ { name: 'Budget', data: [80, 50, 30, 40, 100, 20] },
73
+ { name: 'Actual', data: [60, 70, 90, 50, 40, 60] }
74
+ ],
75
+ xaxis: {
76
+ categories: ['Marketing', 'Engineering', 'Sales', 'Support', 'R&D', 'Operations']
77
+ },
78
+ stroke: { width: 2 },
79
+ fill: { opacity: 0.2 },
80
+ markers: { size: 4 },
81
+ yaxis: { stepSize: 20 },
82
+ title: { text: 'Budget vs Actual Spend', align: 'center' }
83
+ }
84
+
85
+ const chart = new ApexCharts(document.querySelector('#chart'), options)
86
+ await chart.render()
87
+ </script>
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Family-Specific Pitfalls
93
+
94
+ 1. **Missing `xaxis.categories`** — without categories, spokes have no labels. Always provide category names.
95
+ 2. **Data length mismatch** — each series `data` array must have exactly as many values as there are categories.
96
+ 3. **Confusing with polar area** — radar uses `series: [{ data: [...] }]` (axis format), polar area uses `series: [num]` (flat array). They look similar but have completely different data shapes.
97
+ 4. **Using `{ x, y }` format** — radar charts expect simple number arrays, NOT `{ x, y }` objects.
@@ -0,0 +1,201 @@
1
+ # Server-Side Rendering (SSR) — ApexCharts
2
+
3
+ ## Overview
4
+
5
+ ApexCharts supports SSR for generating chart SVGs on the server (Node.js) and hydrating them on the client for interactivity.
6
+
7
+ ## Import Paths
8
+
9
+ ```js
10
+ // Server (Node.js) — includes renderToString, renderToHTML
11
+ import ApexCharts from 'apexcharts/ssr'
12
+
13
+ // Client (Browser) — for hydration after SSR
14
+ import ApexCharts from 'apexcharts' // auto-detects browser
15
+ // or explicitly:
16
+ import ApexCharts from 'apexcharts/client'
17
+ ```
18
+
19
+ **Important:** The default `import ApexCharts from 'apexcharts'` uses Node.js conditional exports. In Node.js, it automatically resolves to the SSR bundle. In browsers (bundlers), it resolves to the client bundle.
20
+
21
+ ---
22
+
23
+ ## Server-Side API
24
+
25
+ ### renderToString(options)
26
+
27
+ Returns a raw SVG string suitable for embedding:
28
+
29
+ ```js
30
+ import ApexCharts from 'apexcharts/ssr'
31
+
32
+ const svgString = await ApexCharts.renderToString({
33
+ chart: { type: 'line', height: 350, width: 600 },
34
+ series: [{ name: 'Sales', data: [30, 40, 35, 50] }],
35
+ xaxis: { categories: ['Q1', 'Q2', 'Q3', 'Q4'] }
36
+ })
37
+
38
+ // svgString is raw <svg>...</svg> markup
39
+ ```
40
+
41
+ ### renderToHTML(options)
42
+
43
+ Returns an HTML string with a wrapper `<div>` containing the SVG, ready for hydration:
44
+
45
+ ```js
46
+ const htmlString = await ApexCharts.renderToHTML({
47
+ chart: {
48
+ type: 'bar',
49
+ height: 350,
50
+ width: 600,
51
+ id: 'my-chart' // id is important for hydration targeting
52
+ },
53
+ series: [{ data: [44, 55, 41, 67] }],
54
+ xaxis: { categories: ['A', 'B', 'C', 'D'] }
55
+ })
56
+
57
+ // htmlString is <div id="my-chart" data-apexcharts>...<svg>...</svg></div>
58
+ ```
59
+
60
+ ---
61
+
62
+ ## Client-Side Hydration
63
+
64
+ After the server-rendered HTML is in the DOM, hydrate it to make it interactive:
65
+
66
+ ### hydrate(element)
67
+
68
+ ```js
69
+ import ApexCharts from 'apexcharts'
70
+
71
+ // Hydrate a specific chart element
72
+ const chart = ApexCharts.hydrate(document.querySelector('#my-chart'))
73
+ ```
74
+
75
+ ### hydrateAll()
76
+
77
+ ```js
78
+ // Hydrate all server-rendered charts on the page
79
+ ApexCharts.hydrateAll()
80
+ ```
81
+
82
+ ### isHydrated(element)
83
+
84
+ ```js
85
+ // Check if an element has already been hydrated
86
+ if (!ApexCharts.isHydrated(el)) {
87
+ ApexCharts.hydrate(el)
88
+ }
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Full SSR + Hydration Example
94
+
95
+ ### Server (Node.js / Express)
96
+
97
+ ```js
98
+ import express from 'express'
99
+ import ApexCharts from 'apexcharts/ssr'
100
+
101
+ const app = express()
102
+
103
+ app.get('/', async (req, res) => {
104
+ const chartHTML = await ApexCharts.renderToHTML({
105
+ chart: { type: 'line', height: 350, width: 600, id: 'sales-chart' },
106
+ series: [{ name: 'Sales', data: [30, 40, 35, 50, 49, 60] }],
107
+ xaxis: { categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'] }
108
+ })
109
+
110
+ res.send(`
111
+ <!DOCTYPE html>
112
+ <html>
113
+ <head><title>Chart</title></head>
114
+ <body>
115
+ ${chartHTML}
116
+ <script type="module">
117
+ import ApexCharts from '/node_modules/apexcharts/dist/apexcharts.esm.js'
118
+ ApexCharts.hydrateAll()
119
+ </script>
120
+ </body>
121
+ </html>
122
+ `)
123
+ })
124
+
125
+ app.listen(3000)
126
+ ```
127
+
128
+ ---
129
+
130
+ ## SSR with Frameworks
131
+
132
+ ### Next.js (React)
133
+
134
+ ```jsx
135
+ // app/page.js (Server Component)
136
+ import ApexCharts from 'apexcharts/ssr'
137
+
138
+ export default async function Page() {
139
+ const chartHTML = await ApexCharts.renderToHTML({
140
+ chart: { type: 'line', height: 350, id: 'my-chart' },
141
+ series: [{ data: [10, 20, 30] }],
142
+ xaxis: { categories: ['A', 'B', 'C'] }
143
+ })
144
+
145
+ return (
146
+ <>
147
+ <div dangerouslySetInnerHTML={{ __html: chartHTML }} />
148
+ <HydrateCharts />
149
+ </>
150
+ )
151
+ }
152
+
153
+ // components/HydrateCharts.js (Client Component)
154
+ 'use client'
155
+ import { useEffect } from 'react'
156
+
157
+ export default function HydrateCharts() {
158
+ useEffect(() => {
159
+ import('apexcharts').then(({ default: ApexCharts }) => {
160
+ ApexCharts.hydrateAll()
161
+ })
162
+ }, [])
163
+ return null
164
+ }
165
+ ```
166
+
167
+ ### Nuxt 3 (Vue)
168
+
169
+ ```vue
170
+ <!-- pages/index.vue -->
171
+ <template>
172
+ <div v-html="chartHTML" />
173
+ </template>
174
+
175
+ <script setup>
176
+ // Server-side
177
+ const chartHTML = await useAsyncData('chart', async () => {
178
+ const ApexCharts = (await import('apexcharts/ssr')).default
179
+ return await ApexCharts.renderToHTML({
180
+ chart: { type: 'bar', height: 350, id: 'my-chart' },
181
+ series: [{ data: [44, 55, 41] }],
182
+ xaxis: { categories: ['A', 'B', 'C'] }
183
+ })
184
+ })
185
+
186
+ // Client-side hydration
187
+ onMounted(async () => {
188
+ const ApexCharts = (await import('apexcharts')).default
189
+ ApexCharts.hydrateAll()
190
+ })
191
+ </script>
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Common Pitfalls
197
+
198
+ 1. **Using `apexcharts` in Node.js without SSR methods** — the default export auto-resolves based on environment, but `renderToString` is only available via `apexcharts/ssr`.
199
+ 2. **Forgetting to hydrate on the client** — server-rendered charts are static SVGs. Without `hydrate()`, they have no interactivity (no tooltips, zoom, click events).
200
+ 3. **Missing `chart.width`** — SSR has no DOM to measure container width. Always provide explicit `width` for server rendering.
201
+ 4. **Hydrating before DOM is ready** — call `hydrate()` after the server-rendered HTML is in the DOM (use `onMounted`, `useEffect`, or `DOMContentLoaded`).
@@ -0,0 +1,154 @@
1
+ # Tree-Shaking & Bundle Optimization — ApexCharts
2
+
3
+ ## Overview
4
+
5
+ ApexCharts supports three import strategies with different bundle sizes:
6
+
7
+ | Strategy | Import | Includes |
8
+ |---|---|---|
9
+ | Full bundle | `import ApexCharts from 'apexcharts'` | All 16 chart types + all features |
10
+ | Per-type entry | `import ApexCharts from 'apexcharts/line'` | Specific chart family + core (no optional features) |
11
+ | Bare core | `import ApexCharts from 'apexcharts/core'` | Core class only — must manually register everything |
12
+
13
+ ---
14
+
15
+ ## Per-Type Entry Points
16
+
17
+ Each entry point registers a family of related chart types:
18
+
19
+ | Entry Point | Chart Types Registered |
20
+ |---|---|
21
+ | `apexcharts/line` | line, area, scatter, bubble, rangeArea |
22
+ | `apexcharts/area` | same as /line |
23
+ | `apexcharts/scatter` | same as /line |
24
+ | `apexcharts/bubble` | same as /line |
25
+ | `apexcharts/rangeArea` | same as /line |
26
+ | `apexcharts/bar` | bar, column, rangeBar |
27
+ | `apexcharts/column` | same as /bar |
28
+ | `apexcharts/rangeBar` | same as /bar |
29
+ | `apexcharts/candlestick` | candlestick, boxPlot |
30
+ | `apexcharts/boxPlot` | same as /candlestick |
31
+ | `apexcharts/pie` | pie, donut, polarArea |
32
+ | `apexcharts/donut` | same as /pie |
33
+ | `apexcharts/polarArea` | same as /pie |
34
+ | `apexcharts/radialBar` | radialBar |
35
+ | `apexcharts/radar` | radar |
36
+ | `apexcharts/heatmap` | heatmap |
37
+ | `apexcharts/treemap` | treemap |
38
+
39
+ ### Using Multiple Chart Types
40
+
41
+ ```js
42
+ // Import multiple entry points for a mixed chart
43
+ import ApexCharts from 'apexcharts/line'
44
+ import 'apexcharts/bar' // side-effect: registers bar types onto the same class
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Optional Features
50
+
51
+ Features are optional modules that add functionality. When using per-type entries or core, features must be explicitly imported.
52
+
53
+ | Feature | Import | What It Adds |
54
+ |---|---|---|
55
+ | Legend | `import 'apexcharts/features/legend'` | Interactive legend component |
56
+ | Toolbar | `import 'apexcharts/features/toolbar'` | Zoom, pan, download buttons |
57
+ | Annotations | `import 'apexcharts/features/annotations'` | X/Y/point/text/image annotations |
58
+ | Exports | `import 'apexcharts/features/exports'` | `dataURI()`, `getSvgString()`, `exportToCSV()` |
59
+ | Keyboard | `import 'apexcharts/features/keyboard'` | Keyboard navigation (accessibility) |
60
+ | All | `import 'apexcharts/features/all'` | All of the above |
61
+
62
+ **Important:** Tooltip is always included in core — it cannot be tree-shaken.
63
+
64
+ ### What Happens If You Forget a Feature
65
+
66
+ Features fail **silently**. If you use a per-type entry without importing legend:
67
+ - No legend appears, no error thrown
68
+ - `chart.toolbar` is undefined, toolbar doesn't render
69
+ - `addXaxisAnnotation()` does nothing
70
+ - `dataURI()` / `exportToCSV()` throw because the feature isn't registered
71
+
72
+ ---
73
+
74
+ ## Bare Core Usage
75
+
76
+ For maximum control, import core and register everything manually:
77
+
78
+ ```js
79
+ import ApexCharts from 'apexcharts/core'
80
+
81
+ // Register chart types manually
82
+ import { Line } from 'apexcharts/src/charts/Line.js'
83
+ ApexCharts.use({ line: Line, area: Line })
84
+
85
+ // Register features manually
86
+ import { Legend } from 'apexcharts/src/modules/legend/Legend.js'
87
+ ApexCharts.registerFeatures({ legend: Legend })
88
+ ```
89
+
90
+ This approach is rarely needed — per-type entries with feature imports cover most use cases.
91
+
92
+ ---
93
+
94
+ ## Example: Minimal Line Chart Bundle
95
+
96
+ ```js
97
+ import ApexCharts from 'apexcharts/line'
98
+ import 'apexcharts/features/legend'
99
+ import 'apexcharts/features/toolbar'
100
+
101
+ const chart = new ApexCharts(el, {
102
+ chart: { type: 'line', height: 350 },
103
+ series: [{ data: [10, 20, 30] }],
104
+ xaxis: { categories: ['A', 'B', 'C'] }
105
+ })
106
+ await chart.render()
107
+ ```
108
+
109
+ ## Example: Mixed Chart (Line + Bar)
110
+
111
+ ```js
112
+ import ApexCharts from 'apexcharts/line'
113
+ import 'apexcharts/bar'
114
+ import 'apexcharts/features/legend'
115
+
116
+ const chart = new ApexCharts(el, {
117
+ chart: { type: 'line', height: 350 },
118
+ series: [
119
+ { name: 'Revenue', type: 'column', data: [44, 55, 57] },
120
+ { name: 'Profit', type: 'line', data: [15, 25, 35] }
121
+ ],
122
+ xaxis: { categories: ['Q1', 'Q2', 'Q3'] }
123
+ })
124
+ await chart.render()
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Vite Configuration
130
+
131
+ When using Vite with tree-shaking entries, configure `optimizeDeps` to prevent duplicate bundles:
132
+
133
+ ```js
134
+ // vite.config.js
135
+ export default {
136
+ optimizeDeps: {
137
+ include: [
138
+ 'apexcharts/line',
139
+ 'apexcharts/features/legend',
140
+ 'apexcharts/features/toolbar'
141
+ // Add all apexcharts entries you use
142
+ ]
143
+ }
144
+ }
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Common Pitfalls
150
+
151
+ 1. **Missing feature imports** — features fail silently. If legend/toolbar/annotations don't appear, check imports.
152
+ 2. **Importing `apexcharts` AND `apexcharts/line`** — creates duplicate bundles. Use one strategy.
153
+ 3. **Vite duplicate bundle issue** — without `optimizeDeps.include`, Vite may bundle ApexCharts twice.
154
+ 4. **Calling `dataURI()` without exports feature** — throws an error. Import `apexcharts/features/exports` first.