{"id":12578,"date":"2021-04-20T11:10:04","date_gmt":"2021-04-20T11:10:04","guid":{"rendered":"https:\/\/www.anychart.com\/blog\/?p=12578"},"modified":"2022-08-13T11:04:54","modified_gmt":"2022-08-13T11:04:54","slug":"js-dot-density-map","status":"publish","type":"post","link":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/","title":{"rendered":"Making JS Dot Density Map to Visualize Shipping Ports Across Globe"},"content":{"rendered":"<p><a href=\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/\"><img decoding=\"async\" class=\"alignnone size-full wp-image-12597\" src=\"https:\/\/www.anychart.com\/blog\/wp-content\/uploads\/2021\/04\/javascript-dot-density-map-shipping-ports-data.png\" alt=\"An interactive JavaScript Dot Density Map data visualization showing the distribution of shipping ports across the globe\" width=\"100%\" \/><\/a>The recent incident of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/2021_Suez_Canal_obstruction\" target=\"_blank\" rel=\"nofollow\">Suez Canal blockage<\/a> caught my interest in shipping and prompted me to explore the various shipping ports around the globe. There are more than 850 ports in the world and to get an overall view of where these are located, I decided to\u00a0plot them on\u00a0a <a href=\"https:\/\/www.anychart.com\/chartopedia\/chart-type\/dot-map\/\">dot map<\/a>, or dot density map, using\u00a0JavaScript.<\/p>\n<p>Building an interactive JS dot density map\u00a0can seem like a daunting task. But let me assure you that it\u00a0can be pretty straightforward. Right now, I will show\u00a0how to make a fully functional dot map chart using a JavaScript library for data visualization.<\/p>\n<p><!--more Read the JS charting tutorial \u00bb--><\/p>\n<h2>JavaScript Charting Libraries<\/h2>\n<p>There are some great <a href=\"https:\/\/en.wikipedia.org\/wiki\/Comparison_of_JavaScript_charting_libraries\" target=\"_blank\" rel=\"nofollow\">JavaScript charting libraries<\/a> available to use with each one of them having its advantages and disadvantages. The good part with using JS libraries is that the logic of the chart creation process with all of them is quite similar. So, you can learn the basics with one and then extrapolate your learnings to use the library that suits your project&#8217;s requirements.<\/p>\n<p>For this tutorial, I have decided to use <a href=\"https:\/\/www.anychart.com\/\">AnyChart JS Charts<\/a>\u00a0library\u00a0to create the dot density map. I think it is a great choice for beginners because AnyChart is easy to use yet flexible with <a href=\"https:\/\/docs.anychart.com\/\" target=\"_blank\" rel=\"nofollow\">extensive documentation<\/a> and loads of <a href=\"https:\/\/www.anychart.com\/products\/anychart\/gallery\/\">examples<\/a>.<\/p>\n<h2>Building Dot Density Map with JavaScript<\/h2>\n<p>Whether it&#8217;s a dot density map or any other map or chart,\u00a0when it comes to JavaScript charting there are four basic steps that are generally needed to make a data visualization of almost any type:<\/p>\n<ol>\n<li>Create the HTML page where the chart will be displayed.<\/li>\n<li>Include all necessary JavaScript files.<\/li>\n<li>Prepare the data you want to visualize.<\/li>\n<li>Write the JS code for the chart.<\/li>\n<\/ol>\n<h3>1. Create a basic HTML page<\/h3>\n<p>The first step is to create a blank HTML page to hold the dot map chart. I add a div element with a unique id that I will use to reference it later.<\/p>\n<p>Note that you can specify the width and height parameters inside the <code>&lt;style&gt;<\/code> block to modify the space that your\u00a0visualization\u00a0will occupy. I have put 100% in both parameters so\u00a0my dot density map will fill the whole page.<\/p>\n<pre><code>&lt;html&gt;\r\n\u00a0\u00a0&lt;head&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;title&gt;JavaScript Dot Map&lt;\/title&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;style type=\"text\/css\"&gt;      \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0html, body, #container { \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  width: 100%;\r\n        height: 100%;\r\n        margin: 0;\r\n        padding: 0; \r\n\u00a0\u00a0\u00a0\u00a0  } \r\n\u00a0\u00a0\u00a0\u00a0&lt;\/style&gt;\r\n\u00a0\u00a0&lt;\/head&gt;\r\n\u00a0\u00a0&lt;body&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;div id=\"container\"&gt;&lt;\/div&gt;\r\n\u00a0\u00a0&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/code><\/pre>\n<h3>2. Include the required scripts<\/h3>\n<p>The next step is to link the appropriate JS scripts that will be used to create the dot map. Since I am using the AnyChart library, I will reference the corresponding files. For my map, I need to add AnyChart\u2019s\u00a0Core and Geo Maps <a href=\"https:\/\/docs.anychart.com\/Quick_Start\/Modules\" target=\"_blank\" rel=\"nofollow\">modules<\/a>. I also need to include the file that has the geodata for the world map which is also available in the library\u2019s <a href=\"https:\/\/cdn.anychart.com\" target=\"_blank\" rel=\"nofollow\">CDN<\/a>.<\/p>\n<p>All these script files need to be included in the <code>&lt;head&gt;<\/code> section of the HTML page.<\/p>\n<pre><code>&lt;html&gt;\r\n\u00a0\u00a0&lt;head&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;title&gt;JavaScript Dot Map&lt;\/title&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-core.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-map.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/geodata\/latest\/custom\/world\/world.js\"&gt;&lt;\/script&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;style type=\"text\/css\"&gt;      \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0html, body, #container { \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  width: 100%;\r\n        height: 100%;\r\n        margin: 0;\r\n        padding: 0; \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \r\n\u00a0\u00a0\u00a0\u00a0&lt;\/style&gt;\r\n\u00a0\u00a0&lt;\/head&gt;\r\n\u00a0\u00a0&lt;body&gt;  \r\n\u00a0\u00a0\u00a0\u00a0&lt;div id=\"container\"&gt;&lt;\/div&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ All the code for the JS dot density map will come here.\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/script&gt;\r\n\u00a0\u00a0&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/code><\/pre>\n<h3>3. Connect the data<\/h3>\n<p>I downloaded the shipping port data from <a href=\"https:\/\/datacatalog.worldbank.org\/dataset\/global-international-ports\" target=\"_blank\" rel=\"nofollow\">The World Bank Data Catalog<\/a>.<\/p>\n<p>The AnyChart library supports many <a href=\"https:\/\/docs.anychart.com\/Working_with_Data\/Supported_Data_Formats\" target=\"_blank\" rel=\"nofollow\">data formats<\/a>, including CSV, JSON, and XML. My file is JSON which you can download <a href=\"https:\/\/gist.github.com\/shacheeswadia\/47b28a4d061e415555f01f5ce48e9ae3\" target=\"_blank\" rel=\"nofollow\">here<\/a>.<\/p>\n<p>Before we start using the data, I include\u00a0two more script files on the HTML page. To handle the loading of the data file, I add the <a href=\"https:\/\/docs.anychart.com\/Working_with_Data\/Data_Adapter\/Overview\" target=\"_blank\" rel=\"nofollow\">Data Adapter<\/a>\u00a0module. Since I am creating a map, I will make use of another JavaScript library\u00a0\u2014 <a href=\"http:\/\/proj4js.org\/\" target=\"_blank\" rel=\"nofollow\">Proj4js<\/a> \u2014 which transforms point coordinates from one coordinate system to another. In simple terms, it will take care of plotting the dots over the respective geographical areas.<\/p>\n<p>I then use the <code>loadJsonFile<\/code> method inside the <code>&lt;script&gt;<\/code> tag in the body of the HTML page to load the JSON file.<\/p>\n<pre><code>&lt;html&gt;\r\n\u00a0\u00a0&lt;head&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;title&gt;JavaScript Dot Map&lt;\/title&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-base.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-map.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/geodata\/latest\/custom\/world\/world.js\"&gt;&lt;\/script&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-data-adapter.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/proj4js\/2.3.15\/proj4.js\"&gt;&lt;\/script&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;style type=\"text\/css\"&gt;      \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0html, body, #container { \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  width: 100%;\r\n        height: 100%;\r\n        margin: 0;\r\n        padding: 0; \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \r\n\u00a0\u00a0\u00a0\u00a0&lt;\/style&gt;\r\n\u00a0\u00a0&lt;\/head&gt;\r\n\u00a0\u00a0&lt;body&gt;  \r\n\u00a0\u00a0\u00a0\u00a0&lt;div id=\"container\"&gt;&lt;\/div&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script&gt;\r\n\u00a0\u00a0\u00a0   anychart.data.loadJsonFile('https:\/\/gist.githubusercontent.com\/shacheeswadia\/47b28a4d061e415555f01f5ce48e9ae3\/raw\/0f7592a8048872db7b77ccd2df8907e61952a806\/shippingDataInverted.json', function (data) {})\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/script&gt;\r\n\u00a0\u00a0&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/code><\/pre>\n<p>So, now that the package is all ready, it is time to ship it!<\/p>\n<h3>4. Add the code to draw the dot density map<\/h3>\n<p>The best part of using JS charting libraries is that the amount of code to write is really limited. I am not exaggerating when I say that the dot density map will be built in just 10 lines of code.<\/p>\n<p>Firstly, I will make sure that all the code for creating the chart is inside the <code>anychart.onDocumentReady()<\/code> function. This is to have the page fully loaded before anything else is executed. After the data is loaded, as we saw in the earlier step, I create the map and set the geodata. I also add a title to the map.<\/p>\n<pre><code>&lt;script&gt;\r\n\u00a0\u00a0anychart.onDocumentReady(function() {\r\n\u00a0\u00a0\u00a0\u00a0anychart.data.loadJsonFile('https:\/\/gist.githubusercontent.com\/shacheeswadia\/47b28a4d061e415555f01f5ce48e9ae3\/raw\/0f7592a8048872db7b77ccd2df8907e61952a806\/shippingDataInverted.json',\r\n\u00a0\u00a0\u00a0\u00a0function (data) {\r\n      \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ set the map chart\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var map = anychart.map();\r\n      \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ set the global geodata\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0map.geoData('anychart.maps.world');\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ set the map title\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0map.title( 'Shipping ports across the globe');\r\n\t\r\n\u00a0\u00a0\u00a0\u00a0});\r\n\u00a0\u00a0});\r\n&lt;\/script&gt;\r\n<\/code><\/pre>\n<p>Next, I create a series that will mark the seaports on the map as dots. Each point displays a latitude and longitude label by default which I don\u2019t want so I disable the labels for the series.<\/p>\n<pre><code>\/\/ set the marker series\r\nvar series = map.marker(anychart.data.set(data));   \r\n  \r\n\/\/ disable labels to not show latitude and longitude for each point\r\nseries.labels(false);<\/code><\/pre>\n<p>The final\u00a0two lines of code are setting the container to reference the previously added HTML block element and drawing the map.<\/p>\n<pre><code>\/\/ set the containter\r\nmap.container('container');\r\n\r\n\/\/ draw the map\r\nmap.draw();<\/code><\/pre>\n<p>That\u2019s it \u2014 a fully functional interactive dot density map is delivered!<\/p>\n<p><iframe loading=\"lazy\" class=\"anychart-embed anychart-embed-VevfP9bJ\" src=\"https:\/\/playground.anychart.com\/VevfP9bJ\/iframe\" width=\"300\" height=\"150\" frameborder=\"0\" sandbox=\"allow-scripts allow-pointer-lock allow-same-origin allow-popups allow-modals allow-forms\" allowfullscreen=\"allowfullscreen\"><br \/>\n<\/iframe><br \/>\n<script type=\"text\/javascript\">(function(){\nfunction ac_add_to_head(el){\n\tvar head = document.getElementsByTagName('head')[0];\n\thead.insertBefore(el,head.firstChild);\n}\nfunction ac_add_style(css){\n\tvar ac_style = document.createElement('style');\n\tif (ac_style.styleSheet) ac_style.styleSheet.cssText = css;\n\telse ac_style.appendChild(document.createTextNode(css));\n\tac_add_to_head(ac_style);\n}\nac_add_style(\".anychart-embed-VevfP9bJ{width:100%;height:600px;}\");\n})();<\/script><\/p>\n<p>You can check out this initial version with the code here, or on <a href=\"https:\/\/codepen.io\/shacheeswadia\/pen\/XWpgepY\" target=\"_blank\" rel=\"nofollow\">CodePen<\/a>, or on <a href=\"https:\/\/playground.anychart.com\/VevfP9bJ\/\" target=\"_blank\" rel=\"nofollow\">AnyChart Playground<\/a>.<\/p>\n<pre><code>&lt;html&gt;\r\n\u00a0\u00a0&lt;head&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;title&gt;JavaScript Dot Map&lt;\/title&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-base.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-map.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/geodata\/latest\/custom\/world\/world.js\"&gt;&lt;\/script&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-data-adapter.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/proj4js\/2.3.15\/proj4.js\"&gt;&lt;\/script&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;style type=\"text\/css\"&gt;      \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0html, body, #container { \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  width: 100%;\r\n        height: 100%;\r\n        margin: 0;\r\n        padding: 0; \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \r\n\u00a0\u00a0\u00a0\u00a0&lt;\/style&gt;\r\n\u00a0\u00a0&lt;\/head&gt;\r\n\u00a0\u00a0&lt;body&gt;  \r\n\u00a0\u00a0\u00a0\u00a0&lt;div id=\"container\"&gt;&lt;\/div&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script&gt;\r\n\u00a0\u00a0\u00a0 anychart.onDocumentReady(function() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0anychart.data.loadJsonFile('https:\/\/gist.githubusercontent.com\/shacheeswadia\/47b28a4d061e415555f01f5ce48e9ae3\/raw\/0f7592a8048872db7b77ccd2df8907e61952a806\/shippingDataInverted.json',\r\n\u00a0\u00a0\u00a0\u00a0  function (data) {\r\n      \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  \/\/ set the map chart\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  var map = anychart.map();\r\n      \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  \/\/ set the global geodata\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  map.geoData('anychart.maps.world');\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  \/\/ set the chart title\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  map.title( 'Shipping ports across the globe');\r\n\r\n        \/\/ set the marker series\r\n        var series = map.marker(anychart.data.set(data));   \r\n  \r\n        \/\/ disable labels to not show latitude and longitude for each point\r\n        series.labels(false);\r\n\r\n        \/\/ set the container\r\n        map.container('container');\r\n\r\n        \/\/ draw the chart\r\n        map.draw();\r\n\r\n\u00a0\u00a0\u00a0\u00a0  });\r\n    });\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/script&gt;\r\n\u00a0\u00a0&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/code><\/pre>\n<h2>Customizing JS Dot Map<\/h2>\n<p>We have a basic dot map built in JavaScript here, with predefined styles and features. However, there are numerous ways you can easily tweak the map to make it more engaging. You may want to make your\u00a0graphic aesthetically better, to highlight a particularly interesting aspect of the data visualization, or to add some functionality to improve the information being shown.<\/p>\n<p>I will show you how to customize the JS dot density map in the following ways:<\/p>\n<ol>\n<li>Indicate the number of outflows at each shipping port with a color scale.<\/li>\n<li>Enhance the tooltip.<\/li>\n<li>Add zoom functionality for the map.<\/li>\n<li>Change the overall color theme.<\/li>\n<\/ol>\n<h3>1. Indicate the number of outflows at each port with a color scale<\/h3>\n<p>I wanted to show more information in the visualization\u00a0without adding too much complexity. So, I add an extra dimension to the dot map by using colors to represent the number of outflows from each shipping port. This requires a bit of coding so follow along as I explain how I do this.<\/p>\n<p>Firstly, I define the dataset that I will map to multiple series with different colors based on the outflow numbers.<\/p>\n<pre><code>var portsDataSet = anychart.data.set(data).mapAs();<\/code><\/pre>\n<p>Next, I create a function that defines how I want to represent the series and also the legend for this representation. Now, using this function, I create\u00a0five different series, each with a name, minimum\/maximum number of outflows, and color.<\/p>\n<pre><code>\/\/ helper function to create several series\r\nvar createSeries = function (name, data, color) {\r\n        \r\n  \/\/ set the marker series\r\n  var series = map.marker(data);\r\n        \r\n  \/\/ configure the series settings\r\n  series\r\n    .name(name)\r\n    .fill(color)\r\n    .stroke('2 #E1E1E1')\r\n    .type('circle')\r\n    .size(5)\r\n    .labels(false)\r\n    .selectionMode('none');\r\n\r\n  series\r\n    .legendItem()\r\n    .iconType('circle')\r\n    .iconFill(color)\r\n    .iconStroke('2 #E1E1E1');\r\n  };\r\n\r\n\/\/ create 5 series, filtering the data by the outflows at each port\r\ncreateSeries(\r\n  'Up to 100,000',\r\n  portsDataSet.filter('outflows', filterFunction(0, 100000)),\r\n  '#D1FAE9'\r\n);\r\ncreateSeries(\r\n  '100,000 - 1,000,000',\r\n  portsDataSet.filter('outflows', filterFunction(100000, 1000000)),\r\n  '#9CE0E5'\r\n);\r\ncreateSeries(\r\n  '1,000,000 - 5,000,000',\r\n  portsDataSet.filter('outflows', filterFunction(1000000, 5000000)),\r\n  '#00ACC3'\r\n);\r\ncreateSeries(\r\n  '5,000,000 - 10,000,000',\r\n  portsDataSet.filter('outflows', filterFunction(5000000, 10000000)),\r\n  '#355CB1'\r\n);\r\ncreateSeries(\r\n  'More than 10,000,000 outflows',\r\n  portsDataSet.filter('outflows', filterFunction(10000000, 0)),\r\n  '#002D79'\r\n);<\/code><\/pre>\n<p>You will see that a filter function is used to segregate data in each series. This filter function is defined right at the end of the code.<\/p>\n<pre><code>\/\/ helper filter function\r\nfunction filterFunction(val1, val2) {\r\n  if (val2) {\r\n    return function (fieldVal) {\r\n      return val1 &lt;= fieldVal &amp;&amp; fieldVal &lt; val2;\r\n    };\r\n  }\r\n  return function (fieldVal) {\r\n    return val1 &lt;= fieldVal;\r\n  };\r\n}<\/code><\/pre>\n<p>I enable the legend for the map and voila, you can see the dots colored in 5 different shades according to the outflow numbers.<\/p>\n<pre><code>map.legend(true);<\/code><\/pre>\n<p><iframe sandbox=\"allow-scripts allow-pointer-lock allow-same-origin\n                 allow-popups allow-modals allow-forms\" frameBorder=\"0\" class=\"anychart-embed anychart-embed-wp2gHZeb\"\n        allowtransparency=\"true\" allowfullscreen=\"true\"\n        src=\"https:\/\/playground.anychart.com\/wp2gHZeb\/iframe\"><br \/>\n<\/iframe><br \/>\n<script type=\"text\/javascript\">(function(){\nfunction ac_add_to_head(el){\n\tvar head = document.getElementsByTagName('head')[0];\n\thead.insertBefore(el,head.firstChild);\n}\nfunction ac_add_style(css){\n\tvar ac_style = document.createElement('style');\n\tif (ac_style.styleSheet) ac_style.styleSheet.cssText = css;\n\telse ac_style.appendChild(document.createTextNode(css));\n\tac_add_to_head(ac_style);\n}\nac_add_style(\".anychart-embed-wp2gHZeb{width:100%;height:600px;}\");\n})();<\/script><\/p>\n<p>Don\u2019t worry if all this feels a bit overwhelming. It is a bit beyond the beginner level but not too complicated if you follow the steps. You can\u00a0play with the code\u00a0of this\u00a0customized dot density map on <a href=\"https:\/\/codepen.io\/shacheeswadia\/pen\/LYxLOWN\" target=\"_blank\" rel=\"nofollow\">CodePen<\/a>, or on <a href=\"https:\/\/playground.anychart.com\/wp2gHZeb\/\" target=\"_blank\" rel=\"nofollow\">AnyChart Playground<\/a>.<\/p>\n<h3>2. Enhance the map tooltip<\/h3>\n<p>The default tooltip of the dot map just shows the latitude and longitude of each point so I customize the tooltip to display some more meaningful information.<\/p>\n<p>For each point, I show the name of the shipping port as the title of the tooltip and the country as well as the number of outflows in the body of the tooltip. Since I want to show multiple fields, I enable HTML for the tooltip that would allow me to format the text. I then add all the information in HTML format.<\/p>\n<pre><code>map\r\n  .tooltip() \r\n  .useHtml(true)\r\n  .padding([8, 13, 10, 13])\r\n  .width(350)\r\n  .fontSize(12)\r\n  .fontColor('#e6e6e6')\r\n  .titleFormat(function () {\r\n    return this.getData('Name');\r\n  })\r\n  .format(function () {\r\n    return (\r\n      '&lt;span style=\"color: #bfbfbf;\"&gt;Country: &lt;\/span&gt;'+\r\n      this.getData('Country') +\r\n      '&lt;br\/&gt;' +\r\n      '&lt;span style=\"color: #bfbfbf;\"&gt;Outflows: &lt;\/span&gt;' +\r\n      this.getData('outflows').toFixed(0)\r\n    );\r\n  });<\/code><\/pre>\n<p>Doesn\u2019t the tooltip now feel like a useful additive to the dot density map?<\/p>\n<h3>3. Add zoom functionality for the map<\/h3>\n<p>In the dot map, I noticed that there are clusters indicating a lot of shipping ports in certain areas. To enable a viewer to have a closer view of those areas, I add the zoom functionality.<\/p>\n<p>For this, I first need to include some scripts and CSS links. I add all those in the <code>&lt;head&gt;<\/code> section. Then, I just add\u00a0two lines to enable zoom UI controls for the map. This again shows how easy and convenient it is to add such features when using an appropriate\u00a0data visualization library like AnyChart.<\/p>\n<pre><code class=\"html\">&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-exports.min.js\"&gt;&lt;\/script&gt;\r\n&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-ui.min.js\"&gt;&lt;\/script&gt;\r\n\r\n&lt;link rel=\"stylesheet\" type=\"text\/css\" href=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/css\/anychart-ui.min.css\"&gt;\r\n&lt;link rel=\"stylesheet\" type=\"text\/css\" href=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/fonts\/css\/anychart-font.min.css\"&gt;<\/code><\/pre>\n<pre><code class=\"javascript\">\/\/ add zoom ui controls\r\nvar zoomController = anychart.ui.zoom();\r\nzoomController.render(map);<\/code><\/pre>\n<p>Check out the <a href=\"https:\/\/docs.anychart.com\/Maps\/Move_and_Zoom\" target=\"_blank\" rel=\"nofollow\">Move and Zoom API<\/a> documentation if you want to set up any other interactive behavior to let the viewer dig into the data displayed on the map.<\/p>\n<h3>4. Change the overall theme and some appearance tweaks<\/h3>\n<p>To polish the dot density map just, I make some simple modifications. I decide to change the background of the map to a darker shade which would highlight the dots. For this, I use one of AnyChart\u2019s inbuilt <a href=\"https:\/\/docs.anychart.com\/Appearance_Settings\/Themes\" target=\"_blank\" rel=\"nofollow\">themes<\/a> \u2014 Dark Glamour \u2014 that includes predefined settings like the dark background color. For this, I include the theme script and add a line of code to set the theme for the map.<\/p>\n<pre><code>&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/themes\/dark_glamour.min.js\"&gt;&lt;\/script&gt;<\/code><\/pre>\n<pre><code>\/\/ set the color theme\r\nanychart.theme('darkGlamour');\r\n<\/code><\/pre>\n<p>One last thing I do is reduce the size of the\u00a0markers and remove the stroke for the series.<\/p>\n<pre><code>series\r\n  .name(name)\r\n  .fill(color)\r\n  .stroke('none')\r\n  .type('circle')\r\n  .size(3)\r\n  .labels(false)\r\n  .selectionMode('none');<\/code><\/pre>\n<p>There you have it! A really cool and beautiful dot map that intuitively showcases the different shipping ports around the globe.<\/p>\n<p><iframe sandbox=\"allow-scripts allow-pointer-lock allow-same-origin\n                 allow-popups allow-modals allow-forms\" frameBorder=\"0\" class=\"anychart-embed anychart-embed-xuPnlj6Q\"\n        allowtransparency=\"true\" allowfullscreen=\"true\"\n        src=\"https:\/\/playground.anychart.com\/xuPnlj6Q\/iframe\"><br \/>\n<\/iframe><br \/>\n<script type=\"text\/javascript\">(function(){\nfunction ac_add_to_head(el){\n\tvar head = document.getElementsByTagName('head')[0];\n\thead.insertBefore(el,head.firstChild);\n}\nfunction ac_add_style(css){\n\tvar ac_style = document.createElement('style');\n\tif (ac_style.styleSheet) ac_style.styleSheet.cssText = css;\n\telse ac_style.appendChild(document.createTextNode(css));\n\tac_add_to_head(ac_style);\n}\nac_add_style(\".anychart-embed-xuPnlj6Q{width:100%;height:600px;}\");\n})();<\/script><\/p>\n<p>Have a look at the code on <a href=\"https:\/\/codepen.io\/shacheeswadia\/pen\/eYgRVBM\" target=\"_blank\" rel=\"nofollow\">CodePen<\/a>, or on <a href=\"https:\/\/playground.anychart.com\/xuPnlj6Q\/\" target=\"_blank\" rel=\"nofollow\">AnyChart Playground<\/a>, or right here below.<\/p>\n<pre><code>&lt;html&gt;\r\n\u00a0\u00a0&lt;head&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;title&gt;JavaScript Dot Map&lt;\/title&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-base.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-map.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/geodata\/latest\/custom\/world\/world.js\"&gt;&lt;\/script&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-data-adapter.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/proj4js\/2.3.15\/proj4.js\"&gt;&lt;\/script&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-exports.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/js\/anychart-ui.min.js\"&gt;&lt;\/script&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/themes\/dark_glamour.min.js\"&gt;&lt;\/script&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;link rel=\"stylesheet\" type=\"text\/css\" href=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/css\/anychart-ui.min.css\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;link rel=\"stylesheet\" type=\"text\/css\" href=\"https:\/\/cdn.anychart.com\/releases\/8.9.0\/fonts\/css\/anychart-font.min.css\"&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;style type=\"text\/css\"&gt;      \r\n\u00a0\u00a0\u00a0\u00a0  html, body, #container { \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  width: 100%;\r\n        height: 100%;\r\n        margin: 0;\r\n        padding: 0; \r\n\u00a0\u00a0\u00a0\u00a0  } \r\n\u00a0\u00a0\u00a0\u00a0&lt;\/style&gt;\r\n\u00a0\u00a0&lt;\/head&gt;\r\n\u00a0\u00a0&lt;body&gt;  \r\n\u00a0\u00a0\u00a0\u00a0&lt;div id=\"container\"&gt;&lt;\/div&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;script&gt;\r\n\u00a0\u00a0\u00a0 anychart.onDocumentReady(function() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0anychart.data.loadJsonFile('https:\/\/gist.githubusercontent.com\/shacheeswadia\/47b28a4d061e415555f01f5ce48e9ae3\/raw\/0f7592a8048872db7b77ccd2df8907e61952a806\/shippingDataInverted.json',\r\n\u00a0\u00a0\u00a0\u00a0  function (data) {\r\n      \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ set the color theme\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0anychart.theme('darkGlamour');\r\n      \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ set the map chart\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var map = anychart.map();\r\n      \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ set the global geodata\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0map.geoData('anychart.maps.world');\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ set the chart title\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0map.title( 'Shipping ports across the globe');\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ create a dataset from data\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var portsDataSet = anychart.data.set(data).mapAs();\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ helper function to create several series\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var createSeries = function (name, data, color) {\r\n        \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ set the marker series\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var series = map.marker(data);\r\n        \r\n        \/\/ configure the series settings\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0series\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.name(name)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.fill(color)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.stroke('none')\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.type('circle')\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.size(3)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.labels(false)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.selectionMode('none');\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0series\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.legendItem()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.iconType('circle')\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.iconFill(color);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0};\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ create 5 series, filtering the data by the outflows at each port\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0createSeries(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'Up to 100,000',\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0portsDataSet.filter('outflows', filterFunction(0, 100000)),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'#D1FAE9'\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0createSeries(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'100,000 - 1,000,000',\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0portsDataSet.filter('outflows', filterFunction(100000, 1000000)),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'#9CE0E5'\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0createSeries(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'1,000,000 - 5,000,000',\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0portsDataSet.filter('outflows', filterFunction(1000000, 5000000)),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'#00ACC3'\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0createSeries(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'5,000,000 - 10,000,000',\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0portsDataSet.filter('outflows', filterFunction(5000000, 10000000)),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'#355CB1'\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0createSeries(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'More than 10,000,000 outflows',\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0portsDataSet.filter('outflows', filterFunction(10000000, 0)),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'#002D79'\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ enable and configure the map tooltip\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0map\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.tooltip() \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.useHtml(true)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.padding([8, 13, 10, 13])\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.width(350)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.fontSize(12)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.fontColor('#e6e6e6')\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.titleFormat(function () {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return this.getData('Name');\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.format(function () {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return (\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'&lt;span style=\"color: #bfbfbf\"&gt;Country: &lt;\/span&gt;'+\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.getData('Country') +\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'&lt;br\/&gt;' +\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'&lt;span style=\"color: #bfbfbf\"&gt;Outflows: &lt;\/span&gt;' +\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.getData('outflows').toFixed(0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ turn on the map legend\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0map.legend(true);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ add zoom ui controls\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var zoomController = anychart.ui.zoom();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0zoomController.render(map);\r\n\r\n      \/\/ set the container\r\n      map.container('container');\r\n\r\n      \/\/ draw the map\r\n      map.draw();\r\n\r\n      });\r\n    });\r\n\r\n    \/\/ helper filter function\r\n    function filterFunction(val1, val2) {\r\n  \u00a0\u00a0  if (val2) {\r\n\u00a0\u00a0\u00a0\u00a0    return function (fieldVal) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0    return val1 &lt;= fieldVal &amp;&amp; fieldVal &lt; val2;\r\n\u00a0\u00a0\u00a0\u00a0    };\r\n\u00a0\u00a0    }\r\n\u00a0\u00a0    return function (fieldVal) {\r\n\u00a0\u00a0\u00a0\u00a0    return val1 &lt;= fieldVal;\r\n\u00a0\u00a0    };\r\n    }\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/script&gt;\r\n\u00a0\u00a0&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/code><\/pre>\n<h2>Conclusion<\/h2>\n<p>As you see, it is quite simple and exciting to create interactive data visualizations like dot density maps using a JavaScript library. There are many different types of charts and maps available with AnyChart so check out the various options <a href=\"https:\/\/docs.anychart.com\/Quick_Start\/Supported_Charts_Types\" target=\"_blank\" rel=\"nofollow\">here<\/a>.<\/p>\n<p>I hope this tutorial has piqued your interest in dot maps and JavaScript charts in general. Please feel free to ask any questions, offer suggestions, or drop a comment. Go on, explore the seas and let your data visualization ship sail!<\/p>\n<hr \/>\n<p><strong><em>We at AnyChart are glad to thank Shachee Swadia for creating this amazing JS Dot Map tutorial.<\/em><\/p>\n<p><em>If you want to write an interesting guest post for our blog, please\u00a0<a href=\"https:\/\/www.anychart.com\/support\/\">contact us<\/a>.<\/em><\/strong><\/p>\n<hr \/>\n<p><strong><em>Check out other <a href=\"https:\/\/www.anychart.com\/blog\/category\/javascript-chart-tutorials\/\">JavaScript charting tutorials<\/a>.<\/em><\/strong><\/p>\n<p><!-- SyntaxHighlighter --><link rel=\"stylesheet\" href=\"\/\/cdnjs.cloudflare.com\/ajax\/libs\/highlight.js\/9.12.0\/styles\/default.min.css\"><link rel=\"stylesheet\" href=\"\/\/cdnjs.cloudflare.com\/ajax\/libs\/highlight.js\/9.12.0\/styles\/atom-one-light.min.css\"><script src=\"\/\/cdnjs.cloudflare.com\/ajax\/libs\/highlight.js\/9.12.0\/highlight.min.js\"><\/script><script>hljs.initHighlightingOnLoad();<\/script><\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>The recent incident of the Suez Canal blockage caught my interest in shipping and prompted me to explore the various shipping ports around the globe. There are more than 850 ports in the world and to get an overall view of where these are located, I decided to\u00a0plot them on\u00a0a dot map, or dot density [&hellip;]<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":20,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,66,263,23,13,279,4],"tags":[843,53,265,267,268,284,127,258,282,471,266,620,916,1292,880,806,1759,1293,840,294,257,2171,2220,54,1389,1760,256,1111,350,744,844,165,313,1370,743,133,774,775,2390,233,810,100,1528,2397,1530,2050,1527,236,2013,2014,32,55,150,144,809,36,907,141,249,81,57,142,67,2398,147,58,65,56,101,68,1937,2335,1938,2396,1858,1859,1728,340,237,2389,1190,1191,234,2392,2391,2393,459,2395,2394,30,172,832,954,1939,1233],"class_list":["post-12578","post","type-post","status-publish","format-standard","hentry","category-anychart-charting-component","category-anymap","category-big-data","category-html5","category-javascript","category-javascript-chart-tutorials","category-tips-and-tricks","tag-advanced-data-visualization","tag-anychart","tag-big-data","tag-big-data-applications","tag-big-data-tools","tag-chart-examples","tag-chart-types","tag-charts","tag-data","tag-data-analysis","tag-data-analytics","tag-data-analytics-examples","tag-data-api","tag-data-chart","tag-data-charting","tag-data-charts","tag-data-design","tag-data-map","tag-data-presentations","tag-data-science","tag-data-stories","tag-data-vis","tag-data-visual","tag-data-visualization","tag-data-visualization-best-pracices","tag-data-visualization-design","tag-data-visualization-examples","tag-data-visualization-practice","tag-data-visualization-projects","tag-data-visualization-techniques","tag-data-visualization-tutorial","tag-data-visualizations","tag-data-visuals","tag-data-viz-examples","tag-data-viz","tag-dataviz","tag-dataviz-examples","tag-dataviz-projects","tag-distribution-map","tag-dot-map","tag-dot-maps","tag-drawing-in-javascript","tag-geography","tag-geojson","tag-geoscience","tag-geospatial-analysis","tag-geospatial-technologies","tag-geovisualization","tag-html","tag-html-charts","tag-html5","tag-html5-charts","tag-html5-maps","tag-infographics","tag-interactive-maps","tag-javascript","tag-javascript-chart-tutorial","tag-javascript-charting","tag-javascript-charting-api","tag-javascript-charting-library","tag-javascript-charts","tag-javascript-graphics","tag-javascript-map","tag-javascript-mapping-library","tag-javascript-maps","tag-js-chart","tag-js-charting","tag-js-charts","tag-js-graphics","tag-js-maps","tag-json","tag-json-charts","tag-json-data-visualization","tag-json-map","tag-location-data","tag-location-data-visualization","tag-map","tag-map-visualizations","tag-maps","tag-marker-map","tag-open-data","tag-open-data-visualization","tag-point-map","tag-ports","tag-shipping","tag-shipping-ports","tag-statistics","tag-suez-canal","tag-the-world-bank-data-catalog","tag-tips-and-tricks","tag-tutorial","tag-visual-data","tag-visual-data-analytics","tag-visualizing-json-data","tag-world-bank","wpautop"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Making JS Dot Density Map to Visualize Shipping Ports Across Globe<\/title>\n<meta name=\"description\" content=\"Dot maps may seem difficult to create. Not true! Learn how to make a JS dot density map visualizing data of all shipping ports worldwide, in 4 quick steps.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Making JS Dot Density Map to Visualize Shipping Ports Across Globe\" \/>\n<meta property=\"og:description\" content=\"Dot maps may seem difficult to create. Not true! Learn how to make a JS dot density map visualizing data of all shipping ports worldwide, in 4 quick steps.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/\" \/>\n<meta property=\"og:site_name\" content=\"AnyChart News\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/AnyCharts\" \/>\n<meta property=\"article:published_time\" content=\"2021-04-20T11:10:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-08-13T11:04:54+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.anychart.com\/blog\/wp-content\/uploads\/2021\/04\/javascript-dot-density-map-shipping-ports-data-social.png\" \/>\n<meta name=\"author\" content=\"Shachee Swadia\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Making JS Dot Density Map to Visualize Shipping Ports Across Globe\" \/>\n<meta name=\"twitter:description\" content=\"Dot maps may seem difficult to create. Not true! Learn how to make a JS dot density map visualizing data of all shipping ports worldwide, in 4 quick steps.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.anychart.com\/blog\/wp-content\/uploads\/2021\/04\/javascript-dot-density-map-shipping-ports-data-social.png\" \/>\n<meta name=\"twitter:creator\" content=\"@AnyChart\" \/>\n<meta name=\"twitter:site\" content=\"@AnyChart\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Shachee Swadia\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/\"},\"author\":{\"name\":\"Shachee Swadia\",\"@id\":\"https:\/\/www.anychart.com\/blog\/#\/schema\/person\/273255f98371177b5ac1f4775610bb51\"},\"headline\":\"Making JS Dot Density Map to Visualize Shipping Ports Across Globe\",\"datePublished\":\"2021-04-20T11:10:04+00:00\",\"dateModified\":\"2022-08-13T11:04:54+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/\"},\"wordCount\":1622,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.anychart.com\/blog\/wp-content\/uploads\/2021\/04\/javascript-dot-density-map-shipping-ports-data.png\",\"keywords\":[\"advanced data visualization\",\"AnyChart\",\"big data\",\"big data applications\",\"big data tools\",\"chart examples\",\"chart types\",\"charts\",\"data\",\"data analysis\",\"data analytics\",\"data analytics examples\",\"data API\",\"data chart\",\"data charting\",\"data charts\",\"data design\",\"data map\",\"data presentations\",\"data science\",\"data stories\",\"data vis\",\"data visual\",\"Data Visualization\",\"data visualization best practices\",\"data visualization design\",\"data visualization examples\",\"data visualization practice\",\"data visualization projects\",\"data visualization techniques\",\"data visualization tutorial\",\"data visualizations\",\"data visuals\",\"data viz examples\",\"data-viz\",\"dataviz\",\"dataviz examples\",\"dataviz projects\",\"distribution map\",\"dot map\",\"dot maps\",\"drawing in JavaScript\",\"geography\",\"GeoJSON\",\"geoscience\",\"geospatial analysis\",\"geospatial technologies\",\"geovisualization\",\"HTML\",\"HTML charts\",\"HTML5\",\"html5 charts\",\"html5 maps\",\"infographics\",\"interactive maps\",\"JavaScript\",\"javascript chart tutorial\",\"javascript charting\",\"javascript charting api\",\"JavaScript charting library\",\"javascript charts\",\"javascript graphics\",\"javascript map\",\"JavaScript mapping library\",\"javascript maps\",\"js chart\",\"js charting\",\"js charts\",\"JS graphics\",\"js maps\",\"JSON\",\"JSON charts\",\"JSON data visualization\",\"JSON map\",\"location data\",\"location data visualization\",\"map\",\"map visualizations\",\"maps\",\"marker map\",\"open data\",\"open data visualization\",\"point map\",\"ports\",\"shipping\",\"shipping ports\",\"statistics\",\"Suez Canal\",\"The World Bank Data Catalog\",\"Tips and tricks\",\"tutorial\",\"visual data\",\"visual data analytics\",\"visualizing JSON data\",\"World Bank\"],\"articleSection\":[\"AnyChart Charting Component\",\"AnyMap\",\"Big Data\",\"HTML5\",\"JavaScript\",\"JavaScript Chart Tutorials\",\"Tips and Tricks\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/\",\"url\":\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/\",\"name\":\"Making JS Dot Density Map to Visualize Shipping Ports Across Globe\",\"isPartOf\":{\"@id\":\"https:\/\/www.anychart.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.anychart.com\/blog\/wp-content\/uploads\/2021\/04\/javascript-dot-density-map-shipping-ports-data.png\",\"datePublished\":\"2021-04-20T11:10:04+00:00\",\"dateModified\":\"2022-08-13T11:04:54+00:00\",\"author\":{\"@id\":\"https:\/\/www.anychart.com\/blog\/#\/schema\/person\/273255f98371177b5ac1f4775610bb51\"},\"description\":\"Dot maps may seem difficult to create. Not true! Learn how to make a JS dot density map visualizing data of all shipping ports worldwide, in 4 quick steps.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#primaryimage\",\"url\":\"\",\"contentUrl\":\"\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.anychart.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Making JS Dot Density Map to Visualize Shipping Ports Across Globe\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.anychart.com\/blog\/#website\",\"url\":\"https:\/\/www.anychart.com\/blog\/\",\"name\":\"AnyChart News\",\"description\":\"AnyChart JS Charts\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.anychart.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.anychart.com\/blog\/#\/schema\/person\/273255f98371177b5ac1f4775610bb51\",\"name\":\"Shachee Swadia\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.anychart.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/50ebd5c61e4e46e052898a5ddbcef5996666132cf07c614be4725f028ec7eae3?s=96&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/50ebd5c61e4e46e052898a5ddbcef5996666132cf07c614be4725f028ec7eae3?s=96&r=g\",\"caption\":\"Shachee Swadia\"},\"url\":\"https:\/\/www.anychart.com\/blog\/author\/shachee-swadia\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Making JS Dot Density Map to Visualize Shipping Ports Across Globe","description":"Dot maps may seem difficult to create. Not true! Learn how to make a JS dot density map visualizing data of all shipping ports worldwide, in 4 quick steps.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/","og_locale":"en_US","og_type":"article","og_title":"Making JS Dot Density Map to Visualize Shipping Ports Across Globe","og_description":"Dot maps may seem difficult to create. Not true! Learn how to make a JS dot density map visualizing data of all shipping ports worldwide, in 4 quick steps.","og_url":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/","og_site_name":"AnyChart News","article_publisher":"https:\/\/www.facebook.com\/AnyCharts","article_published_time":"2021-04-20T11:10:04+00:00","article_modified_time":"2022-08-13T11:04:54+00:00","og_image":[{"url":"https:\/\/www.anychart.com\/blog\/wp-content\/uploads\/2021\/04\/javascript-dot-density-map-shipping-ports-data-social.png","type":"","width":"","height":""}],"author":"Shachee Swadia","twitter_card":"summary_large_image","twitter_title":"Making JS Dot Density Map to Visualize Shipping Ports Across Globe","twitter_description":"Dot maps may seem difficult to create. Not true! Learn how to make a JS dot density map visualizing data of all shipping ports worldwide, in 4 quick steps.","twitter_image":"https:\/\/www.anychart.com\/blog\/wp-content\/uploads\/2021\/04\/javascript-dot-density-map-shipping-ports-data-social.png","twitter_creator":"@AnyChart","twitter_site":"@AnyChart","twitter_misc":{"Written by":"Shachee Swadia","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#article","isPartOf":{"@id":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/"},"author":{"name":"Shachee Swadia","@id":"https:\/\/www.anychart.com\/blog\/#\/schema\/person\/273255f98371177b5ac1f4775610bb51"},"headline":"Making JS Dot Density Map to Visualize Shipping Ports Across Globe","datePublished":"2021-04-20T11:10:04+00:00","dateModified":"2022-08-13T11:04:54+00:00","mainEntityOfPage":{"@id":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/"},"wordCount":1622,"commentCount":0,"image":{"@id":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#primaryimage"},"thumbnailUrl":"https:\/\/www.anychart.com\/blog\/wp-content\/uploads\/2021\/04\/javascript-dot-density-map-shipping-ports-data.png","keywords":["advanced data visualization","AnyChart","big data","big data applications","big data tools","chart examples","chart types","charts","data","data analysis","data analytics","data analytics examples","data API","data chart","data charting","data charts","data design","data map","data presentations","data science","data stories","data vis","data visual","Data Visualization","data visualization best practices","data visualization design","data visualization examples","data visualization practice","data visualization projects","data visualization techniques","data visualization tutorial","data visualizations","data visuals","data viz examples","data-viz","dataviz","dataviz examples","dataviz projects","distribution map","dot map","dot maps","drawing in JavaScript","geography","GeoJSON","geoscience","geospatial analysis","geospatial technologies","geovisualization","HTML","HTML charts","HTML5","html5 charts","html5 maps","infographics","interactive maps","JavaScript","javascript chart tutorial","javascript charting","javascript charting api","JavaScript charting library","javascript charts","javascript graphics","javascript map","JavaScript mapping library","javascript maps","js chart","js charting","js charts","JS graphics","js maps","JSON","JSON charts","JSON data visualization","JSON map","location data","location data visualization","map","map visualizations","maps","marker map","open data","open data visualization","point map","ports","shipping","shipping ports","statistics","Suez Canal","The World Bank Data Catalog","Tips and tricks","tutorial","visual data","visual data analytics","visualizing JSON data","World Bank"],"articleSection":["AnyChart Charting Component","AnyMap","Big Data","HTML5","JavaScript","JavaScript Chart Tutorials","Tips and Tricks"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/","url":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/","name":"Making JS Dot Density Map to Visualize Shipping Ports Across Globe","isPartOf":{"@id":"https:\/\/www.anychart.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#primaryimage"},"image":{"@id":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#primaryimage"},"thumbnailUrl":"https:\/\/www.anychart.com\/blog\/wp-content\/uploads\/2021\/04\/javascript-dot-density-map-shipping-ports-data.png","datePublished":"2021-04-20T11:10:04+00:00","dateModified":"2022-08-13T11:04:54+00:00","author":{"@id":"https:\/\/www.anychart.com\/blog\/#\/schema\/person\/273255f98371177b5ac1f4775610bb51"},"description":"Dot maps may seem difficult to create. Not true! Learn how to make a JS dot density map visualizing data of all shipping ports worldwide, in 4 quick steps.","breadcrumb":{"@id":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#primaryimage","url":"","contentUrl":""},{"@type":"BreadcrumbList","@id":"https:\/\/www.anychart.com\/blog\/2021\/04\/20\/js-dot-density-map\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.anychart.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Making JS Dot Density Map to Visualize Shipping Ports Across Globe"}]},{"@type":"WebSite","@id":"https:\/\/www.anychart.com\/blog\/#website","url":"https:\/\/www.anychart.com\/blog\/","name":"AnyChart News","description":"AnyChart JS Charts","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.anychart.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.anychart.com\/blog\/#\/schema\/person\/273255f98371177b5ac1f4775610bb51","name":"Shachee Swadia","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.anychart.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/50ebd5c61e4e46e052898a5ddbcef5996666132cf07c614be4725f028ec7eae3?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/50ebd5c61e4e46e052898a5ddbcef5996666132cf07c614be4725f028ec7eae3?s=96&r=g","caption":"Shachee Swadia"},"url":"https:\/\/www.anychart.com\/blog\/author\/shachee-swadia\/"}]}},"_links":{"self":[{"href":"https:\/\/www.anychart.com\/blog\/wp-json\/wp\/v2\/posts\/12578","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.anychart.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.anychart.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.anychart.com\/blog\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/www.anychart.com\/blog\/wp-json\/wp\/v2\/comments?post=12578"}],"version-history":[{"count":28,"href":"https:\/\/www.anychart.com\/blog\/wp-json\/wp\/v2\/posts\/12578\/revisions"}],"predecessor-version":[{"id":15508,"href":"https:\/\/www.anychart.com\/blog\/wp-json\/wp\/v2\/posts\/12578\/revisions\/15508"}],"wp:attachment":[{"href":"https:\/\/www.anychart.com\/blog\/wp-json\/wp\/v2\/media?parent=12578"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.anychart.com\/blog\/wp-json\/wp\/v2\/categories?post=12578"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.anychart.com\/blog\/wp-json\/wp\/v2\/tags?post=12578"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}