@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 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: **141 documentation pages**, **283 code examples**, and **1,098 class API references**.
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
- - **141 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
- - **283 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,098 class API references** — every class in the amCharts 5 library with its settings, properties, methods, events, and inheritance chain
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` → MapSankeySeries section.
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` → global `am5geodata_{countryName}Low`
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
- Each item needs `sourceId`, `targetId`, and `value`. IDs use ISO 3166-1 alpha-2 codes matching the geodata.
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
- sankeySeries.data.setAll([
246
- { sourceId: "BR", targetId: "DE", value: 350 },
247
- { sourceId: "BR", targetId: "US", value: 450 },
248
- { sourceId: "DE", targetId: "FR", value: 150 },
249
- { sourceId: "DE", targetId: "PL", value: 100 }
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** instead of polygon IDs:
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
- sankeySeries.data.setAll([
267
- {
268
- sourceId: "GB", targetId: "JP", value: 40,
269
- waypoints: [
270
- { longitude: 30, latitude: 65 },
271
- { longitude: 90, latitude: 55 }
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} → {targetId}: {value}"
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 `mapCircles.template`:
345
+ Each unique endpoint gets a node shape. Configure via `nodes.mapPolygons.template`:
325
346
 
326
347
  ```js
327
- sankeySeries.mapCircles.template.setAll({
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
- sankeySeries.data.setAll([
388
- // Level 1: Producers → Hubs
389
- { sourceId: "BR", targetId: "DE", value: 350 },
390
- { sourceId: "VN", targetId: "DE", value: 200 },
391
- // Level 2: Hubs → Consumers
392
- { sourceId: "DE", targetId: "FR", value: 150 },
393
- { sourceId: "DE", targetId: "PL", value: 100 }
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→1 on each segment line sequentially, with independent timing, easing, and callbacks per segment.
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 → states)
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} → {targetId}: {value}B"
1128
+ tooltipText: "{sourceId} > {targetId}: {value}B"
1106
1129
  });
1107
1130
 
1108
1131
  // Node appearance
1109
- sankeySeries.mapCircles.template.setAll({
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
- // Multi-level trade data
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
- // Producers → Trade hubs
1119
- { sourceId: "BR", targetId: "DE", value: 350 },
1120
- { sourceId: "BR", targetId: "US", value: 450 },
1121
- { sourceId: "CN", targetId: "DE", value: 500 },
1122
- { sourceId: "CN", targetId: "US", value: 600 },
1123
- { sourceId: "AU", targetId: "JP", value: 200 },
1124
- { sourceId: "AU", targetId: "CN", value: 300 },
1125
- // Hubs → Consumers
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>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amcharts/amcharts5-mcp",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "mcpName": "io.github.amcharts/amcharts5",
5
5
  "description": "On-demand access to amCharts 5 docs, code examples, and API reference",
6
6
  "type": "module",