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,218 @@
1
+ # Circular Charts Reference — ApexCharts
2
+
3
+ ## Chart Types Covered
4
+
5
+ - **Pie** (`'pie'`) — Standard pie chart
6
+ - **Donut** (`'donut'`) — Pie chart with hollow center
7
+ - **Polar Area** (`'polarArea'`) — Radial segments with equal angles, varying radius
8
+ - **Radial Bar** (`'radialBar'`) — Circular progress/gauge chart
9
+
10
+ ## Tree-Shakeable Import
11
+
12
+ ```js
13
+ import ApexCharts from 'apexcharts/pie'
14
+ // Registers: pie, donut, polarArea
15
+ // Aliases: apexcharts/donut, apexcharts/polarArea
16
+
17
+ import ApexCharts from 'apexcharts/radialBar'
18
+ // Registers: radialBar (separate entry point)
19
+ ```
20
+
21
+ ---
22
+
23
+ ## Data Format
24
+
25
+ **The canonical format for circular charts is a flat number array for `series` paired with a `labels` array.** The x/y object format used by axis charts also works (ApexCharts normalizes it by extracting `y` as the value and `x` as the label), but it is not recommended — prefer the flat array form for clarity and predictability.
26
+
27
+ ### Pie / Donut / Polar Area
28
+
29
+ ```js
30
+ {
31
+ chart: { type: 'pie', height: 350 }, // or 'donut' or 'polarArea'
32
+ series: [44, 55, 13, 43, 22],
33
+ labels: ['Team A', 'Team B', 'Team C', 'Team D', 'Team E']
34
+ }
35
+ ```
36
+
37
+ ### Radial Bar (values 0–100)
38
+
39
+ ```js
40
+ {
41
+ chart: { type: 'radialBar', height: 350 },
42
+ series: [76, 67, 61, 90],
43
+ labels: ['Apples', 'Oranges', 'Bananas', 'Berries']
44
+ }
45
+ ```
46
+
47
+ **Important:** RadialBar values represent percentages (0–100). Values above 100 will overflow the track.
48
+
49
+ ---
50
+
51
+ ## Key plotOptions
52
+
53
+ ### Pie / Donut
54
+
55
+ ```js
56
+ plotOptions: {
57
+ pie: {
58
+ startAngle: 0,
59
+ endAngle: 360,
60
+ expandOnClick: true, // expand slice on click
61
+ offsetX: 0,
62
+ offsetY: 0,
63
+
64
+ customScale: 1, // scale the pie (0.5 = half size)
65
+
66
+ dataLabels: {
67
+ offset: 0, // move labels away from center
68
+ minAngleToShowLabel: 10 // hide labels on tiny slices
69
+ },
70
+
71
+ donut: {
72
+ size: '65%', // donut hole size (percentage string)
73
+ background: 'transparent',
74
+
75
+ labels: {
76
+ show: true, // show center labels
77
+ name: {
78
+ show: true,
79
+ fontSize: '22px',
80
+ fontWeight: 600,
81
+ offsetY: -10
82
+ },
83
+ value: {
84
+ show: true,
85
+ fontSize: '16px',
86
+ formatter: (val) => val // format the numeric value
87
+ },
88
+ total: {
89
+ show: true,
90
+ label: 'Total',
91
+ formatter: (w) => {
92
+ // w.globals.seriesTotals is array of values
93
+ return w.globals.seriesTotals.reduce((a, b) => a + b, 0)
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ ### Radial Bar
103
+
104
+ ```js
105
+ plotOptions: {
106
+ radialBar: {
107
+ startAngle: -135,
108
+ endAngle: 135,
109
+
110
+ hollow: {
111
+ size: '70%', // size of the hollow center
112
+ background: 'transparent'
113
+ },
114
+
115
+ track: {
116
+ show: true,
117
+ background: '#f2f2f2', // track background color
118
+ strokeWidth: '97%',
119
+ margin: 5 // margin between tracks
120
+ },
121
+
122
+ dataLabels: {
123
+ name: {
124
+ show: true,
125
+ fontSize: '16px'
126
+ },
127
+ value: {
128
+ show: true,
129
+ fontSize: '14px',
130
+ formatter: (val) => `${val}%`
131
+ },
132
+ total: {
133
+ show: true,
134
+ label: 'Total',
135
+ formatter: (w) => {
136
+ const total = w.globals.seriesTotals.reduce((a, b) => a + b, 0)
137
+ return `${(total / w.globals.series.length).toFixed(1)}%`
138
+ }
139
+ }
140
+ }
141
+ }
142
+ }
143
+ ```
144
+
145
+ ### Polar Area
146
+
147
+ ```js
148
+ plotOptions: {
149
+ polarArea: {
150
+ rings: {
151
+ strokeWidth: 1,
152
+ strokeColor: '#e8e8e8'
153
+ },
154
+ spokes: {
155
+ strokeWidth: 1,
156
+ connectorColors: '#e8e8e8'
157
+ }
158
+ }
159
+ }
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Complete Working Example — Donut with Center Label
165
+
166
+ ```html
167
+ <div id="chart"></div>
168
+ <script type="module">
169
+ import ApexCharts from 'apexcharts'
170
+
171
+ const options = {
172
+ chart: {
173
+ type: 'donut',
174
+ height: 350
175
+ },
176
+ series: [44, 55, 41, 17, 15],
177
+ labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
178
+ plotOptions: {
179
+ pie: {
180
+ donut: {
181
+ size: '65%',
182
+ labels: {
183
+ show: true,
184
+ name: { show: true },
185
+ value: {
186
+ show: true,
187
+ formatter: (val) => `${val} tasks`
188
+ },
189
+ total: {
190
+ show: true,
191
+ label: 'Total',
192
+ formatter: (w) => {
193
+ return w.globals.seriesTotals.reduce((a, b) => a + b, 0) + ' tasks'
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
199
+ },
200
+ legend: { position: 'bottom' },
201
+ title: { text: 'Tasks by Day', align: 'center' }
202
+ }
203
+
204
+ const chart = new ApexCharts(document.querySelector('#chart'), options)
205
+ await chart.render()
206
+ </script>
207
+ ```
208
+
209
+ ---
210
+
211
+ ## Family-Specific Pitfalls
212
+
213
+ 1. **Using axis-chart series format** — `series: [{ name: 'A', data: [44, 55] }]` is WRONG for pie/donut. The x/y object form `series: [{ data: [{ x: 'A', y: 44 }] }]` works (ApexCharts normalizes it), but the canonical form is preferred: `series: [44, 55]` (flat array) + `labels: ['A', 'B']`.
214
+ 2. **RadialBar values above 100** — values represent percentages and will overflow. If you have raw values, calculate percentages first: `(value / max) * 100`.
215
+ 3. **Missing `labels` array** — without `labels`, pie/donut slices show as "undefined" in tooltips and legend.
216
+ 4. **Donut center labels not showing** — must set `plotOptions.pie.donut.labels.show: true` explicitly.
217
+ 5. **`total.formatter` signature** — receives `w` (the full chart config object), NOT a simple value. Access `w.globals.seriesTotals` for the array of current values.
218
+ 6. **Polar Area confused with Radar** — polar area uses `series: [num]` (flat), radar uses `series: [{ data: [num] }]` (axis format). They look similar but have different data shapes.
@@ -0,0 +1,157 @@
1
+ # Financial Charts Reference — ApexCharts
2
+
3
+ ## Chart Types Covered
4
+
5
+ - **Candlestick** (`'candlestick'`) — OHLC (Open, High, Low, Close) financial chart
6
+ - **Box Plot** (`'boxPlot'`) — Statistical distribution chart showing min, Q1, median, Q3, max
7
+
8
+ ## Tree-Shakeable Import
9
+
10
+ ```js
11
+ import ApexCharts from 'apexcharts/candlestick'
12
+ // Registers: candlestick, boxPlot
13
+ // Alias: apexcharts/boxPlot
14
+ ```
15
+
16
+ ---
17
+
18
+ ## Data Formats
19
+
20
+ ### Candlestick — OHLC
21
+
22
+ The `y` value must be an array of exactly 4 numbers: `[Open, High, Low, Close]`
23
+
24
+ ```js
25
+ {
26
+ chart: { type: 'candlestick', height: 350 },
27
+ series: [{
28
+ data: [
29
+ { x: new Date('2024-01-01').getTime(), y: [51.98, 56.29, 51.59, 53.85] },
30
+ { x: new Date('2024-01-02').getTime(), y: [53.66, 54.99, 51.35, 52.95] },
31
+ { x: new Date('2024-01-03').getTime(), y: [52.76, 57.35, 52.15, 57.03] }
32
+ ]
33
+ }],
34
+ xaxis: { type: 'datetime' }
35
+ }
36
+ ```
37
+
38
+ **Alternative 2D array formats:**
39
+
40
+ ```js
41
+ // Nested: [x, [O, H, L, C]]
42
+ data: [
43
+ [new Date('2024-01-01').getTime(), [51.98, 56.29, 51.59, 53.85]],
44
+ [new Date('2024-01-02').getTime(), [53.66, 54.99, 51.35, 52.95]]
45
+ ]
46
+
47
+ // Flat: [x, O, H, L, C] (5 elements)
48
+ data: [
49
+ [new Date('2024-01-01').getTime(), 51.98, 56.29, 51.59, 53.85],
50
+ [new Date('2024-01-02').getTime(), 53.66, 54.99, 51.35, 52.95]
51
+ ]
52
+ ```
53
+
54
+ ### Box Plot — Five-Number Summary
55
+
56
+ The `y` value must be an array of exactly 5 numbers: `[min, Q1, median, Q3, max]`
57
+
58
+ ```js
59
+ {
60
+ chart: { type: 'boxPlot', height: 350 },
61
+ series: [{
62
+ data: [
63
+ { x: 'Jan 2024', y: [54, 66, 69, 75, 88] },
64
+ { x: 'Feb 2024', y: [43, 65, 69, 76, 81] },
65
+ { x: 'Mar 2024', y: [31, 39, 45, 51, 59] }
66
+ ]
67
+ }]
68
+ }
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Key plotOptions
74
+
75
+ ### Candlestick Colors
76
+
77
+ ```js
78
+ plotOptions: {
79
+ candlestick: {
80
+ colors: {
81
+ upward: '#00B746', // color when Close > Open (bullish)
82
+ downward: '#EF403C' // color when Close < Open (bearish)
83
+ },
84
+ wick: {
85
+ useFillColor: true // wick color matches candle body
86
+ }
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### Box Plot Colors
92
+
93
+ ```js
94
+ plotOptions: {
95
+ boxPlot: {
96
+ colors: {
97
+ upper: '#00E396', // color for upper quartile
98
+ lower: '#008FFB' // color for lower quartile
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Complete Working Example — Candlestick Chart
107
+
108
+ ```html
109
+ <div id="chart"></div>
110
+ <script type="module">
111
+ import ApexCharts from 'apexcharts'
112
+
113
+ const options = {
114
+ chart: {
115
+ type: 'candlestick',
116
+ height: 350
117
+ },
118
+ series: [{
119
+ name: 'AAPL',
120
+ data: [
121
+ { x: new Date('2024-01-02').getTime(), y: [185.09, 185.60, 183.66, 185.56] },
122
+ { x: new Date('2024-01-03').getTime(), y: [184.22, 185.88, 183.43, 184.25] },
123
+ { x: new Date('2024-01-04').getTime(), y: [182.15, 183.09, 180.88, 181.91] },
124
+ { x: new Date('2024-01-05').getTime(), y: [181.99, 182.76, 180.17, 181.18] },
125
+ { x: new Date('2024-01-08').getTime(), y: [181.79, 185.60, 181.32, 185.56] }
126
+ ]
127
+ }],
128
+ xaxis: { type: 'datetime' },
129
+ yaxis: {
130
+ tooltip: { enabled: true },
131
+ labels: { formatter: (val) => `$${val.toFixed(2)}` }
132
+ },
133
+ plotOptions: {
134
+ candlestick: {
135
+ colors: {
136
+ upward: '#26a69a',
137
+ downward: '#ef5350'
138
+ }
139
+ }
140
+ },
141
+ title: { text: 'AAPL Stock Price', align: 'left' }
142
+ }
143
+
144
+ const chart = new ApexCharts(document.querySelector('#chart'), options)
145
+ await chart.render()
146
+ </script>
147
+ ```
148
+
149
+ ---
150
+
151
+ ## Family-Specific Pitfalls
152
+
153
+ 1. **Wrong OHLC order** — must be `[Open, High, Low, Close]`, not `[High, Low, Open, Close]` or any other order.
154
+ 2. **Box Plot with wrong array length** — must be exactly 5 values `[min, Q1, median, Q3, max]`. Fewer or more values cause rendering errors.
155
+ 3. **Using simple numeric array** — `data: [10, 20, 30]` does NOT work for candlestick/boxPlot. Each point requires an array in `y`.
156
+ 4. **Missing `xaxis.type: 'datetime'`** — candlestick charts with date x-values need `xaxis: { type: 'datetime' }` to format dates correctly.
157
+ 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.
@@ -0,0 +1,251 @@
1
+ # Framework Integration — ApexCharts
2
+
3
+ ## Official Wrappers
4
+
5
+ | Framework | Package | Install |
6
+ |---|---|---|
7
+ | React | `react-apexcharts` | `npm install react-apexcharts apexcharts` |
8
+ | Vue 3 | `vue3-apexcharts` | `npm install vue3-apexcharts apexcharts` |
9
+ | Angular | `ng-apexcharts` | `npm install ng-apexcharts apexcharts` |
10
+
11
+ **Important:** All wrappers require `apexcharts` as a peer dependency. Install both packages.
12
+
13
+ ---
14
+
15
+ ## React
16
+
17
+ ### Basic Usage
18
+
19
+ ```jsx
20
+ import React from 'react'
21
+ import Chart from 'react-apexcharts'
22
+
23
+ function MyChart() {
24
+ const options = {
25
+ chart: { type: 'line' },
26
+ xaxis: { categories: ['Jan', 'Feb', 'Mar', 'Apr'] }
27
+ }
28
+
29
+ const series = [{
30
+ name: 'Sales',
31
+ data: [30, 40, 35, 50]
32
+ }]
33
+
34
+ return <Chart options={options} series={series} type="line" height={350} />
35
+ }
36
+ ```
37
+
38
+ ### Updating Data
39
+
40
+ Pass new `series` or `options` props — the wrapper handles `updateSeries` / `updateOptions` internally:
41
+
42
+ ```jsx
43
+ function LiveChart() {
44
+ const [series, setSeries] = useState([{ data: [30, 40, 35] }])
45
+
46
+ const addData = () => {
47
+ setSeries([{ data: [...series[0].data, Math.random() * 100] }])
48
+ }
49
+
50
+ return (
51
+ <>
52
+ <Chart options={options} series={series} type="line" height={350} />
53
+ <button onClick={addData}>Add Point</button>
54
+ </>
55
+ )
56
+ }
57
+ ```
58
+
59
+ ### Common React Pitfall: Cleanup
60
+
61
+ The wrapper handles `destroy()` automatically on unmount. But if you use the vanilla API directly:
62
+
63
+ ```jsx
64
+ // ❌ WRONG — no cleanup
65
+ useEffect(() => {
66
+ const chart = new ApexCharts(ref.current, options)
67
+ chart.render()
68
+ }, [])
69
+
70
+ // ✅ CORRECT — destroy on unmount
71
+ useEffect(() => {
72
+ const chart = new ApexCharts(ref.current, options)
73
+ chart.render()
74
+ return () => chart.destroy()
75
+ }, [])
76
+ ```
77
+
78
+ ### SSR with Next.js
79
+
80
+ For Next.js, use dynamic import to avoid SSR issues with the wrapper:
81
+
82
+ ```jsx
83
+ import dynamic from 'next/dynamic'
84
+
85
+ const Chart = dynamic(() => import('react-apexcharts'), { ssr: false })
86
+
87
+ export default function Page() {
88
+ return <Chart options={options} series={series} type="line" height={350} />
89
+ }
90
+ ```
91
+
92
+ Or use the native SSR approach (see `references/ssr.md`).
93
+
94
+ ---
95
+
96
+ ## Vue 3
97
+
98
+ ### Setup
99
+
100
+ ```js
101
+ // main.js
102
+ import { createApp } from 'vue'
103
+ import VueApexCharts from 'vue3-apexcharts'
104
+ import App from './App.vue'
105
+
106
+ const app = createApp(App)
107
+ app.use(VueApexCharts)
108
+ app.mount('#app')
109
+ ```
110
+
111
+ ### Basic Usage
112
+
113
+ ```vue
114
+ <template>
115
+ <apexchart
116
+ type="bar"
117
+ height="350"
118
+ :options="chartOptions"
119
+ :series="series"
120
+ />
121
+ </template>
122
+
123
+ <script setup>
124
+ import { ref } from 'vue'
125
+
126
+ const chartOptions = ref({
127
+ chart: { type: 'bar' },
128
+ xaxis: { categories: ['Jan', 'Feb', 'Mar'] },
129
+ plotOptions: { bar: { horizontal: false } }
130
+ })
131
+
132
+ const series = ref([
133
+ { name: 'Revenue', data: [44, 55, 41] }
134
+ ])
135
+ </script>
136
+ ```
137
+
138
+ ### Updating Data
139
+
140
+ The wrapper watches for changes to `series` and `options` props and calls the appropriate update methods:
141
+
142
+ ```vue
143
+ <script setup>
144
+ const series = ref([{ data: [44, 55, 41] }])
145
+
146
+ function updateData() {
147
+ // Mutating the ref triggers re-render
148
+ series.value = [{ data: [10, 20, 30] }]
149
+ }
150
+ </script>
151
+ ```
152
+
153
+ ### Common Vue Pitfall: Reactive Config Mutation
154
+
155
+ ```js
156
+ // ❌ WRONG — directly mutating deep config can miss reactivity
157
+ chartOptions.value.xaxis.categories.push('Apr')
158
+
159
+ // ✅ CORRECT — replace the whole object
160
+ chartOptions.value = {
161
+ ...chartOptions.value,
162
+ xaxis: { categories: ['Jan', 'Feb', 'Mar', 'Apr'] }
163
+ }
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Angular
169
+
170
+ ### Setup
171
+
172
+ ```typescript
173
+ // app.module.ts
174
+ import { NgApexchartsModule } from 'ng-apexcharts'
175
+
176
+ @NgModule({
177
+ imports: [NgApexchartsModule]
178
+ })
179
+ export class AppModule {}
180
+ ```
181
+
182
+ ### Basic Usage
183
+
184
+ ```typescript
185
+ // chart.component.ts
186
+ import { Component } from '@angular/core'
187
+
188
+ @Component({
189
+ selector: 'app-chart',
190
+ template: `
191
+ <apx-chart
192
+ [series]="series"
193
+ [chart]="chartOptions"
194
+ [xaxis]="xaxis"
195
+ ></apx-chart>
196
+ `
197
+ })
198
+ export class ChartComponent {
199
+ chartOptions = { type: 'line' as const, height: 350 }
200
+ series = [{ name: 'Sales', data: [30, 40, 35, 50] }]
201
+ xaxis = { categories: ['Jan', 'Feb', 'Mar', 'Apr'] }
202
+ }
203
+ ```
204
+
205
+ ### Updating Data
206
+
207
+ ```typescript
208
+ updateChart() {
209
+ this.series = [{ name: 'Sales', data: [10, 20, 30, 40] }]
210
+ }
211
+ ```
212
+
213
+ ---
214
+
215
+ ## Vanilla JS (No Framework)
216
+
217
+ ```html
218
+ <div id="chart"></div>
219
+
220
+ <!-- CDN -->
221
+ <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
222
+
223
+ <script>
224
+ const options = {
225
+ chart: { type: 'line', height: 350 },
226
+ series: [{ name: 'Sales', data: [30, 40, 35, 50] }],
227
+ xaxis: { categories: ['Q1', 'Q2', 'Q3', 'Q4'] }
228
+ }
229
+
230
+ const chart = new ApexCharts(document.querySelector('#chart'), options)
231
+ chart.render()
232
+ </script>
233
+ ```
234
+
235
+ ### CDN Links
236
+
237
+ ```
238
+ https://cdn.jsdelivr.net/npm/apexcharts
239
+ https://cdn.jsdelivr.net/npm/apexcharts@5/dist/apexcharts.min.js
240
+ https://unpkg.com/apexcharts
241
+ ```
242
+
243
+ ---
244
+
245
+ ## Common Framework Pitfalls
246
+
247
+ 1. **Missing peer dependency** — `react-apexcharts`, `vue3-apexcharts`, and `ng-apexcharts` all require `apexcharts` as a separate dependency.
248
+ 2. **SSR with wrapper components** — most wrappers access `window`/`document` and crash in SSR. Use dynamic imports with `{ ssr: false }` or the native SSR API.
249
+ 3. **Not destroying on unmount (vanilla API in React/Vue)** — causes memory leaks and duplicate charts. The official wrappers handle this automatically.
250
+ 4. **Mutating config objects in place (Vue)** — deep mutations may not trigger reactivity. Replace the entire object or use `ref` at the right level.
251
+ 5. **Rendering in hidden containers** — charts rendered in hidden tabs/modals have zero dimensions. Call `chart.updateOptions({})` or trigger a resize after showing the container.