Anonymous
Динамическая государственная раскраска в Индии карта с использованием Amcharts 5
Сообщение
Anonymous » 15 июл 2025, 12:26
Я строю интерактивную индийскую карту с использованием Amcharts 5, где каждое состояние должно быть динамически окрашено в зависимости от процента взносов покупки. Данные вклада поступают из бэкэнда, и я назначаю цвета из предопределенной палитры в соответствии с рейтингом каждого состояния. не отражать эти цвета. Вместо этого все состояния появляются в одном и том же оттенке по умолчанию (обычно серый), независимо от их значений заполнения в данных. Тем не менее, он, похоже, не применяет заполнение к полигонам, как и ожидалось. Mappolygonseries config. Я ожидал, что каждый полигон штата будет заполнен соответствующим цветом, соответствующим легенде. Я также пытался использовать шаблон: «заполнить» в шаблоне многоугольника, но это не изменило результат. [Я хочу, чтобы легенда и карта были такого же цвета < /p>
Код: Выделить всё
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);
}
});
^(
https://i.sstatic.net/65d6sfnb.png )
Подробнее здесь:
https://stackoverflow.com/questions/797 ... amcharts-5
1752571580
Anonymous
Я строю интерактивную индийскую карту с использованием Amcharts 5, где каждое состояние должно быть динамически окрашено в зависимости от процента взносов покупки. Данные вклада поступают из бэкэнда, и я назначаю цвета из предопределенной палитры в соответствии с рейтингом каждого состояния. не отражать эти цвета. Вместо этого все состояния появляются в одном и том же оттенке по умолчанию (обычно серый), независимо от их значений заполнения в данных. Тем не менее, он, похоже, не применяет заполнение к полигонам, как и ожидалось. Mappolygonseries config. Я ожидал, что каждый полигон штата будет заполнен соответствующим цветом, соответствующим легенде. Я также пытался использовать шаблон: «заполнить» в шаблоне многоугольника, но это не изменило результат. [Я хочу, чтобы легенда и карта были такого же цвета < /p> [code] 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); } }); [/code] ^(https://i.sstatic.net/65d6sfnb.png) Подробнее здесь: [url]https://stackoverflow.com/questions/79701830/dynamic-state-wise-coloring-in-india-map-using-amcharts-5[/url]