javascriptangularjsamchartsworld-map

How to display markers on amCharts world map using angular routing?


I am trying to include a world map chart in my web site. My problem is when the page is loaded in the first time everything is working, but when I am switching between views on the page, world map is loaded without markers, it looks like the map can't be fully loaded in angular routing. What should I do in order to reload it? Thanks in advance.

  <!DOCTYPE html>
  <html lang="en-US">
  <head>
 <title>Online Trading Data</title>
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <link rel="stylesheet" 
  href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
  <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-
  awesome/4.0.0/css/font-awesome.css" />

    <style>[ng:\:cloak],[ng-cloak],.ng-cloak { display:none;}</style>
    <style>
     html,
     body {
     width: 100%;
     height: 100%;
     margin: 0px;
    }

   #chartdiv {
    width: 100%;
    height: 50%;
   }

  #selector {
   position: absolute;
   top: 20px;
   right: 20px;
   background: rgba(255, 255, 255, 0.7);
   padding: 10px;
   font-size: 16px;
 }

 #selector input,
 #selector select {
   padding: 5px;
 }


 .ammapDescriptionTitle {
   font-size: 15px;
  font-weight: bold;
  color:#000;
}
.ammapDescriptionText {
  max-height: 200px;
  overflow: auto;
  border:1px solid;
  background-color:#dedede;
  color:#000;
}
.ammapDescriptionText img, .ammapDescriptionText p {
  max-width: 95%;
}

    </style>
    </head>

    <body>

    <div ng-app="scotchApp">
    <ul class="nav navbar-nav navbar-right">
                        <li><a href="#"><i class="fa fa-home"></i> Home</a></li>
                        <li><a href="#about"><i class="fa fa-shield"></i> About</a></li>
                        <li><a href="#contact"><i class="fa fa-comment"></i> Contact</a></li>
                    </ul>
    <div ng-view></div>


    </div>

    <!-- <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> -->
     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
     <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
    <script src="https://www.amcharts.com/lib/3/ammap.js"></script>
    <script src="https://www.amcharts.com/lib/3/maps/js/worldLow.js"></script>
    <script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
    <script>
     var scotchApp = angular.module('scotchApp', ['ngRoute']);

        // configure our routes
        scotchApp.config(function($routeProvider) {
            $routeProvider

                // route for the home page
                .when('/', {
                    template : '<div id="chartdiv" style="height:500px !important; width:980px!important;">sdsd</div>',
                    controller  : 'mainController'
                })


                .when('/about', {
                    template : '<div>Second page</div>',
                    controller  : 'aboutController'
                })


                .when('/contact', {
                    template : '<div>Third page</div>',
                    controller  : 'contactController'
                });
        });

        scotchApp.controller('mainController', function($scope) {
        var relevantcities = [
        {
          "title": "Berlin",
          "latitude": 52.5235,
          "longitude": 13.4115
        },{
          "title": "Monaco",
          "latitude": 43.7325,
          "longitude": 7.4189
        },{
          "title": "Moscow",
          "latitude": 55.7558,
          "longitude": 37.6176
        },{
          "title": "Madrid",
          "latitude": 40.4167,
          "longitude": -3.7033
        },{
          "title": "London",
          "latitude": 51.5002,
          "longitude": -0.1262
        },{
          "title": "New Delhi",
          "latitude": 28.6353,
          "longitude": 77.2250
        },{
          "title": "Jerusalem",
          "latitude": 31.7857,
          "longitude": 35.2007
        },{
          "title": "Tokyo",
          "latitude": 35.6785,
          "longitude": 139.6823
        },{
          "title": "Bangkok",
          "latitude": 13.7573,
          "longitude": 100.5020
        }, {
          "title": "Abu Dhabi",
          "latitude": 24.4764,
          "longitude": 54.3705
        },{
          "title": "Washington",
          "latitude": 38.8921,
          "longitude": -77.0241,
          "color":"#000"
        }

        ];
            var targetSVG = "M9,0C4.029,0,0,4.029,0,9s4.029,9,9,9s9-4.029,9-9S13.971,0,9,0z M9,15.93 c-3.83,0-6.93-3.1-6.93-6.93S5.17,2.07,9,2.07s6.93,3.1,6.93,6.93S12.83,15.93,9,15.93 M12.5,9c0,1.933-1.567,3.5-3.5,3.5S5.5,10.933,5.5,9S7.067,5.5,9,5.5 S12.5,7.067,12.5,9z";

            var map = AmCharts.makeChart( "chartdiv", {
              "type": "map",
              "theme": "light",

              "imagesSettings": {
                "rollOverColor": "#000",
                "rollOverScale": 1,
                "selectedScale": 1,
                "selectedColor": "red",
                "color": "#13564e"
              },

              "areasSettings": {
                "unlistedAreasColor": "#000"
              },

              "dataProvider": {
                "map": "worldLow",
                "images": []
              }
            } );

            // populate the city dropdown when the page loads
            AmCharts.ready( function() {
            relevantcities.forEach( function (arrayItem)
            {
                    var city = arrayItem;
                    city.svgPath = targetSVG;
                    city.zoomLevel = 3;
                    city.scale = 1.2;
                    city.label = city.title + " +25%";
                    city.color = "green";
                    //city.description ="<img src='http://upload.wikimedia.org/wikipedia/commons/9/97/Palace_of_Westminster%2C_London_-_Feb_2007.jpg' /><p>London is the capital and most populous city of England and the United Kingdom. Standing on the River Thames, London has been a major settlement for two millennia, its history going back to its founding by the Romans, who named it Londinium. London's ancient core, the City of London, largely retains its 1.12-square-mile (2.9 km2) medieval boundaries and in 2011 had a resident population of 7,375, making it the smallest city in England. Since at least the 19th century, the term London has also referred to the metropolis developed around this core The bulk of this conurbation forms the Greater London administrative area (coterminous with the London region), governed by the Mayor of London and the London Assembly.</p>";

                  // add city object to map
                  map.dataProvider.images.push( city );
                  map.validateData();
            });

            } );


        });

        scotchApp.controller('aboutController', function($scope) {
            $scope.message = 'Look! I am an about page.';
        });

        scotchApp.controller('contactController', function($scope) {
            $scope.message = 'Contact us! JK. This is just a demo.';
        });

    </script>
    </body>
    </html>

Solution

  • AmCharts.ready is the equivalent of window.onload, so it's useless in this scenario as your code will only run once. Getting rid of that ready call and having your forEach code run on its own will make it work. You also don't want to call validateData after each image is added as it will slow down the process - just call it once after your forEach is done.

    I'm not really sure why you have your forEach code running after makeChart when you can just create the images upfront and assign it to the images array in the makeChart call itself. If you must have the image setup code run only when the map is initialized, put it in the map's init event:

      var map = AmCharts.makeChart("chartdiv", {
        // ..
        listeners: [
          {
            event: "init",
            method: function(e) {
              var map = e.chart;
              // populate the city dropdown when the page loads
              relevantcities.forEach(function(arrayItem) {
                var city = arrayItem;
                city.svgPath = targetSVG;
                city.zoomLevel = 3;
                city.scale = 1.2;
                city.label = city.title + " +25%";
                city.color = "green";
    
                // add city object to map
                map.dataProvider.images.push(city);
              });
              map.validateData();
            }
          }
        ]
      });