0
    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;

Here i am using amcharts with reactjs.

I am displaying data whatever data coming from api.

I am not changing all data. I am only changing the color index from api data in the map for "us", "uk", "india" regions

So in customComponentDidMount() i am calling getGeography() function and storing colors in localStorage as per the country.

But, the problem is this.getGeography() function is getting called later so my map is not getting data from localStorage.

And it is throwing error.

How to call getGeography() at first then to do rest of the stuffs.

Api response i am getting.

    {
    "us":10,
    "uk":23,
    "india":33
    }

Any way without using localStorage is also helpful.

Please have a look

1 Answer 1

1

Because you are fetching data from API so this function is asynchronous. An easy solution is to pass a callback parameter in getGeography(), so it becomes:

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();
        }
      })
    }

so in your componentDidMount, you can pass your following functions into this callback:

 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;
    })
}

Another option is to use async/await. So you can set

 async getGeography(cb = null){}

as async function and then call

await this.getGeography() 

in componentDidMount so the code below won't run until the promise is fulfilled.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.