I'm building an interactive India map using amCharts 5, where each state should be dynamically colored based on its purchase contribution percentage. The contribution data is coming from the backend, and I’m assigning colors from a predefined palette according to each state’s ranking.
I’m successfully generating a mapData array where each object includes a fill color (using am5.color(0xRRGGBB)) along with the state name and its contribution.
While the legend correctly shows the dynamic colors, the actual map polygons do not reflect these colors. Instead, all states appear in the same default shade (usually grey), regardless of their fill values in the data.
I’m using fillField: "fill" in my MapPolygonSeries configuration, which (according to the docs) should tell amCharts to use the fill field from the data object. However, it doesn't seem to apply the fill to the polygons as expected.
I’ve also tried using templateField: "fill" inside the polygon template configuration, but that didn’t fix the issue either.I want that state present in map also need to be the same color of the legend
I assigned a fill color to each state in mapData and set fillField: "fill" in the MapPolygonSeries config. I expected each state polygon to be filled with its corresponding color, matching the legend.
However, all states appeared in the same default color (gray), even though the legend showed the correct dynamic colors. I also tried using templateField: "fill" in the polygon template, but that didn't change the outcome.[I want that the legend and map should be of same color
<script src="https://cdn.amcharts.com/lib/5/map.js"></script> <script src="https://cdn.amcharts.com/lib/5/geodata/indiaLow.js"></script> <script> const statePurchasesData = {{{ json state_purchases_contribution }}}; am5.ready(function () { try { console.log("[am5] Raw data:", statePurchasesData); const root = am5.Root.new("india-purchases-map"); root.container.set("layout", root.horizontalLayout); root.setThemes([am5themes_Animated.new(root)]); // Map chart container const chart = root.container.children.push(am5map.MapChart.new(root, { panX: false, panY: false, wheelX: "none", wheelY: "none", projection: am5map.geoMercator() })); console.log("[am5] MapChart initialized."); // ID mapping const idMap = {}; am5geodata_indiaLow.features.forEach(feature => { const name = feature.properties.name.trim(); const id = feature.id; if (name && id) { idMap[name] = id; } }); // Convert data const data = (statePurchasesData || []).map(item => { const state = (item.state || "").replace(/ - $/, "").trim(); const id = idMap[state]; if (!id) console.warn("[am5] State not mapped to ID:", state); return { id, name: state, purchases_contribution: item.purchases_contribution }; }).filter(d => d.id); const colorPalette = [ 0x004d40, 0x00796b, 0x009688, 0x26a69a, 0x4db6ac, 0x80cbc4, 0xb2dfdb, 0xdcedc8, 0xf0f4c3, 0xe0e0e0 ]; data.forEach((item, index) => { item.polygonSettings = { fill: am5.color(colorPalette[index] || 0xe0e0e0) }; }); // Polygon series const polygonSeries = chart.series.push(am5map.MapPolygonSeries.new(root, { geoJSON: am5geodata_indiaLow, valueField: "purchases_contribution", nameField: "name", calculateAggregates: true })); polygonSeries.data.setAll(data); console.log("[am5] Polygon series data set."); polygonSeries.set("heatRules", [{ target: polygonSeries.mapPolygons.template, dataField: "purchases_contribution", min: am5.color(0x000000), max: am5.color(0xFFFFFF), key: "fill" }]); polygonSeries.mapPolygons.template.setAll({ tooltipText: "{name}: {purchases_contribution}%", interactive: true }); polygonSeries.mapPolygons.template.adapters.add("fill", (fill, target) => { const dataItem = target.dataItem; return dataItem && dataItem.dataContext.purchases_contribution != null ? fill : am5.color(0xe0e0e0); }); // Legend const legend = root.container.children.push(am5.Legend.new(root, { nameField: "name", fillField: "fill", strokeField: "fill", layout: root.verticalLayout, y: am5.percent(50), centerY: am5.percent(50), marginRight: 80, width: 150 })); polygonSeries.events.on("datavalidated", function () { console.log("[am5] Data validated. Populating legend."); const legendData = polygonSeries.dataItems .filter(dataItem => dataItem.get("value") !== undefined) // Only include those with data .map(dataItem => { const polygon = dataItem.get("mapPolygon"); const dataContext = polygon.dataItem.dataContext; return { name: `${ dataContext.name } - ${ dataContext.purchases_contribution }%`, fill: polygon.get("fill") || am5.color(0x999999) }; }); console.log("[am5] Filtered legend data:", legendData); legend.data.setAll(legendData); }); } catch (err) { console.error("[am5] Error rendering map:", err); } }); </script>