svgMap is a JavaScript library that lets you easily create an interactable world map comparing customizable data for each country.

Overview

svgMap

svgMap is a JavaScript library that lets you easily create an interactable world map comparing customizable data for each country.

Live demo: https://stephanwagner.me/create-world-map-charts-with-svgmap#svgMapDemoGDP


Install

ES6

npm install --save svgmap
import svgMap from 'svgmap';
import 'svgmap/dist/svgMap.min.css';

CDN

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/svg-pan-zoom.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/StephanWagner/[email protected]/dist/svgMap.min.js"></script>
<link href="https://cdn.jsdelivr.net/gh/StephanWagner/[email protected]/dist/svgMap.min.css" rel="stylesheet">

Usage

Create an HTML element where to show your map, then use JavaScript to initialize:

<div id="svgMap"></div>
new svgMap({
  targetElementID: 'svgMap',
  data: {
    data: {
      gdp: {
        name: 'GDP per capita',
        format: '{0} USD',
        thousandSeparator: ',',
        thresholdMax: 50000,
        thresholdMin: 1000
      },
      change: {
        name: 'Change to year before',
        format: '{0} %'
      }
    },
    applyData: 'gdp',
    values: {
      AF: { gdp: 587, change: 4.73 },
      AL: { gdp: 4583, change: 11.09 },
      DZ: { gdp: 4293, change: 10.01 }
      // ...
    }
  }
});

This example code creates a world map with the GDP per capita and its change to the previous year: https://stephanwagner.me/create-world-map-charts-with-svgmap#svgMapDemoGDP


Options

You can pass the following options into svgMap:

Option Type Default
targetElementID string The ID of the element where the world map will render (Required)
minZoom float 1 Minimal zoom level
maxZoom float 25 Maximal zoom level
initialZoom float 1.06 Initial zoom level
initialPan object Initial pan on x and y axis (e.g. { x: 30, y: 60 })
showContinentSelector boolean false Show continent selector
zoomScaleSensitivity float 0.2 Sensitivity when zooming
showZoomReset boolean false Show zoom reset button
mouseWheelZoomEnabled boolean true Enables or disables zooming with the scroll wheel
mouseWheelZoomWithKey boolean false Allow zooming only when one of the following keys is pressed: SHIFT, CONTROL, ALT, COMMAND, OPTION
mouseWheelKeyMessage string 'Press the [ALT] key to zoom' The message when trying to scroll without a key
mouseWheelKeyMessageMac string Press the [COMMAND] key to zoom The message when trying to scroll without a key on MacOS
colorMax string '#CC0033' Color for highest value
colorMin string '#FFE5D9' Color for lowest value
colorNoData string '#E2E2E2' Color when there is no data
flagType 'image', 'emoji' 'image' The type of the flag in the tooltip
flagURL string The URL to the flags when using flag type 'image'. The placeholder {0} will get replaced with the lowercase ISO 3166-1 alpha-2 country code. Default: 'https://cdn.jsdelivr.net/gh/hjnilsson/[email protected]/svg/{0}.svg'
hideFlag boolean false Hide the flag in tooltips
noDataText string 'No data available' The text to be shown when no data is present
touchLink boolean false Set to true to open the link (see data.values.link) on mobile devices, by default the tooltip will be shown
onGetTooltip function Called when a tooltip is created to custimize the tooltip content (function (tooltipDiv, countryID, countryValues) { return 'Custom HTML'; })
countries object Additional options specific to countries:
   ↳ EH boolean true When set to false, Western Sahara (EH) will be combined with Morocco (MA)
   ↳ Crimea 'UA', 'RU' 'UA' Crimea: Set to 'RU' to make the Crimea part of Russia, by default it is part of the Ukraine
data object The chart data to use for coloring and to show in the tooltip. Use a unique data-id as key and provide following options as value:
   ↳ name string The name of the data, it will be shown in the tooltip
   ↳ format string The format for the data value, {0} will be replaced with the actual value
   ↳ thousandSeparator string ',' The character to use as thousand separator
   ↳ thresholdMax number null Maximal value to use for coloring calculations
   ↳ thresholdMin number 0 Minimum value to use for coloring calculations
   ↳ applyData string The ID (key) of the data that will be used for coloring
   ↳ values object An object with the ISO 3166-1 alpha-2 country code as key and the chart data for each country as value
        ↳ color string Forces a color for this country
        ↳ link string An URL to redirect to when clicking the country
        ↳ linkTarget string The target of the link. By default the link will be opened in the same tab. Use '_blank' to open the link in a new tab
countryNames object An object with the ISO 3166-1 alpha-2 country code as key and the country name as value

Localize

Use the option countryNames to translate country names. In the folder demo/html/local or demo/es6/local you can find translations in following languages: Arabic, Chinese, English, French, German, Hindi, Portuguese, Russian, Spanish, Urdu.

To create your own translations, check out country-list by Saša Stamenković.


Attribution

If you need more detailed maps or more options for your data, there is a great open source project called datawrapper out there, with a lot more power than svgMap.

svgMap uses svg-pan-zoom by Anders Riutta (now maintained by bumpu).

The country flag images are from country-flags by Hampus Joakim Borgos.

Most data in the demos was taken from Wikipedia.

Comments
  • The map of Russia and Ukraine is made incorrectly

    The map of Russia and Ukraine is made incorrectly

    Thank you for your work! What you did is really cool and useful!

    You have a serious error on the map that many site users don't like :(

    Crimea has not belonged to Ukraine for several years. It belongs to Russia. Screenshot: https://monosnap.com/file/ARm0SqeLMD76LNFxDGIvvUYpWSZIWQ

    I tried to fix it but it didn't work out. I will be very grateful if you fix it or tell me what SVG paths i need to put for Ukraine and Russia.

    Thank you for your work!

    opened by revered777 7
  • Add Internet Explorer Support

    Add Internet Explorer Support

    The library does not work in IE11 :( To test simply go to the example page https://stephanwagner.me/create-world-map-charts-with-svgmap#svgMapDemoGDP and you will not see any map.

    It does work in edge though it has scaling issues

    As much as we may all not like internet explorer, IE 11 does supports SVGs, doesn't hit EOL until 2023 and is still used across a lot of corporate netwoks so adding support would be good

    The error appears to be around the use of assign at character 29774 of svgmap.min.js

    Further investigation shows that it is indeed this line as Object.assign is not supported in IE and needs a polyfill or other work around in order to work

    opened by StevenMapes 4
  • Controls & tooltips z-index.

    Controls & tooltips z-index.

    Since no other element have a z-index defined, 0 is considered for all elements.

    Having z-index 50 for the map controls and z-index 10000 for the tooltips can create overlay issues in several cases.

    I'm suggesting z-index 1 for map controls, and z-index 2 for tooltips.

    This should avoid lots of issues with Boostrap and other CSS framework implementations, as they generally have higher z-index values defined.

    A clear example where z-index 50 for map controls is too high, is on a layout that has, let's say... a "slide-over" menu, with a z-index less than that, the map controls would actually overlay that menu, which is really undesirable. Or the tooltip would overlay the primary navigation element (let's say the header), no element on a page should supersed that.

    I have already done the required tests to ensure that it still works as expected, tooltips will overlay everything, and the map controls will overlay the map elements.

    opened by pricop 3
  • Added

    Added "onGetTooltip" function for custom tooltips

    Example to hide tooltip when there are no values...

    	onGetTooltip:function(tooltip, countryID, countryValues) {
    		if(!countryValues) {
    			tooltip.style.display='none';
    		} else {
    			tooltip.style.display='';
    		}
    	},
    

    Make your own tooltip...

    	onGetTooltip:function(tooltip, countryID, countryValues) {
    		var div= document.createElement('div');
    		div.innerHTML='custom stuff for '+countryID;
    		return div;
    	},
    

    A hacky way to get continents...

    var continents={
    	"NA":"North America"
    };
    var continentsMap={
    	US:"NA",
    	CA:"NA",
    	MX:"NA"
    };
    ```
    
    ```
    	onGetTooltip:function(tooltip, countryID, countryValues) {
    		if(continentsMap[countryID]) {
    			var div= document.createElement('div');
    			div.innerHTML=continents[continentsMap[countryID]];
    			return div;
    		}
    	},
    ```
    
    opened by niknah 2
  • tooltipContentTable is not defined

    tooltipContentTable is not defined

    image I have encountered an exception while mouse hover on the country which had data to view the tooltip, I have added this variable 'tooltipContentTable' in window object to solve this undefined variable exception. could be really helpful if you could declare this variable inside js file.

    bug 
    opened by fsdkarthik 2
  • Prevent firing click when dragging.

    Prevent firing click when dragging.

    Currently, when trying to pan the map and mouse cursor is on any country, click event will be triggered after panning, URL will be changed (if data link is set). This seems limiting how you can pan the map.

    This PR will prevent click from firing by logging if mouse (or finger) has been moved before mouse button / finger press is released.

    And also, thank you for the great project!

    opened by CQD 1
  • Manually set color of country option

    Manually set color of country option

    @StephanWagner - awesome project 🙌 I wanted the option to set a specific color manually from the data, so here's a PR of that functionality. Example use:

        ...
        values: {
          AF: {gdp: 587, change: 4.73, color: '#000'}
        ...
    

    ...or override the color option (in case of conflicts):

    new svgMap({
      targetElementID: 'svgMap',
      manualColorAttribute: 'manualcolor', //override 'color'
      data: {
        data: {
          gdp: {
            name: 'GDP per capita',
            format: '{0} USD',
            thousandSeparator: ',',
            thresholdMax: 50000,
            thresholdMin: 1000
          },
          change: {
            name: 'Change to year before',
            format: '{0} %'
          }
        },
        applyData: 'gdp',
        values: {
          AF: {gdp: 587, change: 4.73, manualcolor: '#000'}, // use the overridden value here to set a color manually
          AL: {gdp: 4583, change: 11.09},
          DZ: {gdp: 4293, change: 10.01}
          // ...
        }
      }
    });
    
    opened by OllieJC 1
  • Is it possible to open the associated link in a new tab?

    Is it possible to open the associated link in a new tab?

    I feel like having to go back and forth every time you open a new link can be a downside for some users.

    I tried adding my own JS after setting the options but due to my limited knowledge of the language, I couldn't override the default behaviour.

    enhancement 
    opened by tavernhell 1
  • Singapore no longer accessible after hovering over Malaysia

    Singapore no longer accessible after hovering over Malaysia

    We noticed when trying to use the map that, even when zoomed in, Singapore was no longer visible or able to be accessed if you have previously hovered over Malaysia (as it brings that particular path to the front, covering Singapore). We resolved this by editing the SVG path data in mapPaths.js to clean up the division between the two.

    The path information is below in case it is useful for anyone. After updating the path information we just ran the build process again to generate new versions of the combined .js files.

    Singapore: M1561.4, 563.4l-0.5-0.3l-0.8-0.1l-0.6,0.1l-0.3,0.6 l0.0,0.6L1561.8,564z

    Malaysia: M1543.6,532.7l-4.7-2.8l-0.9,1.1l1.4,2.7l-0.4,4.7l2.1,3.4l1,5.3 l3.4,4.3l0.8,3.2l6.7,5l5.4,4.8 0.8-0.1 0-0.6 0.3-0.6 0.6-0.1 0.8,0.1 0.5,0.3 0.4,0.6 l0.6-0.1 l0.1-2.1 l-2.3-5.6 l-2.1-1.8l-0.5-3.8l-0.6-2.1l0.5-2.9l-0.5-4.3l-2.6-4.3l-3.5-3.8l-1.3-0.6 l-1.7,2.6l-3.7,0.8L1543.6,532.7L1543.6,532.7z M1642.6,543.7l-1.2-3.1l3.8-0.4l0.3-2.4l-4.8-2l-3.8-1.7l-0.4-2.8l-3.1-3.2h-2.3 l-2.5,5l-4.1,4.4l-0.1,3.1l-0.1,4.1l-2.7-0.2l-1.1,2.2l-2.7-3.3l-2.6,4l-3.8,5l-6.7,1.4l-2.4,1.2l-0.9,5.4l-4.4,1.2l-4.1-2.2l1,4.3 l3.9,3.5l3.6-1.2l3.6,0.4l3.2-3.2l2.7-0.6l5.4,1.8l4.5-1.3l2.7-8.9l2-2.2l1.7-7.2h6.4l5,1L1642.6,543.7z

    opened by sneaknz 1
  • Bump minimatch from 3.0.4 to 3.1.2

    Bump minimatch from 3.0.4 to 3.1.2

    Bumps minimatch from 3.0.4 to 3.1.2.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump loader-utils from 2.0.3 to 2.0.4 in /demo/react/app

    Bump loader-utils from 2.0.3 to 2.0.4 in /demo/react/app

    Bumps loader-utils from 2.0.3 to 2.0.4.

    Release notes

    Sourced from loader-utils's releases.

    v2.0.4

    2.0.4 (2022-11-11)

    Bug Fixes

    Changelog

    Sourced from loader-utils's changelog.

    2.0.4 (2022-11-11)

    Bug Fixes

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • If map cantainer is smaller, continent selector show wrong world part

    If map cantainer is smaller, continent selector show wrong world part

    Hi.

    There is not correct work of continent selector when map container has small size.

    Here screenshot form your example page ( html folder ) -> https://prnt.sc/PzqQNWj6mRBP -> https://prnt.sc/r09NjimffwaX

    It would be nice to fix this. Thank's.

    opened by Aleksandr2015 0
  • How can I destroy the map entity?

    How can I destroy the map entity?

    Let's say I've created a map like below:

                        this.map = new svgMap({
                            targetElementID: 'cmsSvgMap',
                            data: mapData,
                            colorMax: '#393c4d',
                            colorMin: '#393c4d73',
                            flagType: 'emoji',
                            noDataText: this.$t('analytics.cookies.map.no_data'),
                            countryNames: this.countries.reduce((acc, cur) => ({ ...acc, [cur.country_id??'_unknown']: cur.country_name }), {})
                        });
    

    I then want to destroy what is in this.map - there doesn't seem to be a destroy() function?

    opened by seifti 0
  • Trigger showtooltip

    Trigger showtooltip

    Hi, I have a html table with some countries. Clicking on country row I have a country code, so I need to show tooltip (and zoom on it if necessary), highlight country (same as mousenter event) programmatically using id of country path. It's possible with this script ?

    Alberto

    opened by albertixcom 2
  • [Question] Map lat/lon to pixel x y on the map

    [Question] Map lat/lon to pixel x y on the map

    Is there a function to convert a lat/lon (in degrees) to an x,y pixel on the map? If not, what projection is the map using by default and I can probably make one...

    enhancement 
    opened by jjxtra 1
  • No Typescript compatibility, and 'window is not defined' error on Next.js

    No Typescript compatibility, and 'window is not defined' error on Next.js

    I'm trying to use svgMap with Next.js and Typescript and I feel like I'm doing something wrong.

    First of all, I can't find any '@types/svgmap' package when I try to install one, so I just need to force Typescript to ignore this.

    Secondly, I am using the library as it is documented, but I get a 'window is not defined' error when I run the code. I have created a div element with the "svgMap" id with it as follows: <div className="map-container w-full" id="svgMap"></div>

    I imported the library, with its css.

    // @ts-ignore
    import svgMap from "svgmap";
    import "svgmap/dist/svgMap.min.css"
    

    and created a new svgMap when the component is mounted. I've also made sure that it's only run if 'window' is defined. Here's the code:

    useEffect(() => {
        new svgMap({
          targetElementID: "svgMap",
          data: {
            data: {
              gdp: {
                name: "GDP per capita",
                format: "{0} USD",
                thousandSeparator: ",",
                thresholdMax: 50000,
                thresholdMin: 1000,
              },
              change: {
                name: "Change to year before",
                format: "{0} %",
              },
            },
            applyData: "gdp",
            values: {
              AF: { gdp: 587, change: 4.73 },
              AL: { gdp: 4583, change: 11.09 },
              DZ: { gdp: 4293, change: 10.01 },
              // ...
            },
          },
        });
      }, []);
    

    That is an example map data that's stated in the documentation of the library, and as I said when I run it I get this: image

    Am I using the library in a wrong way? or Is it not compatible with React yet?

    opened by 0sssama 7
Releases(v2.10.1)
Owner
Stephan Wagner
When I'm not hopping around the globe, you'll most likely find me glued to my mac hunting down syntax errors. I hate snytax errors!
Stephan Wagner
Make Your Company Data Driven. Connect to any data source, easily visualize, dashboard and share your data.

Redash is designed to enable anyone, regardless of the level of technical sophistication, to harness the power of data big and small. SQL users levera

Redash 22.2k Nov 21, 2022
A logseq plugin that lets you find #tags

Logseq Tags Plugin A plugin that lets you find and search all of your #tags. This plugin will query and list all #tags, #[[tags]] and page-tags(tags::

Gidong Kwon 91 Nov 14, 2022
JAVASCRIPT library with which you can easily draw CANVAS HTML

easycanvas Quick start Documentation: gaidadei.ru/easycanvas Download: gaidadei.ru/easycanvas/easyc.zip Buy premium: gaidadei.ru/easycanvas/premium (A

null 18 Nov 12, 2022
danfo.js is an open source, JavaScript library providing high performance, intuitive, and easy to use data structures for manipulating and processing structured data.

Danfojs: powerful javascript data analysis toolkit What is it? Danfo.js is a javascript package that provides fast, flexible, and expressive data stru

JSdata 3.9k Nov 28, 2022
Mini map for web pages.

pagemap Mini map for web pages. Example usage add a canvas tag to your HTML page: <canvas id='map'></canvas> fix it's position on the screen: #map {

Lars Jung 1.2k Nov 21, 2022
Composable data visualisation library for web with a data-first approach now powered by WebAssembly

What is Muze? Muze is a free data visualization library for creating exploratory data visualizations (like Tableau) in browser, using WebAssembly. It

Charts.com 1.2k Nov 15, 2022
Highly customizable, animated, responsive, and dependency-free Evolution Graph implementation

Highly customizable, animated, responsive, and dependency-free Evolution Graph implementation. The package is built with Vanilla JavaScript and is used to create flexible data visualizations and present evolution relationships between entities.

Nathan S. Santos 38 Oct 16, 2022
Easily compose images together without messing around with canvas

merge-images Easily compose images together without messing around with canvas Canvas can be kind of a pain to work with sometimes, especially if you

Luke Childs 1.5k Nov 25, 2022
D3 (or D3.js) is a JavaScript library for visualizing data using web standards

D3 (or D3.js) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data.

D3 103.5k Nov 23, 2022
Apache Superset is a Data Visualization and Data Exploration Platform

Superset A modern, enterprise-ready business intelligence web application. Why Superset? | Supported Databases | Installation and Configuration | Rele

The Apache Software Foundation 49.3k Nov 26, 2022
DataSphereStudio is a one stop data application development& management portal, covering scenarios including data exchange, desensitization/cleansing, analysis/mining, quality measurement, visualization, and task scheduling.

English | 中文 Introduction DataSphere Studio (DSS for short) is WeDataSphere, a big data platform of WeBank, a self-developed one-stop data application

WeBankFinTech 2.4k Nov 19, 2022
API to generate candlestick chart data for any time period based on transactions data

candel-maker API to generate candlestick chart data for any time period based on transactions data Installation clone repo git clone https://github.co

null 2 Aug 18, 2022
Java library for use with Chart.js javascript library

Chart.java Chart.java enables integration with the excellent Chart.js library from within a Java application. Usage example In Java: BarDataset datase

Marceau Dewilde 101 Nov 17, 2022
Apache ECharts is a powerful, interactive charting and data visualization library for browser

Apache ECharts Apache ECharts is a free, powerful charting and visualization library offering an easy way of adding intuitive, interactive, and highly

The Apache Software Foundation 53.4k Nov 25, 2022
A library optimized for concise and principled data graphics and layouts.

MetricsGraphics is a library built for visualizing and laying out time-series data. At around 15kB (gzipped), it provides a simple way to produce comm

Metrics Graphics 7.5k Nov 16, 2022
Data visualization library for depicting quantities as animated liquid blobs

liquidity.js A data visualization library for depicting quantities as animated liquid blobs. For a demonstration of what the final product can look li

N Halloran 91 Sep 20, 2022
Powerful data visualization library based on G2 and React.

BizCharts New charting and visualization library has been released: http://bizcharts.net/products/bizCharts. More details about BizCharts Features Rea

Alibaba 6k Nov 19, 2022
🌏 A Declarative 3D Globe Data Visualization Library built with Three.js

Gio.js English | 中文 React Version: react-giojs Wechat minigame: wechat usage Gio.js is an open source library for web 3D globe data visualization buil

syt123450 1.6k Nov 25, 2022
📊 Data visualization library for React based on D3

Data visualization library for React based on D3js REAVIZ is a modular chart component library that leverages React natively for rendering the compone

REAVIZ 729 Nov 17, 2022