# amCharts 5 — Full AI Context Reference > amCharts 5 is a comprehensive JavaScript/TypeScript data visualization library for building interactive charts, maps, and graphs. Canvas-based rendering. Supports React, Angular, Vue, Next.js, SvelteKit, Nuxt, Remix, and vanilla JS/TS. Commercial license required for commercial use. **Important:** Always use amCharts 5 syntax. Do NOT use amCharts 4. The APIs are completely different. --- ## Installation ```bash npm install @amcharts/amcharts5 npm install @amcharts/amcharts5-geodata # for maps npm install @amcharts/amcharts5-fonts # for PDF export ``` CDN: ```html ``` --- ## Core Patterns ### Root element (required for every chart) ```js import * as am5 from "@amcharts/amcharts5"; import am5themes_Animated from "@amcharts/amcharts5/themes/Animated"; // Create root var root = am5.Root.new("chartdiv"); // Apply theme (always apply before creating charts) root.setThemes([am5themes_Animated.new(root)]); // Dispose on cleanup (critical for React/Angular/Vue) // root.dispose(); ``` ### Settings API All amCharts 5 elements use a unified settings API: ```js element.set("settingName", value); element.get("settingName"); element.setAll({ setting1: value1, setting2: value2 }); ``` ### Adapters ```js series.adapters.add("fill", function(fill, target) { if (target.dataItem.get("valueY") < 0) { return am5.color(0xff0000); } return fill; }); ``` ### Events ```js series.events.on("click", function(ev) { console.log(ev.target); }); ``` ### Templates and bullets ```js series.bullets.push(function() { return am5.Bullet.new(root, { sprite: am5.Circle.new(root, { radius: 5, fill: series.get("fill") }) }); }); ``` --- ## XY Chart Handles: line, area, bar, column, scatter, candlestick, OHLC, step, smoothed. ```js import * as am5xy from "@amcharts/amcharts5/xy"; var chart = root.container.children.push( am5xy.XYChart.new(root, { panX: true, panY: true, wheelX: "panX", wheelY: "zoomX", pinchZoomX: true }) ); // X axis (category) var xAxis = chart.xAxes.push( am5xy.CategoryAxis.new(root, { maxDeviation: 0.3, categoryField: "category", renderer: am5xy.AxisRendererX.new(root, { minGridDistance: 30 }) }) ); // X axis (date) var xAxis = chart.xAxes.push( am5xy.DateAxis.new(root, { maxDeviation: 0.2, baseInterval: { timeUnit: "day", count: 1 }, renderer: am5xy.AxisRendererX.new(root, {}) }) ); // Y axis (value) var yAxis = chart.yAxes.push( am5xy.ValueAxis.new(root, { renderer: am5xy.AxisRendererY.new(root, {}) }) ); // Line series var series = chart.series.push( am5xy.LineSeries.new(root, { name: "Series", xAxis: xAxis, yAxis: yAxis, valueYField: "value", valueXField: "date", // for date axis categoryXField: "category", // for category axis tooltip: am5.Tooltip.new(root, { labelText: "{valueY}" }) }) ); // Column series var series = chart.series.push( am5xy.ColumnSeries.new(root, { name: "Series", xAxis: xAxis, yAxis: yAxis, valueYField: "value", categoryXField: "category" }) ); // Set data xAxis.data.setAll(data); series.data.setAll(data); // Animate on load series.appear(1000); chart.appear(1000, 100); ``` ### Scrollbar ```js chart.set("scrollbarX", am5xy.XYChartScrollbar.new(root, { orientation: "horizontal", height: 60 })); ``` ### Cursor ```js var cursor = chart.set("cursor", am5xy.XYCursor.new(root, { behavior: "zoomXY" })); cursor.lineY.set("visible", false); ``` ### Legend ```js var legend = chart.children.push(am5.Legend.new(root, {})); legend.data.setAll(chart.series.values); ``` ### Axis ranges ```js var rangeDataItem = yAxis.makeDataItem({ value: 0, endValue: 100 }); var range = yAxis.createAxisRange(rangeDataItem); range.get("axisFill").setAll({ fill: am5.color(0xff0000), fillOpacity: 0.1, visible: true }); ``` ### Stacked series ```js // On each series: series.set("stacked", true); ``` ### Date axis grouping ```js var xAxis = chart.xAxes.push( am5xy.DateAxis.new(root, { groupData: true, baseInterval: { timeUnit: "day", count: 1 }, renderer: am5xy.AxisRendererX.new(root, {}) }) ); ``` --- ## Pie / Donut Chart ```js import * as am5percent from "@amcharts/amcharts5/percent"; var chart = root.container.children.push( am5percent.PieChart.new(root, { innerRadius: am5.percent(50), // remove for regular pie, set for donut layout: root.horizontalLayout }) ); var series = chart.series.push( am5percent.PieSeries.new(root, { valueField: "value", categoryField: "category", tooltip: am5.Tooltip.new(root, { labelText: "{category}: {value}" }) }) ); series.data.setAll([ { category: "A", value: 40 }, { category: "B", value: 30 }, { category: "C", value: 30 } ]); var legend = chart.children.push(am5.Legend.new(root, { centerX: am5.percent(50), x: am5.percent(50), layout: root.horizontalLayout })); legend.data.setAll(series.dataItems); series.appear(1000, 100); ``` ### Funnel / Pyramid ```js var chart = root.container.children.push( am5percent.SlicedChart.new(root, { layout: root.horizontalLayout }) ); var series = chart.series.push( am5percent.FunnelSeries.new(root, { // or PyramidSeries valueField: "value", categoryField: "category", orientation: "vertical" }) ); ``` --- ## Radar / Spider / Gauge Chart ```js import * as am5radar from "@amcharts/amcharts5/radar"; var chart = root.container.children.push( am5radar.RadarChart.new(root, { panX: false, panY: false, wheelX: "none", wheelY: "none" }) ); var xRenderer = am5radar.AxisRendererCircular.new(root, {}); var xAxis = chart.xAxes.push( am5xy.CategoryAxis.new(root, { maxDeviation: 0, categoryField: "category", renderer: xRenderer }) ); var yAxis = chart.yAxes.push( am5xy.ValueAxis.new(root, { min: 0, renderer: am5radar.AxisRendererRadial.new(root, { minGridDistance: 20 }) }) ); var series = chart.series.push( am5radar.RadarLineSeries.new(root, { name: "Series", xAxis: xAxis, yAxis: yAxis, valueYField: "value", categoryXField: "category", fill: am5.color(0x297373), stroke: am5.color(0x297373) }) ); series.fills.template.setAll({ fillOpacity: 0.3, visible: true }); ``` ### Gauge (ClockHand) ```js var chart = root.container.children.push( am5radar.RadarChart.new(root, { startAngle: -90, endAngle: 180 }) ); var axisRenderer = am5radar.AxisRendererCircular.new(root, { innerRadius: -40 }); var xAxis = chart.xAxes.push( am5xy.ValueAxis.new(root, { min: 0, max: 100, strictMinMax: true, renderer: axisRenderer }) ); var hand = chart.series.push( am5radar.ClockHand.new(root, { pinRadius: am5.percent(20), radius: am5.percent(100), bottomWidth: 40 }) ); hand.dataItem.animate({ key: "value", to: 75, duration: 800, easing: am5.ease.out(am5.ease.cubic) }); ``` --- ## Map Chart ```js import * as am5map from "@amcharts/amcharts5/map"; import am5geodata_worldLow from "@amcharts/amcharts5-geodata/worldLow"; var chart = root.container.children.push( am5map.MapChart.new(root, { panX: "rotateX", panY: "rotateY", projection: am5map.geoNaturalEarth1() // or geoMercator(), geoOrthographic() }) ); // Polygon (country fills) series var polygonSeries = chart.series.push( am5map.MapPolygonSeries.new(root, { geoJSON: am5geodata_worldLow, exclude: ["AQ"] // exclude Antarctica }) ); polygonSeries.mapPolygons.template.setAll({ fill: am5.color(0x74B266), tooltipText: "{name}" }); // Choropleth (heat map) polygonSeries.set("heatRules", [{ target: polygonSeries.mapPolygons.template, dataField: "value", min: am5.color(0xff621f), max: am5.color(0x661f00), key: "fill" }]); polygonSeries.data.setAll([ { id: "US", value: 100 }, { id: "GB", value: 80 } ]); // Point series var pointSeries = chart.series.push( am5map.MapPointSeries.new(root, {}) ); pointSeries.bullets.push(function() { return am5.Bullet.new(root, { sprite: am5.Circle.new(root, { radius: 5, fill: am5.color(0xff0000) }) }); }); pointSeries.data.setAll([ { geometry: { type: "Point", coordinates: [-73.935242, 40.730610] }, name: "New York" } ]); ``` --- ## Hierarchy Charts ```js import * as am5hierarchy from "@amcharts/amcharts5/hierarchy"; // Treemap var series = root.container.children.push( am5hierarchy.Treemap.new(root, { singleBranchOnly: false, downDepth: 1, upDepth: -1, initialDepth: 2, valueField: "value", categoryField: "name", childDataField: "children", nodePaddingOuter: 0, nodePaddingInner: 0 }) ); // Force-directed var series = root.container.children.push( am5hierarchy.ForceDirected.new(root, { singleBranchOnly: false, downDepth: 1, initialDepth: 2, valueField: "value", categoryField: "name", childDataField: "children", idField: "name", linkWithField: "linkWith", manyBodyStrength: -20, centerStrength: 0.8 }) ); // Sunburst var series = root.container.children.push( am5hierarchy.Sunburst.new(root, { singleBranchOnly: false, downDepth: 2, upDepth: -1, initialDepth: 3, valueField: "value", categoryField: "name", childDataField: "children" }) ); // Data format (same for all hierarchy types) var data = { name: "Root", children: [ { name: "A", value: 10 }, { name: "B", children: [ { name: "B1", value: 5 }, { name: "B2", value: 7 } ]} ] }; series.data.setAll([data]); series.set("selectedDataItem", series.dataItems[0]); ``` --- ## Flow Charts (Sankey, Chord, Arc) ```js import * as am5flow from "@amcharts/amcharts5/flow"; // Sankey var series = root.container.children.push( am5flow.Sankey.new(root, { sourceIdField: "from", targetIdField: "to", valueField: "value", orientation: "horizontal", // or "vertical" nodeAlign: "justify" }) ); series.data.setAll([ { from: "A", to: "B", value: 10 }, { from: "A", to: "C", value: 5 }, { from: "B", to: "D", value: 8 } ]); // Chord diagram var series = root.container.children.push( am5flow.ChordDirected.new(root, { // or ChordNonRibbon sourceIdField: "from", targetIdField: "to", valueField: "value", padAngle: 0.02 }) ); // Arc diagram var series = root.container.children.push( am5flow.ArcDiagram.new(root, { sourceIdField: "from", targetIdField: "to", valueField: "value", orientation: "horizontal" }) ); ``` --- ## Stock Chart ```js import * as am5stock from "@amcharts/amcharts5/stock"; var stockChart = root.container.children.push( am5stock.StockChart.new(root, {}) ); var mainPanel = stockChart.panels.push( am5stock.StockPanel.new(root, { wheelY: "zoomX", panX: true, panY: true }) ); var valueAxis = mainPanel.yAxes.push( am5xy.ValueAxis.new(root, { renderer: am5xy.AxisRendererY.new(root, { pan: "zoom" }), tooltip: am5.Tooltip.new(root, {}), numberFormat: "#,###.00", extraTooltipPrecision: 2 }) ); var dateAxis = mainPanel.xAxes.push( am5xy.GaplessDateAxis.new(root, { baseInterval: { timeUnit: "day", count: 1 }, renderer: am5xy.AxisRendererX.new(root, {}), tooltip: am5.Tooltip.new(root, {}) }) ); var candlestickSeries = mainPanel.series.push( am5xy.CandlestickSeries.new(root, { name: "TICKER", clustered: false, valueXField: "Date", valueYField: "Close", highValueYField: "High", lowValueYField: "Low", openValueYField: "Open", calculateAggregates: true, xAxis: dateAxis, yAxis: valueAxis, legendValueText: "open: [bold]{openValueY}[/] high: [bold]{highValueY}[/] low: [bold]{lowValueY}[/] close: [bold]{valueY}[/]" }) ); stockChart.set("stockSeries", candlestickSeries); // Toolbar var toolbar = am5stock.StockToolbar.new(root, { container: document.getElementById("chartcontrols"), stockChart: stockChart, controls: [ am5stock.DateRangeSelector.new(root, { stockChart: stockChart }), am5stock.PeriodSelector.new(root, { stockChart: stockChart }), am5stock.DrawingControl.new(root, { stockChart: stockChart }), am5stock.IndicatorControl.new(root, { stockChart: stockChart }), am5stock.SeriesTypeControl.new(root, { stockChart: stockChart }), am5stock.ResetControl.new(root, { stockChart: stockChart }), am5stock.SettingsControl.new(root, { stockChart: stockChart }) ] }); ``` --- ## Word Cloud ```js import * as am5wc from "@amcharts/amcharts5/wc"; var series = root.container.children.push( am5wc.WordCloud.new(root, { maxCount: 100, minWordLength: 2, maxFontSize: am5.percent(15), text: "your long text here..." // or use data }) ); // With data series.data.setAll([ { tag: "JavaScript", weight: 20 }, { tag: "TypeScript", weight: 15 } ]); series.fields.tag = "tag"; series.fields.weight = "weight"; ``` --- ## Gantt Chart Gantt charts use XY chart with a date axis on X and category axis on Y, with column series. ```js var chart = root.container.children.push( am5xy.XYChart.new(root, { panX: false, panY: false, wheelX: "panX" }) ); var yAxis = chart.yAxes.push( am5xy.CategoryAxis.new(root, { categoryField: "category", renderer: am5xy.AxisRendererY.new(root, { inversed: true, cellStartLocation: 0.1, cellEndLocation: 0.9 }) }) ); var xAxis = chart.xAxes.push( am5xy.DateAxis.new(root, { baseInterval: { timeUnit: "minute", count: 1 }, renderer: am5xy.AxisRendererX.new(root, {}) }) ); var series = chart.series.push( am5xy.ColumnSeries.new(root, { xAxis: xAxis, yAxis: yAxis, openValueXField: "start", valueXField: "end", categoryYField: "category", sequencedInterpolation: true }) ); series.columns.template.setAll({ templateField: "columnSettings" }); var data = [ { category: "Task 1", start: new Date(2024, 0, 1).getTime(), end: new Date(2024, 0, 5).getTime(), columnSettings: { fill: am5.color(0x6794dc) } } ]; yAxis.data.setAll(data); series.data.setAll(data); ``` --- ## Venn Diagram ```js import * as am5venn from "@amcharts/amcharts5/venn"; var series = root.container.children.push( am5venn.Venn.new(root, { categoryField: "name", valueField: "value", intersectionsField: "sets", tooltip: am5.Tooltip.new(root, { labelText: "{category}: {value}" }) }) ); series.data.setAll([ { name: "A", value: 10 }, { name: "B", value: 10 }, { name: "C", value: 10 }, { name: "A&B", sets: ["A", "B"], value: 4 }, { name: "B&C", sets: ["B", "C"], value: 3 } ]); ``` --- ## Themes ```js import am5themes_Animated from "@amcharts/amcharts5/themes/Animated"; import am5themes_Dark from "@amcharts/amcharts5/themes/Dark"; import am5themes_Dataviz from "@amcharts/amcharts5/themes/Dataviz"; import am5themes_Material from "@amcharts/amcharts5/themes/Material"; import am5themes_Kelly from "@amcharts/amcharts5/themes/Kelly"; import am5themes_Micro from "@amcharts/amcharts5/themes/Micro"; root.setThemes([ am5themes_Animated.new(root), am5themes_Dark.new(root) ]); // Custom theme var myTheme = am5.Theme.new(root); myTheme.rule("Label").setAll({ fontSize: 14, fill: am5.color(0xffffff) }); root.setThemes([am5themes_Animated.new(root), myTheme]); ``` --- ## Colors ```js // From hex am5.color(0xff0000) am5.color("#ff0000") // ColorSet (automatic color cycling) var colorSet = am5.ColorSet.new(root, { colors: [am5.color(0xff0000), am5.color(0x00ff00)] }); // Gradient fill series.fills.template.set("fillGradient", am5.LinearGradient.new(root, { stops: [{ color: am5.color(0x000000) }, { color: am5.color(0xffffff) }] })); ``` --- ## Exporting ```js import * as am5plugins_exporting from "@amcharts/amcharts5/plugins/exporting"; var exporting = am5plugins_exporting.Exporting.new(root, { menu: am5plugins_exporting.ExportingMenu.new(root, {}), dataSource: data, filePrefix: "myChart" }); // Programmatic export exporting.export("png"); exporting.export("csv"); exporting.export("pdf"); ``` --- ## React Integration Pattern ```jsx import { useLayoutEffect, useRef } from "react"; import * as am5 from "@amcharts/amcharts5"; import * as am5xy from "@amcharts/amcharts5/xy"; import am5themes_Animated from "@amcharts/amcharts5/themes/Animated"; function Chart() { const chartRef = useRef(null); useLayoutEffect(() => { var root = am5.Root.new(chartRef.current); root.setThemes([am5themes_Animated.new(root)]); var chart = root.container.children.push( am5xy.XYChart.new(root, {}) ); // ... chart setup ... return () => { root.dispose(); // Always dispose on unmount }; }, []); return
; } ``` --- ## Common Pitfalls 1. **Never mix v4 and v5 syntax.** v4 uses `am4core`, v5 uses `am5`. Completely different APIs. 2. **Always dispose the root** on component unmount: `root.dispose()`. Failing to do so causes memory leaks. 3. **Use `useLayoutEffect`, not `useEffect`** in React to avoid chart flickering. 4. **Apply themes before creating charts**, not after. 5. **Date axis expects timestamps** (milliseconds since epoch), not Date objects: `new Date(...).getTime()`. 6. **`setAll` on axis data AND series data** for category axes: both `xAxis.data.setAll(data)` and `series.data.setAll(data)`. 7. **Canvas-based, not SVG** — do not try to manipulate the DOM directly. 8. **Colors must use `am5.color()`** wrapper, not raw hex strings, when assigned to fill/stroke settings. 9. **`appear()` should be called last**, after data is set and chart is configured. 10. **Maps need geodata** — import from `@amcharts/amcharts5-geodata` package. --- ## AI Integration Resources - **MCP Server**: `npx -y @amcharts/amcharts5-mcp` — gives AI assistants access to 141 doc pages, 283 examples, 1,098 class references - **Skill files**: https://github.com/amcharts/amcharts5-skill — SKILL.md + per-chart-type references - **AI docs page**: https://www.amcharts.com/docs/v5/ai/ - **MCP setup**: https://www.amcharts.com/docs/v5/ai/mcp/ - **npm package**: `@amcharts/amcharts5-mcp` --- ## Key URLs - Documentation: https://www.amcharts.com/docs/v5/ - Demos: https://www.amcharts.com/demos/ - Class reference: https://www.amcharts.com/docs/v5/reference/tag/class/ - Licensing: https://www.amcharts.com/online-store/ - GitHub (skill): https://github.com/amcharts/amcharts5-skill - GitHub (MCP): https://github.com/amcharts/amcharts5-mcp - npm (MCP): https://www.npmjs.com/package/@amcharts/amcharts5-mcp