@amcharts/amcharts5-mcp 1.1.5 → 1.1.7
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/README.md +4 -4
- package/content/flow.md +1 -1
- package/content/map.md +203 -46
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# amCharts 5 MCP Server
|
|
2
2
|
|
|
3
|
-
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that gives AI assistants on-demand access to the complete amCharts 5 knowledge base: **
|
|
3
|
+
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that gives AI assistants on-demand access to the complete amCharts 5 knowledge base: **140+ documentation pages**, **280+ code examples**, and **1,000+ class API references**.
|
|
4
4
|
|
|
5
5
|
Works with **Claude Code**, **Claude Desktop**, **Cursor**, **Windsurf**, **VS Code + GitHub Copilot**, and any other MCP-compatible AI tool.
|
|
6
6
|
|
|
@@ -132,9 +132,9 @@ Once connected, your AI assistant can:
|
|
|
132
132
|
|
|
133
133
|
The server includes **1,500+ documents**:
|
|
134
134
|
|
|
135
|
-
- **
|
|
136
|
-
- **
|
|
137
|
-
- **1,
|
|
135
|
+
- **140+ documentation pages** — getting started, chart guides, concepts (themes, events, adapters, data binding, animations, accessibility, etc.), and framework integration guides (React, Angular, Vue, Next.js, Svelte, and more)
|
|
136
|
+
- **280+ code examples** — working demos across 16 categories including column/bar, line/area, pie/donut, maps, hierarchy, flow, radar/polar, stock, gauges, Gantt, timeline, and more
|
|
137
|
+
- **1,000+ class API references** — every class in the amCharts 5 library with its settings, properties, methods, events, and inheritance chain
|
|
138
138
|
- **Curated skill reference** — quick-start templates and chart-specific guides from the [amCharts 5 AI Skill](https://github.com/amcharts/amcharts5-skill)
|
|
139
139
|
|
|
140
140
|
## License
|
package/content/flow.md
CHANGED
|
@@ -42,7 +42,7 @@ Node IDs ("A", "B", etc.) are automatically extracted — you don't define nodes
|
|
|
42
42
|
| `am5flow.ChordNonRibbon` | Chord with line links | Arc nodes + line links |
|
|
43
43
|
| `am5flow.ArcDiagram` | Arc connections between linear nodes | Linear nodes + arc links |
|
|
44
44
|
|
|
45
|
-
**Geographic Sankey (MapSankeySeries):** For Sankey-style flow bands drawn on a geographic map, use `am5map.MapSankeySeries` from the **map** package (not flow). See `references/map.md`
|
|
45
|
+
**Geographic Sankey (MapSankeySeries):** For Sankey-style flow bands drawn on a geographic map, use `am5map.MapSankeySeries` from the **map** package (not flow). See `references/map.md` > MapSankeySeries section.
|
|
46
46
|
|
|
47
47
|
## Sankey diagram
|
|
48
48
|
|
package/content/map.md
CHANGED
|
@@ -36,7 +36,7 @@ CDN: `https://cdn.amcharts.com/lib/5/geodata/{mapName}.js`
|
|
|
36
36
|
Pattern: camelCase country name + detail level. E.g. `germanyLow`, `canadaHigh`, `chinaLow`.
|
|
37
37
|
|
|
38
38
|
**IMPORTANT — regional/continent geodata:**
|
|
39
|
-
- Individual country maps: `geodata/{countryName}Low.js`
|
|
39
|
+
- Individual country maps: `geodata/{countryName}Low.js` > global `am5geodata_{countryName}Low`
|
|
40
40
|
- **There are NO continent-level maps** like `europeLow.js` or `asiaLow.js` at the top-level CDN path
|
|
41
41
|
- Regional maps are in subdirectories: `geodata/region/world/{regionName}Low.js`
|
|
42
42
|
- CDN: `https://cdn.amcharts.com/lib/5/geodata/region/world/europeLow.js`
|
|
@@ -239,18 +239,26 @@ var sankeySeries = chart.series.push(
|
|
|
239
239
|
|
|
240
240
|
#### Data format
|
|
241
241
|
|
|
242
|
-
|
|
242
|
+
Two data patterns — polygon IDs or explicit coordinates.
|
|
243
|
+
|
|
244
|
+
**Pattern 1: `sourceId` / `targetId` (country codes)**
|
|
245
|
+
|
|
246
|
+
IDs use ISO 3166-1 alpha-2 codes matching the geodata. **CRITICAL:** Data MUST be set inside `polygonSeries.events.once("datavalidated", ...)` — the polygon series needs to finish parsing geoJSON before MapSankeySeries can resolve country IDs to centroids. Without this wrapper, `getDataItemById()` returns null and flows silently don't appear (no errors, no bands).
|
|
243
247
|
|
|
244
248
|
```js
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
249
|
+
polygonSeries.events.once("datavalidated", function() {
|
|
250
|
+
sankeySeries.data.setAll([
|
|
251
|
+
{ sourceId: "BR", targetId: "DE", value: 350 },
|
|
252
|
+
{ sourceId: "BR", targetId: "US", value: 450 },
|
|
253
|
+
{ sourceId: "DE", targetId: "FR", value: 150 },
|
|
254
|
+
{ sourceId: "DE", targetId: "PL", value: 100 }
|
|
255
|
+
]);
|
|
256
|
+
});
|
|
251
257
|
```
|
|
252
258
|
|
|
253
|
-
**Explicit coordinates
|
|
259
|
+
**Pattern 2: Explicit coordinates (no timing needed)**
|
|
260
|
+
|
|
261
|
+
When using `sourceLongitude`/`sourceLatitude`/`targetLongitude`/`targetLatitude`, data can be set immediately — no `datavalidated` wrapper required:
|
|
254
262
|
```js
|
|
255
263
|
sankeySeries.data.setAll([
|
|
256
264
|
{
|
|
@@ -263,15 +271,28 @@ sankeySeries.data.setAll([
|
|
|
263
271
|
|
|
264
272
|
**Waypoints** — route flows through intermediate points:
|
|
265
273
|
```js
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
274
|
+
polygonSeries.events.once("datavalidated", function() {
|
|
275
|
+
sankeySeries.data.setAll([
|
|
276
|
+
{
|
|
277
|
+
sourceId: "GB", targetId: "JP", value: 40,
|
|
278
|
+
waypoints: [
|
|
279
|
+
{ longitude: 30, latitude: 65 },
|
|
280
|
+
{ longitude: 90, latitude: 55 }
|
|
281
|
+
]
|
|
282
|
+
}
|
|
283
|
+
]);
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**WARNING:** Never call `polygonSeries.data.setAll()` with custom objects — this replaces all geoJSON-derived data items, breaking MapSankeySeries centroid resolution. To set per-country properties (like colors), iterate existing data items after `datavalidated` instead:
|
|
288
|
+
```js
|
|
289
|
+
polygonSeries.events.on("datavalidated", function() {
|
|
290
|
+
am5.array.each(polygonSeries.dataItems, function(di) {
|
|
291
|
+
if (di.get("id") === "BR") {
|
|
292
|
+
di.get("mapPolygon").setAll({ fill: am5.color(0x8fae7e) });
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
});
|
|
275
296
|
```
|
|
276
297
|
|
|
277
298
|
#### Key settings
|
|
@@ -307,7 +328,7 @@ sankeySeries.mapPolygons.template.setAll({
|
|
|
307
328
|
fill: am5.color(0xff6b35),
|
|
308
329
|
fillOpacity: 0.6,
|
|
309
330
|
strokeOpacity: 0,
|
|
310
|
-
tooltipText: "{sourceId}
|
|
331
|
+
tooltipText: "{sourceId} > {targetId}: {value}"
|
|
311
332
|
});
|
|
312
333
|
```
|
|
313
334
|
|
|
@@ -321,10 +342,10 @@ sankeySeries.data.setAll([
|
|
|
321
342
|
|
|
322
343
|
#### Node configuration
|
|
323
344
|
|
|
324
|
-
Each unique endpoint gets a node shape. Configure via `
|
|
345
|
+
Each unique endpoint gets a node shape. Configure via `nodes.mapPolygons.template`:
|
|
325
346
|
|
|
326
347
|
```js
|
|
327
|
-
sankeySeries.
|
|
348
|
+
sankeySeries.nodes.mapPolygons.template.setAll({
|
|
328
349
|
fill: am5.color(0x8b5e3c),
|
|
329
350
|
fillOpacity: 0.9,
|
|
330
351
|
stroke: am5.color(0xffffff),
|
|
@@ -384,14 +405,16 @@ Bullets automatically hide on the back side of the globe (orthographic projectio
|
|
|
384
405
|
The same country can be both target and source — incoming and outgoing bands share unified stacking at intermediate nodes:
|
|
385
406
|
|
|
386
407
|
```js
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
408
|
+
polygonSeries.events.once("datavalidated", function() {
|
|
409
|
+
sankeySeries.data.setAll([
|
|
410
|
+
// Level 1: Producers > Hubs
|
|
411
|
+
{ sourceId: "BR", targetId: "DE", value: 350 },
|
|
412
|
+
{ sourceId: "VN", targetId: "DE", value: 200 },
|
|
413
|
+
// Level 2: Hubs > Consumers
|
|
414
|
+
{ sourceId: "DE", targetId: "FR", value: 150 },
|
|
415
|
+
{ sourceId: "DE", targetId: "PL", value: 100 }
|
|
416
|
+
]);
|
|
417
|
+
});
|
|
395
418
|
```
|
|
396
419
|
|
|
397
420
|
### Animating bullets along lines (positionOnLine)
|
|
@@ -430,7 +453,7 @@ plane.on("positionOnLine", function(pos) {
|
|
|
430
453
|
|
|
431
454
|
**IMPORTANT — Multi-segment lines and `positionOnLine`:**
|
|
432
455
|
- `positionOnLine` treats the entire line as one unit (0 = start, 1 = end). If a line has multiple segments (i.e. `pointsToConnect` has 3+ points), position 0.5 is the midpoint of the *entire* path.
|
|
433
|
-
- For advanced per-segment animations (e.g., scaling the bullet differently at the midpoint of each segment, or pausing between segments), use **single-segment lines** (2 points each) instead of one multi-segment line. This gives you full control: animate `positionOnLine` from 0
|
|
456
|
+
- For advanced per-segment animations (e.g., scaling the bullet differently at the midpoint of each segment, or pausing between segments), use **single-segment lines** (2 points each) instead of one multi-segment line. This gives you full control: animate `positionOnLine` from 0 to 1 on each segment line sequentially, with independent timing, easing, and callbacks per segment.
|
|
434
457
|
- Example: instead of one line with points [A, B, C, D], create three lines: [A,B], [B,C], [C,D] and animate the bullet across them one at a time.
|
|
435
458
|
|
|
436
459
|
## Zoom controls
|
|
@@ -491,7 +514,7 @@ backgroundSeries.data.push({
|
|
|
491
514
|
chart.series.push(am5map.GraticuleSeries.new(root, {}));
|
|
492
515
|
```
|
|
493
516
|
|
|
494
|
-
## Drill-down map (country
|
|
517
|
+
## Drill-down map (country > states)
|
|
495
518
|
|
|
496
519
|
```js
|
|
497
520
|
// World-level polygons
|
|
@@ -1102,33 +1125,167 @@ Demonstrates: `MapSankeySeries` with geographic flow bands, node circles, toolti
|
|
|
1102
1125
|
fill: am5.color(0xff6b35),
|
|
1103
1126
|
fillOpacity: 0.5,
|
|
1104
1127
|
strokeOpacity: 0,
|
|
1105
|
-
tooltipText: "{sourceId}
|
|
1128
|
+
tooltipText: "{sourceId} > {targetId}: {value}B"
|
|
1106
1129
|
});
|
|
1107
1130
|
|
|
1108
1131
|
// Node appearance
|
|
1109
|
-
sankeySeries.
|
|
1132
|
+
sankeySeries.nodes.mapPolygons.template.setAll({
|
|
1110
1133
|
fill: am5.color(0x8b5e3c),
|
|
1111
1134
|
fillOpacity: 0.9,
|
|
1112
1135
|
stroke: am5.color(0xffffff),
|
|
1113
1136
|
strokeWidth: 1.5
|
|
1114
1137
|
});
|
|
1115
1138
|
|
|
1116
|
-
//
|
|
1139
|
+
// Set data AFTER polygonSeries parses geoJSON (required for sourceId/targetId)
|
|
1140
|
+
polygonSeries.events.once("datavalidated", function() {
|
|
1141
|
+
sankeySeries.data.setAll([
|
|
1142
|
+
// Producers > Trade hubs
|
|
1143
|
+
{ sourceId: "BR", targetId: "DE", value: 350 },
|
|
1144
|
+
{ sourceId: "BR", targetId: "US", value: 450 },
|
|
1145
|
+
{ sourceId: "CN", targetId: "DE", value: 500 },
|
|
1146
|
+
{ sourceId: "CN", targetId: "US", value: 600 },
|
|
1147
|
+
{ sourceId: "AU", targetId: "JP", value: 200 },
|
|
1148
|
+
{ sourceId: "AU", targetId: "CN", value: 300 },
|
|
1149
|
+
// Hubs > Consumers
|
|
1150
|
+
{ sourceId: "DE", targetId: "FR", value: 250 },
|
|
1151
|
+
{ sourceId: "DE", targetId: "GB", value: 300 },
|
|
1152
|
+
{ sourceId: "US", targetId: "CA", value: 400 },
|
|
1153
|
+
{ sourceId: "JP", targetId: "KR", value: 100 }
|
|
1154
|
+
]);
|
|
1155
|
+
});
|
|
1156
|
+
|
|
1157
|
+
chart.set("zoomControl", am5map.ZoomControl.new(root, {}));
|
|
1158
|
+
chart.appear(1000, 100);
|
|
1159
|
+
</script>
|
|
1160
|
+
</body>
|
|
1161
|
+
</html>
|
|
1162
|
+
```
|
|
1163
|
+
|
|
1164
|
+
## Example 6: Map Sankey — explicit coordinates with waypoints
|
|
1165
|
+
|
|
1166
|
+
Demonstrates: `MapSankeySeries` with explicit `sourceLongitude`/`sourceLatitude` coordinates, waypoints for routing, and animated bullets. No `datavalidated` timing needed when using explicit coordinates.
|
|
1167
|
+
|
|
1168
|
+
```html
|
|
1169
|
+
<!DOCTYPE html>
|
|
1170
|
+
<html>
|
|
1171
|
+
<head>
|
|
1172
|
+
<meta charset="UTF-8">
|
|
1173
|
+
<title>Map Sankey — Oil Flows</title>
|
|
1174
|
+
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
|
|
1175
|
+
<script src="https://cdn.amcharts.com/lib/5/map.js"></script>
|
|
1176
|
+
<script src="https://cdn.amcharts.com/lib/5/geodata/worldLow.js"></script>
|
|
1177
|
+
<script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
|
|
1178
|
+
<style>body { background: #1a2a3a; margin: 0; } #chartdiv { width: 100%; height: 600px; }</style>
|
|
1179
|
+
</head>
|
|
1180
|
+
<body>
|
|
1181
|
+
<div id="chartdiv"></div>
|
|
1182
|
+
<script>
|
|
1183
|
+
var root = am5.Root.new("chartdiv");
|
|
1184
|
+
root.setThemes([am5themes_Animated.new(root)]);
|
|
1185
|
+
|
|
1186
|
+
var chart = root.container.children.push(am5map.MapChart.new(root, {
|
|
1187
|
+
panX: "rotateX",
|
|
1188
|
+
panY: "rotateY",
|
|
1189
|
+
projection: am5map.geoOrthographic(),
|
|
1190
|
+
rotationX: -54,
|
|
1191
|
+
rotationY: -25
|
|
1192
|
+
}));
|
|
1193
|
+
|
|
1194
|
+
var bgSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {}));
|
|
1195
|
+
bgSeries.mapPolygons.template.setAll({ fill: am5.color(0x111d2d), fillOpacity: 1, strokeOpacity: 0 });
|
|
1196
|
+
bgSeries.data.push({ geometry: am5map.getGeoRectangle(90, 180, -90, -180) });
|
|
1197
|
+
|
|
1198
|
+
var polygonSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {
|
|
1199
|
+
geoJSON: am5geodata_worldLow
|
|
1200
|
+
}));
|
|
1201
|
+
polygonSeries.mapPolygons.template.setAll({
|
|
1202
|
+
fill: am5.color(0x2c4a6a),
|
|
1203
|
+
stroke: am5.color(0x1a2a3a),
|
|
1204
|
+
strokeWidth: 0.5
|
|
1205
|
+
});
|
|
1206
|
+
|
|
1207
|
+
var sankeySeries = chart.series.push(am5map.MapSankeySeries.new(root, {
|
|
1208
|
+
polygonSeries: polygonSeries,
|
|
1209
|
+
maxWidth: 3,
|
|
1210
|
+
controlPointDistance: 0.3,
|
|
1211
|
+
resolution: 60
|
|
1212
|
+
}));
|
|
1213
|
+
|
|
1214
|
+
sankeySeries.mapPolygons.template.setAll({
|
|
1215
|
+
fill: am5.color(0xd4a017),
|
|
1216
|
+
fillOpacity: 0.6,
|
|
1217
|
+
strokeOpacity: 0,
|
|
1218
|
+
tooltipText: "{source} > {target}: {value}M barrels/day"
|
|
1219
|
+
});
|
|
1220
|
+
|
|
1221
|
+
sankeySeries.nodes.mapPolygons.template.setAll({
|
|
1222
|
+
fill: am5.color(0xd4a017),
|
|
1223
|
+
stroke: am5.color(0xf0e6d0),
|
|
1224
|
+
strokeWidth: 1.5,
|
|
1225
|
+
fillOpacity: 0.9,
|
|
1226
|
+
tooltipText: "{name}"
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
// Helper for explicit-coordinate data with optional waypoints
|
|
1230
|
+
function flow(src, srcName, tgt, tgtName, val, wp) {
|
|
1231
|
+
var result = {
|
|
1232
|
+
sourceLongitude: src.lon, sourceLatitude: src.lat,
|
|
1233
|
+
targetLongitude: tgt.lon, targetLatitude: tgt.lat,
|
|
1234
|
+
source: srcName, target: tgtName, value: val
|
|
1235
|
+
};
|
|
1236
|
+
if (wp) result.waypoints = wp;
|
|
1237
|
+
return result;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
var saudiPort = { lon: 50.2, lat: 26.6 };
|
|
1241
|
+
var hormuz = { lon: 56.3, lat: 26.6 };
|
|
1242
|
+
var india = { lon: 72.8, lat: 19.1 };
|
|
1243
|
+
var china = { lon: 121.5, lat: 31.2 };
|
|
1244
|
+
var japan = { lon: 139.7, lat: 35.7 };
|
|
1245
|
+
var europe = { lon: 9.5, lat: 44.4 };
|
|
1246
|
+
var suez = { lon: 32.3, lat: 30.0 };
|
|
1247
|
+
|
|
1248
|
+
// No datavalidated wrapper needed — explicit coordinates resolve immediately
|
|
1117
1249
|
sankeySeries.data.setAll([
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
{ sourceId: "DE", targetId: "FR", value: 250 },
|
|
1127
|
-
{ sourceId: "DE", targetId: "GB", value: 300 },
|
|
1128
|
-
{ sourceId: "US", targetId: "CA", value: 400 },
|
|
1129
|
-
{ sourceId: "JP", targetId: "KR", value: 100 }
|
|
1250
|
+
flow(saudiPort, "Saudi Arabia", china, "China", 1.8,
|
|
1251
|
+
[hormuz, { lon: 65, lat: 20 }, { lon: 80, lat: 15 }, { lon: 105, lat: 20 }]),
|
|
1252
|
+
flow(saudiPort, "Saudi Arabia", japan, "Japan", 1.2,
|
|
1253
|
+
[hormuz, { lon: 70, lat: 22 }, { lon: 100, lat: 18 }, { lon: 125, lat: 28 }]),
|
|
1254
|
+
flow(saudiPort, "Saudi Arabia", india, "India", 0.9,
|
|
1255
|
+
[hormuz, { lon: 62, lat: 22 }]),
|
|
1256
|
+
flow(saudiPort, "Saudi Arabia", europe, "Europe", 1.0,
|
|
1257
|
+
[{ lon: 43, lat: 28 }, suez, { lon: 20, lat: 36 }])
|
|
1130
1258
|
]);
|
|
1131
1259
|
|
|
1260
|
+
// Animated bullets along flow paths
|
|
1261
|
+
sankeySeries.bullets.push(function() {
|
|
1262
|
+
return am5.Bullet.new(root, {
|
|
1263
|
+
locationX: 0,
|
|
1264
|
+
autoRotate: true,
|
|
1265
|
+
sprite: am5.Circle.new(root, {
|
|
1266
|
+
radius: 2,
|
|
1267
|
+
fill: am5.color(0xd4a017)
|
|
1268
|
+
})
|
|
1269
|
+
});
|
|
1270
|
+
});
|
|
1271
|
+
|
|
1272
|
+
sankeySeries.events.on("datavalidated", function() {
|
|
1273
|
+
am5.array.each(sankeySeries.dataItems, function(dataItem) {
|
|
1274
|
+
var bullets = dataItem.bullets;
|
|
1275
|
+
if (bullets) {
|
|
1276
|
+
am5.array.each(bullets, function(bullet) {
|
|
1277
|
+
bullet.animate({
|
|
1278
|
+
key: "locationX",
|
|
1279
|
+
from: 0, to: 1,
|
|
1280
|
+
duration: 3000 + Math.random() * 3000,
|
|
1281
|
+
easing: am5.ease.linear,
|
|
1282
|
+
loops: Infinity
|
|
1283
|
+
});
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
});
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1132
1289
|
chart.set("zoomControl", am5map.ZoomControl.new(root, {}));
|
|
1133
1290
|
chart.appear(1000, 100);
|
|
1134
1291
|
</script>
|