import React from 'react'
import FormatUrl from 'utils/UrlFormatter'
import * as am4core from "@amcharts/amcharts4/core";
import * as am4maps from "@amcharts/amcharts4/maps";
import am4geodata_worldHigh from "@amcharts/amcharts4-geodata/worldHigh";
import am4themes_animated from "@amcharts/amcharts4/themes/animated";
am4core.useTheme(am4themes_animated);
class WorldMap extends React.Component {
constructor(props){
super(props);
this.state = {
bubble:{},
prevEvent: null,
geodata:{}
}
}
getGeography(){
let url = FormatUrl(`/worldmap/`)
fetch(url)
.then(res => res.json())
.then(res => {
localStorage.setItem("india", res['india'])
localStorage.setItem("us", res['us'])
localStorage.setItem("uk", res['uk'])
})
}
customComponentDidMount() {
let chart = am4core.create("worldmap", am4maps.MapChart);
chart.geodata = am4geodata_worldHigh;
chart.projection = new am4maps.projections.Mercator();
chart.exporting.menu = new am4core.ExportMenu();
chart.zoomControl = new am4maps.ZoomControl();
this.getGeography()
let groupData = [
{
"name": "India",
"color": chart.colors.getIndex(localStorage.getItem("india")),
"data": [
{
"title": "India",
"id": "IN",
"customData": localStorage.getItem("india")
}
]
},
{
"name": "Usa",
"color": chart.colors.getIndex(localStorage.getItem("us")),
"data": [
{
"title": "Usa",
"id": "US",
"customData": localStorage.getItem("us")
}
]
},
{
"name": "Uk",
"color" : chart.colors.getIndex(localStorage.getItem("us")),
"data": [
{
"title": "Uk",
"id": "GB",
"customData": localStorage.getItem("uk")
}
]
}
];
let excludedCountries = ["AQ"];
groupData.forEach(function(group) {
let series = chart.series.push(new am4maps.MapPolygonSeries());
series.name = group.name;
series.useGeodata = true;
let includedCountries = [];
group.data.forEach(function(country){
includedCountries.push(country.id);
excludedCountries.push(country.id);
});
series.include = includedCountries;
series.fill = am4core.color(group.color);
series.setStateOnChildren = true;
let seriesHoverState = series.states.create("hover");
let mapPolygonTemplate = series.mapPolygons.template;
mapPolygonTemplate.fill = am4core.color(group.color);
mapPolygonTemplate.fillOpacity = 0.8;
mapPolygonTemplate.nonScalingStroke = true;
mapPolygonTemplate.tooltipText = "{title} Has {customData} AbsM"; // enables tooltip
series.data = JSON.parse(JSON.stringify(group.data));
});
let worldSeries = chart.series.push(new am4maps.MapPolygonSeries());
let worldSeriesName = "world";
worldSeries.name = worldSeriesName;
worldSeries.useGeodata = true;
worldSeries.exclude = excludedCountries;
worldSeries.fillOpacity = 0.8;
worldSeries.hiddenInLegend = true;
worldSeries.mapPolygons.template.nonScalingStroke = true;
}
componentWillUnmount() {
if (this.chart) {
this.chart.dispose();
}
}
render(){
return (
<div>
<div class="card-body">
<div class="chart-area" id="worldmap" style={{ width: "100%", height: '455px' }}>
</div>
</div>
)
}
}
export default WorldMap;
我在这里将 amcharts 与 reactjs 一起使用。
无论来自api的数据是什么,我都会显示数据。
我没有更改所有数据。 我只更改了地图中“我们”,“英国”,“印度” 区域的api数据的颜色索引
因此,在 customComponentDidMount ()中,我正在调用 getGeography ()函数,并根据国家/地区在localStorage中存储颜色。
但是,问题是这样的。 getGeography ()函数稍后被调用,因此我的地图没有从localStorage中获取数据。
它抛出错误。
如何先调用 getGeography (),然后再处理其余内容。
我得到的api响应。
{
"us":10,
"uk":23,
"india":33
}
任何不使用 localStorage 的方式也是有帮助的。
请看看
答案 0 :(得分:1)
因为您正在从API提取数据,所以此函数是异步的。一个简单的解决方案是在getGeography()中传递一个回调参数,因此它变为:
getGeography(cb = null){
let url = FormatUrl(`/worldmap/`)
fetch(url)
.then(res => res.json())
.then(res => {
localStorage.setItem("india", res['india'])
localStorage.setItem("us", res['us'])
localStorage.setItem("uk", res['uk'])
if (cb) {
cb();
}
})
}
因此,在componentDidMount中,您可以将以下函数传递给此回调:
customComponentDidMount() {
let chart = am4core.create("worldmap", am4maps.MapChart);
chart.geodata = am4geodata_worldHigh;
chart.projection = new am4maps.projections.Mercator();
chart.exporting.menu = new am4core.ExportMenu();
chart.zoomControl = new am4maps.ZoomControl();
this.getGeography(() => {
let groupData = [
{
"name": "India",
"color": chart.colors.getIndex(localStorage.getItem("india")),
"data": [
{
"title": "India",
"id": "IN",
"customData": localStorage.getItem("india")
}
]
},
{
"name": "Usa",
"color": chart.colors.getIndex(localStorage.getItem("us")),
"data": [
{
"title": "Usa",
"id": "US",
"customData": localStorage.getItem("us")
}
]
},
{
"name": "Uk",
"color" : chart.colors.getIndex(localStorage.getItem("us")),
"data": [
{
"title": "Uk",
"id": "GB",
"customData": localStorage.getItem("uk")
}
]
}
];
let excludedCountries = ["AQ"];
groupData.forEach(function(group) {
let series = chart.series.push(new am4maps.MapPolygonSeries());
series.name = group.name;
series.useGeodata = true;
let includedCountries = [];
group.data.forEach(function(country){
includedCountries.push(country.id);
excludedCountries.push(country.id);
});
series.include = includedCountries;
series.fill = am4core.color(group.color);
series.setStateOnChildren = true;
let seriesHoverState = series.states.create("hover");
let mapPolygonTemplate = series.mapPolygons.template;
mapPolygonTemplate.fill = am4core.color(group.color);
mapPolygonTemplate.fillOpacity = 0.8;
mapPolygonTemplate.nonScalingStroke = true;
mapPolygonTemplate.tooltipText = "{title} Has {customData} AbsM"; // enables tooltip
series.data = JSON.parse(JSON.stringify(group.data));
});
let worldSeries = chart.series.push(new am4maps.MapPolygonSeries());
let worldSeriesName = "world";
worldSeries.name = worldSeriesName;
worldSeries.useGeodata = true;
worldSeries.exclude = excludedCountries;
worldSeries.fillOpacity = 0.8;
worldSeries.hiddenInLegend = true;
worldSeries.mapPolygons.template.nonScalingStroke = true;
})
}
另一个选择是使用异步/等待。所以你可以设置
async getGeography(cb = null){}
作为异步功能,然后调用
await this.getGeography()
在componentDidMount中,因此下面的代码要等到诺言实现后才能运行。