Highchart World Map In Angular

Charts are one of the most important topics for any kind of small or big application in software.
 
From an administration and management point of view, pictorial representation plays an important role to explain details in a smart way. 
So for that, I decided to explain the world map high-chart in angular.
 
Here in this article, I will try to cover the following,
  1. Setup and installtion
  2. DataBinding
  3. Update data
  4. Legend position change
  5. Show/Hide the legend
  6. Legend Formation
  7. Tooltip
  8. Color coding
  9. Summary

Introduction

 
Highcharts is a pure scripting-based charting library, that is used to enhance web applications. It provides many kinds of charts, for example, line charts, donut charts, bar charts, pie charts etc...
 

Setup and installtion

 
I assume that you have already set up your project, if you didn't set it up yet, you can visit this article.
 
Let's start with highchart setup and installation.
 
First of all, we need to install the required following library.
 
Install the below packages
  1. npm i highcharts  
  2. npm i angular-highcharts  
  3. npm i @highcharts/map-collection  
As we know that we need to select the proper version to get the feature, so do not forget to select the proper version, as I mention here
  1. "@highcharts/map-collection""^1.1.3",  
  2. "highcharts""^8.2.2",  
  3. "highcharts-angular""^2.9.0",  
Then after that in app.module you need to add this module ( HighchartsChartModule) and add the respective reference.
  1. import { HighchartsChartModule } from 'highcharts-angular';  
After finishing the above you have completed step1.
 

DataBinding

 
Here in this section we need to add all the required code to bind the chart and data. First we need to add the references as follows:
  1. import { Component } from '@angular/core';  
  2. import { map } from 'rxjs/operators';  
  3. import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout';  
  4.   
  5. var Highcharts = require("highcharts/highmaps.js");  
  6. import { Options } from "highcharts";  
  7. var worldMap = require("@highcharts/map-collection/custom/world.geo.json");  
Now inside your component the full code is like this:
  1. export class Dashboard1Component {  
  2.     Highcharts: typeof Highcharts = Highcharts;  
  3.     chartConstructor = "mapChart";  
  4.     updateFlag = false;  
  5.     chartData = [{  
  6.         code3: "ABW",  
  7.         z: 105  
  8.     }, {  
  9.         code3: "AFG",  
  10.         z: 35530  
  11.     }];  
  12.   
  13.     chartOptions: Options = {  
  14.         chart: {  
  15.             map: worldMap as any  
  16.         },  
  17.         title: {  
  18.             text: "Angualr Highchart World Map"  
  19.         },  
  20.         subtitle: {  
  21.             text: 'Sub title: <a href="http://code.highcharts.com/mapdata/custom/world.js"> xyzzzz</a>'  
  22.         },  
  23.         exporting: {  
  24.             enabled: true  
  25.         },  
  26.         credits: {  
  27.             enabled: true  
  28.         },  
  29.         mapNavigation: {  
  30.             enabled: true,  
  31.             buttonOptions: {  
  32.                 alignTo: "spacingBox"  
  33.             }  
  34.         },  
  35.         legend: {  
  36.             enabled: true  
  37.         },  
  38.         colorAxis: {  
  39.             dataClasses: [{  
  40.                 to: 25,  
  41.                 color: '#922291'  
  42.             }, {  
  43.                 from: 26,  
  44.                 to: 50,  
  45.                 color: '#c893c7'  
  46.             }, {  
  47.                 from: 51,  
  48.                 to: 75,  
  49.                 color: '#00a2ad'  
  50.             }, {  
  51.                 from: 76,  
  52.                 to: 100,  
  53.                 color: '#7fd0d6'  
  54.             }],  
  55.             type: 'linear',  
  56.         },  
  57.         series: [{  
  58.   
  59.             point: {  
  60.                 events: {  
  61.                     click: (e) => {  
  62.                         this.getDataByCountryKey(e.point['hc-key'])  
  63.                     }  
  64.   
  65.                     // click: this.getDataByCountryKey.bind(this)    
  66.                 }  
  67.             },  
  68.             type: "map",  
  69.             name: "Random Data",  
  70.             states: {  
  71.                 hover: {  
  72.                     color: "#BADA55"  
  73.                 }  
  74.             },  
  75.             dataLabels: {  
  76.                 enabled: true,  
  77.                 format: "{point.name}"  
  78.             },  
  79.             allAreas: false,  
  80.             data: [  
  81.                 ["fo", 0],  
  82.                 ["um", 1],  
  83.                 ["us", 2],  
  84.                 ["jp", 3],  
  85.                 ["sc", 4],  
  86.                 ["in", 5],  
  87.                 ["fr", 6],  
  88.                 ["fm", 7],  
  89.                 ["cn", 8],  
  90.                 ["pt", 9],  
  91.                 ["sw", 10],  
  92.                 ["sh", 11],  
  93.                 ["br", 12],  
  94.                 ["ki", 13],  
  95.                 ["ph", 14],  
  96.                 ["mx", 15],  
  97.                 ["es", 16],  
  98.                 ["bu", 17],  
  99.                 ["mv", 18],  
  100.                 ["sp", 19],  
  101.                 ["gb", 20],  
  102.                 ["gr", 21],  
  103.                 ["as", 22],  
  104.                 ["dk", 23],  
  105.                 ["gl", 24],  
  106.                 ["gu", 25],  
  107.                 ["mp", 26],  
  108.                 ["pr", 27],  
  109.                 ["vi", 28],  
  110.                 ["ca", 29],  
  111.                 ["st", 30],  
  112.                 ["cv", 31],  
  113.                 ["dm", 32],  
  114.                 ["nl", 33],  
  115.                 ["jm", 34],  
  116.                 ["ws", 35],  
  117.                 ["om", 36],  
  118.                 ["vc", 37],  
  119.                 ["tr", 38],  
  120.                 ["bd", 39],  
  121.                 ["lc", 40],  
  122.                 ["nr", 41],  
  123.                 ["no", 42],  
  124.                 ["kn", 43],  
  125.                 ["bh", 44],  
  126.                 ["to", 45],  
  127.                 ["fi", 46],  
  128.                 ["id", 47],  
  129.                 ["mu", 48],  
  130.                 ["se", 49],  
  131.                 ["tt", 50],  
  132.                 ["my", 51],  
  133.                 ["pa", 52],  
  134.                 ["pw", 53],  
  135.                 ["tv", 54],  
  136.                 ["mh", 55],  
  137.                 ["cl", 56],  
  138.                 ["th", 57],  
  139.                 ["gd", 58],  
  140.                 ["ee", 59],  
  141.                 ["ag", 60],  
  142.                 ["tw", 61],  
  143.                 ["bb", 62],  
  144.                 ["it", 63],  
  145.                 ["mt", 64],  
  146.                 ["vu", 65],  
  147.                 ["sg", 66],  
  148.                 ["cy", 67],  
  149.                 ["lk", 68],  
  150.                 ["km", 69],  
  151.                 ["fj", 70],  
  152.                 ["ru", 71],  
  153.                 ["va", 72],  
  154.                 ["sm", 73],  
  155.                 ["kz", 74],  
  156.                 ["az", 75],  
  157.                 ["tj", 76],  
  158.                 ["ls", 77],  
  159.                 ["uz", 78],  
  160.                 ["ma", 79],  
  161.                 ["co", 80],  
  162.                 ["tl", 81],  
  163.                 ["tz", 82],  
  164.                 ["ar", 83],  
  165.                 ["sa", 84],  
  166.                 ["pk", 85],  
  167.                 ["ye", 86],  
  168.                 ["ae", 87],  
  169.                 ["ke", 88],  
  170.                 ["pe", 89],  
  171.                 ["do", 90],  
  172.                 ["ht", 91],  
  173.                 ["pg", 92],  
  174.                 ["ao", 93],  
  175.                 ["kh", 94],  
  176.                 ["vn", 95],  
  177.                 ["mz", 96],  
  178.                 ["cr", 97],  
  179.                 ["bj", 98],  
  180.                 ["ng", 99],  
  181.                 ["ir", 100],  
  182.                 ["sv", 101],  
  183.                 ["sl", 102],  
  184.                 ["gw", 103],  
  185.                 ["hr", 104],  
  186.                 ["bz", 105],  
  187.                 ["za", 106],  
  188.                 ["cf", 107],  
  189.                 ["sd", 108],  
  190.                 ["cd", 109],  
  191.                 ["kw", 110],  
  192.                 ["de", 111],  
  193.                 ["be", 112],  
  194.                 ["ie", 113],  
  195.                 ["kp", 114],  
  196.                 ["kr", 115],  
  197.                 ["gy", 116],  
  198.                 ["hn", 117],  
  199.                 ["mm", 118],  
  200.                 ["ga", 119],  
  201.                 ["gq", 120],  
  202.                 ["ni", 121],  
  203.                 ["lv", 122],  
  204.                 ["ug", 123],  
  205.                 ["mw", 124],  
  206.                 ["am", 125],  
  207.                 ["sx", 126],  
  208.                 ["tm", 127],  
  209.                 ["zm", 128],  
  210.                 ["nc", 129],  
  211.                 ["mr", 130],  
  212.                 ["dz", 131],  
  213.                 ["lt", 132],  
  214.                 ["et", 133],  
  215.                 ["er", 134],  
  216.                 ["gh", 135],  
  217.                 ["si", 136],  
  218.                 ["gt", 137],  
  219.                 ["ba", 138],  
  220.                 ["jo", 139],  
  221.                 ["sy", 140],  
  222.                 ["mc", 141],  
  223.                 ["al", 142],  
  224.                 ["uy", 143],  
  225.                 ["cnm", 144],  
  226.                 ["mn", 145],  
  227.                 ["rw", 146],  
  228.                 ["so", 147],  
  229.                 ["bo", 148],  
  230.                 ["cm", 149],  
  231.                 ["cg", 150],  
  232.                 ["eh", 151],  
  233.                 ["rs", 152],  
  234.                 ["me", 153],  
  235.                 ["tg", 154],  
  236.                 ["la", 155],  
  237.                 ["af", 156],  
  238.                 ["ua", 157],  
  239.                 ["sk", 158],  
  240.                 ["jk", 159],  
  241.                 ["bg", 160],  
  242.                 ["qa", 161],  
  243.                 ["li", 162],  
  244.                 ["at", 163],  
  245.                 ["sz", 164],  
  246.                 ["hu", 165],  
  247.                 ["ro", 166],  
  248.                 ["ne", 167],  
  249.                 ["lu", 168],  
  250.                 ["ad", 169],  
  251.                 ["ci", 170],  
  252.                 ["lr", 171],  
  253.                 ["bn", 172],  
  254.                 ["iq", 173],  
  255.                 ["ge", 174],  
  256.                 ["gm", 175],  
  257.                 ["ch", 176],  
  258.                 ["td", 177],  
  259.                 ["kv", 178],  
  260.                 ["lb", 179],  
  261.                 ["dj", 180],  
  262.                 ["bi", 181],  
  263.                 ["sr", 182],  
  264.                 ["il", 183],  
  265.                 ["ml", 184],  
  266.                 ["sn", 185],  
  267.                 ["gn", 186],  
  268.                 ["zw", 187],  
  269.                 ["pl", 188],  
  270.                 ["mk", 189],  
  271.                 ["py", 190],  
  272.                 ["by", 191],  
  273.                 ["cz", 192],  
  274.                 ["bf", 193],  
  275.                 ["na", 194],  
  276.                 ["ly", 195],  
  277.                 ["tn", 196],  
  278.                 ["bt", 197],  
  279.                 ["md", 198],  
  280.                 ["ss", 199],  
  281.                 ["bw", 200],  
  282.                 ["bs", 201],  
  283.                 ["nz", 202],  
  284.                 ["cu", 203],  
  285.                 ["ec", 204],  
  286.                 ["au", 205],  
  287.                 ["ve", 206],  
  288.                 ["sb", 207],  
  289.                 ["mg", 208],  
  290.                 ["is", 209],  
  291.                 ["eg", 210],  
  292.                 ["kg", 211],  
  293.                 ["np", 212]  
  294.             ]  
  295.         }]  
  296.   
  297.     };  
  298.   
  299.     onClick() {  
  300.         let newData1 = ["eg", 555];  
  301.         let newData2 = ["kg", 555];  
  302.         let newData3 = ["ru", 555];  
  303.   
  304.         console.log(...(this.chartOptions.series[0] as any).data);  
  305.         this.chartOptions = {  
  306.             // title: {    
  307.             // text: "updated"    
  308.             // },    
  309.             series: [{  
  310.                 type: "map",  
  311.                 data: [  
  312.                     ...(this.chartOptions.series[0] as any).data,  
  313.   
  314.                     // ["eg", 555],    
  315.                     // ["kg", 555],    
  316.                     // ["np", 555]    
  317.                     newData1,  
  318.                     newData2,  
  319.                     newData3  
  320.                 ]  
  321.             }]  
  322.         };  
  323.   
  324.         this.updateFlag = true;  
  325.     }  
  326.   
  327.     getDataByCountryKey(ckey: any) {  
  328.         console.log('CountryKey:' + ckey);  
  329.     }  
  330. }  
This is all about component code.
 
Here this is very small code for HTML
  1. <button (click)="onClick()">Update data</button>  
  2. <highcharts-chart id="container"  
  3.    [Highcharts]="Highcharts"  
  4.    [constructorType]="chartConstructor"  
  5.    [options]="chartOptions"  
  6.    [(update)]="updateFlag"  
  7.    style="width: 100%; height: 100%;">  
  8. </highcharts-chart>  
Now you have completed your code part, if you run the application you will get the result like this below.
 
Please refer to the image.
 

Update data

 
As you know that only static data can't meet the business requirement, so for that I have created one button; i.e. Update Data and I use method onClick()
  1. <button (click)="onClick()">Update data</button>  
which is implemented in .ts file for updating data dynamically.
  1. onClick() {  
  2.     let newData1 = ["eg", 555];  
  3.     let newData2 = ["kg", 555];  
  4.     let newData3 = ["ru", 555];  
  5.   
  6.     console.log(...(this.chartOptions.series[0] as any).data);  
  7.     this.chartOptions = {  
  8.         // title: {    
  9.         // text: "updated"    
  10.         // },    
  11.         series: [{  
  12.             type: "map",  
  13.             data: [  
  14.                 ...(this.chartOptions.series[0] as any).data,  
  15.   
  16.                 // ["eg", 555],    
  17.                 // ["kg", 555],    
  18.                 // ["np", 555]    
  19.                 newData1,  
  20.                 newData2,  
  21.                 newData3  
  22.             ]  
  23.         }]  
  24.     };  
  25.   
  26.     this.updateFlag = true;  
  27. }  
 

Legend position change

 
A legend is just a kind box for the data representation that can contain a symbol and name for each series item which is in the chart. In the above code we have only default legend code i.e.
  1. legend: {  
  2.    enabled: true  
  3. },  
so this will show legend in horizontal direction, so when we want to show in vertical direction then use the below code
  1. legend: {  
  2.     enabled: true,  
  3.     layout: 'vertical',  
  4.     align: 'left',  
  5.     verticalAlign: 'middle',  
  6.     itemMarginTop: 10,  
  7.     itemMarginBottom: 10  
  8. },  
 

Show/Hide the Legend

 
As you have seen in the above code we have used enabled: true in the legend section, if we don't want to show the legend, then just make it false.
 

Legend Formatting

 
For legend formating you need to add a labelFormatter with the function, inside this you can write your cusrtom code like below.
  1. legend: {  
  2.    layout: 'vertical',  
  3.    labelFormatter: function () {  
  4.    return this.name + ' abccc';  
  5. }  

Tooltip

 
The tooltip is the options that appears when the user hovers on a series or data point.
  1. tooltip: {  
  2.     formatter: function() {  
  3.         console.log(this.point);  
  4.         return '<b>' + this.point.name + '</b>';  
  5.     },  
  6.     enabled: true  
  7. }  

Color coding

 
Color coding is used to show the different colors based on data range as you can see in the code color axis I have defined the data range.
  1. colorAxis: {  
  2.     dataClasses: [{  
  3.         to: 25,  
  4.         color: '#922291'  
  5.     }, {  
  6.         from: 26,  
  7.         to: 50,  
  8.         color: '#c893c7'  
  9.     }, {  
  10.         from: 51,  
  11.         to: 75,  
  12.         color: '#00a2ad'  
  13.     }, {  
  14.         from: 76,  
  15.         to: 100,  
  16.         color: '#7fd0d6'  
  17.     }],  
  18.     type: 'linear',  
  19. },  
Get data on country click.
 
The method that I use in series inside point:
  1. point: {  
  2.         events: {  
  3.             click: (e) => {  
  4.                 this.getDataByCountryKey(e.point['hc-key'])  
  5.             }  
  6.             // click: this.getDataByCountryKey.bind(this)  
  7.         }  
  8.         will  
  9.         return the key of clicked country,  
  10.         and below in component i have defined this method getDataByCountryKey  
  11.         getDataByCountryKey(ckey: any) {  
  12.             console.log('CountryKey:' + ckey);  
  13.         }  
So based on this key you can get the real data.
 

Summary

 
Now our application is completed. so you can run it again using the command line 'ng serve'.
 
Here you have learned how to create a world map high chart, played with legend and dynamic data binding, and finally got data based on country click.
 
I hope this project will help you to understand better how to build an Angular application and how to integrate the Highcharts library
 
Kindly let me know if you face any issue, I will try my best to resolve as much as possible.
 
I hope you liked this tutorial; please share it with others.
 
Thank you for taking your valuable time to read the full article.