@amcharts/amcharts5-mcp 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,584 @@
1
+ # Radar & Gauge Charts
2
+
3
+
4
+ ## Required imports
5
+
6
+ ### ES modules
7
+ ```ts
8
+ import * as am5 from "@amcharts/amcharts5";
9
+ import * as am5xy from "@amcharts/amcharts5/xy";
10
+ import * as am5radar from "@amcharts/amcharts5/radar";
11
+ import am5themes_Animated from "@amcharts/amcharts5/themes/Animated";
12
+ ```
13
+
14
+ ### CDN
15
+ ```html
16
+ <script src="https://cdn.amcharts.com/lib/5/index.js"></script>
17
+ <script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
18
+ <script src="https://cdn.amcharts.com/lib/5/radar.js"></script>
19
+ <script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
20
+ ```
21
+
22
+ ## Radar chart setup
23
+
24
+ ```js
25
+ const root = am5.Root.new("chartdiv");
26
+ root.setThemes([am5themes_Animated.new(root)]);
27
+
28
+ const chart = root.container.children.push(
29
+ am5radar.RadarChart.new(root, {
30
+ panX: false,
31
+ panY: false,
32
+ wheelX: "panX",
33
+ wheelY: "zoomX",
34
+ radius: am5.percent(80),
35
+ innerRadius: am5.percent(20), // hole in center (0 = solid)
36
+ startAngle: -90, // default: -90 (top)
37
+ endAngle: 270 // default: 270 (full circle)
38
+ })
39
+ );
40
+ ```
41
+
42
+ ### RadarChart key settings
43
+
44
+ | Setting | Type | Description |
45
+ |---------|------|-------------|
46
+ | `radius` | percent/number | Outer radius (default: `am5.percent(80)`) |
47
+ | `innerRadius` | percent/number | Inner radius / hole size (default: 0) |
48
+ | `startAngle` | number | Start angle in degrees (default: -90) |
49
+ | `endAngle` | number | End angle in degrees (default: 270) |
50
+
51
+ ## Axes — use circular + radial renderers
52
+
53
+ ```js
54
+ // Circular axis (X — goes around the perimeter)
55
+ const xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
56
+ categoryField: "category",
57
+ renderer: am5radar.AxisRendererCircular.new(root, {
58
+ minGridDistance: 30
59
+ }),
60
+ tooltip: am5.Tooltip.new(root, {})
61
+ }));
62
+ xAxis.data.setAll(data); // CategoryAxis needs data
63
+
64
+ // Radial axis (Y — goes from center outward)
65
+ const yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
66
+ renderer: am5radar.AxisRendererRadial.new(root, {}),
67
+ min: 0
68
+ }));
69
+ ```
70
+
71
+ ### Circular renderer label options
72
+
73
+ ```js
74
+ am5radar.AxisRendererCircular.new(root, {
75
+ minGridDistance: 30
76
+ });
77
+ // Label text type:
78
+ xAxis.get("renderer").labels.template.setAll({
79
+ textType: "circular", // "circular" | "radial" | "adjusted"
80
+ fontSize: 12
81
+ });
82
+ ```
83
+
84
+ ## Series types
85
+
86
+ | Class | Use for |
87
+ |-------|---------|
88
+ | `am5radar.RadarLineSeries` | Lines on radar chart (spider chart) |
89
+ | `am5radar.RadarColumnSeries` | Columns on radar chart |
90
+ | `am5radar.SmoothedRadarLineSeries` | Smoothed/curved radar lines |
91
+
92
+ ```js
93
+ // Radar line series (spider chart)
94
+ const series = chart.series.push(am5radar.RadarLineSeries.new(root, {
95
+ name: "Performance",
96
+ xAxis: xAxis,
97
+ yAxis: yAxis,
98
+ valueYField: "value",
99
+ categoryXField: "category",
100
+ tooltip: am5.Tooltip.new(root, { labelText: "{categoryX}: {valueY}" }),
101
+ connectEnds: true // connect first and last point (default: true)
102
+ }));
103
+
104
+ // Make it an area chart
105
+ series.fills.template.setAll({
106
+ visible: true,
107
+ fillOpacity: 0.3
108
+ });
109
+
110
+ series.strokes.template.setAll({ strokeWidth: 2 });
111
+
112
+ // Radar column series
113
+ const columnSeries = chart.series.push(am5radar.RadarColumnSeries.new(root, {
114
+ name: "Values",
115
+ xAxis: xAxis,
116
+ yAxis: yAxis,
117
+ valueYField: "value",
118
+ categoryXField: "category",
119
+ stacked: false
120
+ }));
121
+
122
+ columnSeries.columns.template.setAll({
123
+ strokeOpacity: 0,
124
+ fillOpacity: 0.8,
125
+ width: am5.percent(80)
126
+ });
127
+ ```
128
+
129
+ ## Gauge chart
130
+
131
+ Gauges are built with RadarChart + a single axis + axis ranges for colored bands.
132
+
133
+ ```js
134
+ const chart = root.container.children.push(am5radar.RadarChart.new(root, {
135
+ panX: false,
136
+ panY: false,
137
+ startAngle: -180,
138
+ endAngle: 0, // semi-circle
139
+ innerRadius: -25, // fixed-width band (negative = from outer edge)
140
+ radius: am5.percent(95)
141
+ }));
142
+
143
+ // Single value axis (the gauge scale)
144
+ const xAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
145
+ min: 0,
146
+ max: 100,
147
+ strictMinMax: true,
148
+ renderer: am5radar.AxisRendererCircular.new(root, {
149
+ strokeOpacity: 0.1,
150
+ minGridDistance: 30
151
+ })
152
+ }));
153
+
154
+ // Enable ticks
155
+ xAxis.get("renderer").ticks.template.setAll({
156
+ visible: true,
157
+ strokeOpacity: 0.5
158
+ });
159
+
160
+ // Disable grid
161
+ xAxis.get("renderer").grid.template.setAll({ visible: false });
162
+
163
+ // Colored bands via axis ranges
164
+ function createRange(start, end, color, label) {
165
+ var rangeDataItem = xAxis.makeDataItem({ value: start, endValue: end });
166
+ xAxis.createAxisRange(rangeDataItem);
167
+ rangeDataItem.get("axisFill").setAll({
168
+ visible: true,
169
+ fill: color,
170
+ fillOpacity: 0.8
171
+ });
172
+ rangeDataItem.get("label").setAll({
173
+ text: label,
174
+ inside: true,
175
+ radius: 8,
176
+ fontSize: "0.9em",
177
+ fill: am5.color(0xffffff)
178
+ });
179
+ }
180
+
181
+ createRange(0, 33, am5.color(0x4caf50), "Good");
182
+ createRange(33, 66, am5.color(0xffc107), "Warning");
183
+ createRange(66, 100, am5.color(0xf44336), "Danger");
184
+
185
+ // Needle (clock hand) — uses an axis data item
186
+ var handDataItem = xAxis.makeDataItem({ value: 42 });
187
+ xAxis.createAxisRange(handDataItem);
188
+
189
+ var hand = handDataItem.set("bullet", am5xy.AxisBullet.new(root, {
190
+ sprite: am5radar.ClockHand.new(root, {
191
+ radius: am5.percent(99),
192
+ innerRadius: am5.percent(40),
193
+ pinRadius: 10
194
+ })
195
+ }));
196
+
197
+ // Animate needle to a new value
198
+ // handDataItem.animate({ key: "value", to: 75, duration: 1000, easing: am5.ease.out(am5.ease.cubic) });
199
+
200
+ chart.appear(1000, 100);
201
+ ```
202
+
203
+ **Tip: Avoiding needle/label overlap** — When adding a value label in the gauge center, the clock hand pin and inner portion will overlap the label. Hide the pin and increase `innerRadius` to leave space:
204
+
205
+ ```js
206
+ am5radar.ClockHand.new(root, {
207
+ radius: am5.percent(99),
208
+ innerRadius: am5.percent(55), // keep needle away from center
209
+ pinRadius: 0 // hide the center pin circle
210
+ })
211
+ ```
212
+
213
+ ## Cursor
214
+
215
+ ```js
216
+ chart.set("cursor", am5radar.RadarCursor.new(root, {
217
+ behavior: "zoomX" // "none" | "zoomX" | "zoomY" | "zoomXY"
218
+ }));
219
+ ```
220
+
221
+ ## Legend
222
+
223
+ ```js
224
+ const legend = chart.children.push(am5.Legend.new(root, {
225
+ centerX: am5.percent(50),
226
+ x: am5.percent(50)
227
+ }));
228
+ legend.data.setAll(chart.series.values);
229
+ ```
230
+
231
+ ## Partial-circle radar chart
232
+
233
+ ```js
234
+ // Half radar (180 degrees)
235
+ var chart = root.container.children.push(am5radar.RadarChart.new(root, {
236
+ startAngle: -90,
237
+ endAngle: 90
238
+ }));
239
+
240
+ // Three-quarter radar (270 degrees)
241
+ var chart = root.container.children.push(am5radar.RadarChart.new(root, {
242
+ startAngle: -135,
243
+ endAngle: 135
244
+ }));
245
+ ```
246
+
247
+ ## Dynamic gauge value update
248
+
249
+ ```js
250
+ // After creating the gauge hand and data item:
251
+ // Update value from external event (button, API, timer, etc.)
252
+ function setGaugeValue(newValue) {
253
+ handDataItem.animate({
254
+ key: "value",
255
+ to: newValue,
256
+ duration: 800,
257
+ easing: am5.ease.out(am5.ease.cubic)
258
+ });
259
+ }
260
+
261
+ // Example: update every 2 seconds
262
+ setInterval(function() {
263
+ setGaugeValue(Math.random() * 100);
264
+ }, 2000);
265
+ ```
266
+
267
+ ## Axis label formatting for gauges
268
+
269
+ ```js
270
+ // Append "%" to gauge axis labels
271
+ xAxis.get("renderer").labels.template.adapters.add("text", function(text) {
272
+ return text + "%";
273
+ });
274
+
275
+ // Custom number format
276
+ xAxis.set("numberFormat", "#.#'%'");
277
+ ```
278
+
279
+ ## Events on radar elements
280
+
281
+ ```js
282
+ // Click on radar columns
283
+ columnSeries.columns.template.events.on("click", function(ev) {
284
+ var di = ev.target.dataItem;
285
+ console.log("Category:", di.get("categoryX"), "Value:", di.get("valueY"));
286
+ });
287
+
288
+ // Pointer over/out on radar line data points (via bullets)
289
+ series.bullets.push(function() {
290
+ var circle = am5.Circle.new(root, {
291
+ radius: 5,
292
+ fill: series.get("fill"),
293
+ cursorOverStyle: "pointer"
294
+ });
295
+ circle.events.on("click", function(ev) {
296
+ console.log("Clicked data point:", ev.target.dataItem.get("valueY"));
297
+ });
298
+ return am5.Bullet.new(root, { sprite: circle });
299
+ });
300
+
301
+ // Gauge needle animation complete
302
+ handDataItem.animate({
303
+ key: "value",
304
+ to: 75,
305
+ duration: 1000,
306
+ easing: am5.ease.out(am5.ease.cubic)
307
+ }).events.on("stopped", function() {
308
+ console.log("Needle animation complete");
309
+ });
310
+ ```
311
+
312
+ ## Disposal
313
+
314
+ ```js
315
+ root.dispose();
316
+ ```
317
+
318
+
319
+ ---
320
+
321
+ # amCharts 5 Radar & Gauge Charts — Working Examples
322
+
323
+ ## Example 1: Spider chart (radar line chart)
324
+
325
+ ```html
326
+ <!DOCTYPE html>
327
+ <html>
328
+ <head>
329
+ <meta charset="UTF-8">
330
+ <title>Spider Chart</title>
331
+ <script src="https://cdn.amcharts.com/lib/5/index.js"></script>
332
+ <script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
333
+ <script src="https://cdn.amcharts.com/lib/5/radar.js"></script>
334
+ <script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
335
+ <style>#chartdiv { width: 100%; height: 500px; }</style>
336
+ </head>
337
+ <body>
338
+ <div id="chartdiv"></div>
339
+ <script>
340
+ var root = am5.Root.new("chartdiv");
341
+ root.setThemes([am5themes_Animated.new(root)]);
342
+
343
+ var chart = root.container.children.push(am5radar.RadarChart.new(root, {
344
+ panX: false,
345
+ panY: false,
346
+ radius: am5.percent(80)
347
+ }));
348
+
349
+ var data = [
350
+ { category: "Speed", team1: 90, team2: 70 },
351
+ { category: "Accuracy", team1: 75, team2: 85 },
352
+ { category: "Stamina", team1: 80, team2: 60 },
353
+ { category: "Strategy", team1: 65, team2: 90 },
354
+ { category: "Teamwork", team1: 85, team2: 75 },
355
+ { category: "Defense", team1: 70, team2: 80 }
356
+ ];
357
+
358
+ // Circular axis (categories)
359
+ var xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
360
+ categoryField: "category",
361
+ renderer: am5radar.AxisRendererCircular.new(root, {
362
+ minGridDistance: 30
363
+ })
364
+ }));
365
+ xAxis.data.setAll(data);
366
+
367
+ // Radial axis (values)
368
+ var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
369
+ min: 0,
370
+ max: 100,
371
+ renderer: am5radar.AxisRendererRadial.new(root, {}),
372
+ strictMinMax: true
373
+ }));
374
+
375
+ // Helper to create series
376
+ function createSeries(name, field) {
377
+ var series = chart.series.push(am5radar.RadarLineSeries.new(root, {
378
+ name: name,
379
+ xAxis: xAxis,
380
+ yAxis: yAxis,
381
+ valueYField: field,
382
+ categoryXField: "category",
383
+ tooltip: am5.Tooltip.new(root, { labelText: "{name}: {valueY}" })
384
+ }));
385
+
386
+ series.fills.template.setAll({ visible: true, fillOpacity: 0.2 });
387
+ series.strokes.template.setAll({ strokeWidth: 2 });
388
+
389
+ series.data.setAll(data);
390
+ series.appear(1000);
391
+ return series;
392
+ }
393
+
394
+ createSeries("Team Alpha", "team1");
395
+ createSeries("Team Beta", "team2");
396
+
397
+ // Legend
398
+ var legend = chart.children.push(am5.Legend.new(root, {
399
+ centerX: am5.percent(50),
400
+ x: am5.percent(50)
401
+ }));
402
+ legend.data.setAll(chart.series.values);
403
+
404
+ chart.appear(1000, 100);
405
+ </script>
406
+ </body>
407
+ </html>
408
+ ```
409
+
410
+ ## Example 2: Gauge with colored bands
411
+
412
+ ```html
413
+ <!DOCTYPE html>
414
+ <html>
415
+ <head>
416
+ <meta charset="UTF-8">
417
+ <title>Gauge Chart</title>
418
+ <script src="https://cdn.amcharts.com/lib/5/index.js"></script>
419
+ <script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
420
+ <script src="https://cdn.amcharts.com/lib/5/radar.js"></script>
421
+ <script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
422
+ <style>#chartdiv { width: 100%; height: 400px; }</style>
423
+ </head>
424
+ <body>
425
+ <div id="chartdiv"></div>
426
+ <script>
427
+ var root = am5.Root.new("chartdiv");
428
+ root.setThemes([am5themes_Animated.new(root)]);
429
+
430
+ var chart = root.container.children.push(am5radar.RadarChart.new(root, {
431
+ panX: false,
432
+ panY: false,
433
+ startAngle: -180,
434
+ endAngle: 0,
435
+ radius: am5.percent(90),
436
+ innerRadius: -30
437
+ }));
438
+
439
+ var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
440
+ min: 0,
441
+ max: 100,
442
+ strictMinMax: true,
443
+ renderer: am5radar.AxisRendererCircular.new(root, {
444
+ strokeOpacity: 0.1,
445
+ minGridDistance: 30
446
+ })
447
+ }));
448
+
449
+ xAxis.get("renderer").ticks.template.setAll({
450
+ visible: true, strokeOpacity: 0.5
451
+ });
452
+ xAxis.get("renderer").grid.template.set("visible", false);
453
+ xAxis.get("renderer").labels.template.setAll({ fontSize: 12 });
454
+
455
+ // Colored bands
456
+ function addBand(start, end, color, label) {
457
+ var range = xAxis.makeDataItem({ value: start, endValue: end });
458
+ xAxis.createAxisRange(range);
459
+ range.get("axisFill").setAll({
460
+ visible: true, fill: color, fillOpacity: 0.8
461
+ });
462
+ range.get("label").setAll({
463
+ text: label, inside: true, radius: 8,
464
+ fontSize: "0.8em", fill: am5.color(0xffffff)
465
+ });
466
+ }
467
+
468
+ addBand(0, 30, am5.color(0x4caf50), "Good");
469
+ addBand(30, 70, am5.color(0xffc107), "Warning");
470
+ addBand(70, 100, am5.color(0xf44336), "Critical");
471
+
472
+ // Needle
473
+ var handDataItem = xAxis.makeDataItem({ value: 0 });
474
+ xAxis.createAxisRange(handDataItem);
475
+
476
+ handDataItem.set("bullet", am5xy.AxisBullet.new(root, {
477
+ sprite: am5radar.ClockHand.new(root, {
478
+ radius: am5.percent(99),
479
+ innerRadius: am5.percent(55),
480
+ pinRadius: 0 // hidden — avoids overlap with center label
481
+ })
482
+ }));
483
+
484
+ // Animate needle to value
485
+ handDataItem.animate({
486
+ key: "value",
487
+ to: 62,
488
+ duration: 1500,
489
+ easing: am5.ease.out(am5.ease.cubic)
490
+ });
491
+
492
+ // Value label in center
493
+ chart.children.push(am5.Label.new(root, {
494
+ text: "62%",
495
+ fontSize: 28,
496
+ fontWeight: "500",
497
+ centerX: am5.percent(50),
498
+ centerY: am5.percent(100),
499
+ x: am5.percent(50),
500
+ y: am5.percent(65)
501
+ }));
502
+
503
+ chart.appear(1000, 100);
504
+ </script>
505
+ </body>
506
+ </html>
507
+ ```
508
+
509
+ ## Example 3: Radar column chart
510
+
511
+ ```html
512
+ <!DOCTYPE html>
513
+ <html>
514
+ <head>
515
+ <meta charset="UTF-8">
516
+ <title>Radar Column Chart</title>
517
+ <script src="https://cdn.amcharts.com/lib/5/index.js"></script>
518
+ <script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
519
+ <script src="https://cdn.amcharts.com/lib/5/radar.js"></script>
520
+ <script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
521
+ <style>#chartdiv { width: 100%; height: 500px; }</style>
522
+ </head>
523
+ <body>
524
+ <div id="chartdiv"></div>
525
+ <script>
526
+ var root = am5.Root.new("chartdiv");
527
+ root.setThemes([am5themes_Animated.new(root)]);
528
+
529
+ var chart = root.container.children.push(am5radar.RadarChart.new(root, {
530
+ panX: false,
531
+ panY: false,
532
+ radius: am5.percent(85),
533
+ innerRadius: am5.percent(30)
534
+ }));
535
+
536
+ var data = [
537
+ { month: "Jan", sales: 120 }, { month: "Feb", sales: 150 },
538
+ { month: "Mar", sales: 200 }, { month: "Apr", sales: 180 },
539
+ { month: "May", sales: 220 }, { month: "Jun", sales: 250 },
540
+ { month: "Jul", sales: 230 }, { month: "Aug", sales: 210 },
541
+ { month: "Sep", sales: 190 }, { month: "Oct", sales: 240 },
542
+ { month: "Nov", sales: 260 }, { month: "Dec", sales: 300 }
543
+ ];
544
+
545
+ var xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
546
+ categoryField: "month",
547
+ renderer: am5radar.AxisRendererCircular.new(root, { minGridDistance: 20 })
548
+ }));
549
+ xAxis.data.setAll(data);
550
+
551
+ var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
552
+ min: 0,
553
+ renderer: am5radar.AxisRendererRadial.new(root, {})
554
+ }));
555
+
556
+ var series = chart.series.push(am5radar.RadarColumnSeries.new(root, {
557
+ name: "Sales",
558
+ xAxis: xAxis,
559
+ yAxis: yAxis,
560
+ valueYField: "sales",
561
+ categoryXField: "month",
562
+ tooltip: am5.Tooltip.new(root, { labelText: "{month}: {valueY}" })
563
+ }));
564
+
565
+ series.columns.template.setAll({
566
+ strokeOpacity: 0,
567
+ fillOpacity: 0.8,
568
+ width: am5.percent(80),
569
+ cornerRadiusTL: 3,
570
+ cornerRadiusTR: 3
571
+ });
572
+
573
+ // Color each column differently
574
+ series.columns.template.adapters.add("fill", function(fill, target) {
575
+ return chart.get("colors").getIndex(series.columns.indexOf(target));
576
+ });
577
+
578
+ series.data.setAll(data);
579
+ series.appear(1000);
580
+ chart.appear(1000, 100);
581
+ </script>
582
+ </body>
583
+ </html>
584
+ ```