HelpBot Assistant

How can I help you?

Getting started with EJ2 TypeScript Maps component

3 Mar 202624 minutes to read

This section explains how to create a Maps component and configure its available functionalities in TypeScript using the Essential® JS 2 quickstart seed repository.

This application is integrated with the webpack.config.js configuration and uses the latest version of the webpack-cli. It requires node v14.15.0 or higher. For more information about webpack and its features, refer to the webpack documentation.

You can explore some useful features in the Maps component using the following video.

Prerequisites

Before getting started, ensure you have:

  • Node.js v14.15.0 or higher installed
  • Basic knowledge of TypeScript and webpack
  • A code editor (Visual Studio Code recommended)

Dependencies

The Maps component requires the following minimum dependencies:

|-- @syncfusion/ej2-maps
    |-- @syncfusion/ej2-base
    |-- @syncfusion/ej2-data
    |-- @syncfusion/ej2-pdf-export
    |-- @syncfusion/ej2-svg-base

Setup development environment

Open the command prompt from the required directory, and run the following command to clone the Syncfusion® JavaScript (Essential® JS 2) quickstart project from GitHub.

git clone https://github.com/SyncfusionExamples/ej2-quickstart-webpack- ej2-quickstart

After cloning the application in the ej2-quickstart folder, run the following command to navigate to the ej2-quickstart folder.

cd ej2-quickstart

Add Syncfusion® JavaScript packages

Syncfusion® JavaScript (Essential® JS 2) packages are available on the npmjs.com public registry. You can install all Syncfusion® JavaScript (Essential® JS 2) controls in a single @syncfusion/ej2 package or individual packages for each control.

The quickstart application is preconfigured with the dependent @syncfusion/ej2 package in the ~/package.json file. Use the following command to install the dependent npm packages from the command prompt.

npm install

Add Maps component to the project

The Essential® JS2 Maps component can be added to the application. To get started, add the Maps component to the app.ts and index.html files using the following code.

Step 1: Add HTML Container

Add an HTML div element to act as the Maps container in the index.html file using the following code.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Maps</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2//material.css" rel="stylesheet" />
</head>

<body>
    <!--container which is going to render the Map-->
    <div id='container'>
    </div>
</body>

</html>

Note: It’s recommended to set a height for the container element. If no height is specified, the Maps may not render properly.

Step 2: Initialize Maps Component

Import the Maps component in the app.ts to initialize a Maps and append the Maps instance to the #container.

import { Maps } from '@syncfusion/ej2-maps';

// initialize Maps component
let map: Maps = new Maps();

// render initialized Map
map.appendTo('#container');

Step 3: Run the Application

The quickstart project is configured to compile and run the application in the browser. Use the following command to run the application.

npm start

Since no shape data is specified, the Maps component displays as an empty SVG element. The next sections demonstrate how to add geographic data and customize the map.

Module Injection

The Maps component is segregated into individual feature-wise modules. To use a particular feature, inject its feature module using the Maps.Inject() method. The following modules are available in Maps along with their descriptions.

  • Annotations - Inject this provider to use the annotations feature.
  • Bubble - Inject this provider to use the bubble feature.
  • DataLabel - Inject this provider to use the data label feature.
  • Highlight - Inject this provider to use the highlight feature.
  • Legend - Inject this provider to use the legend feature.
  • Marker - Inject this provider to use the marker feature.
  • MapsTooltip - Inject this provider to use the tooltip feature.
  • NavigationLine - Inject this provider to use the navigation lines feature.
  • Selection - Inject this provider to use the selection feature.
  • Zoom - Inject this provider to use the zooming and panning feature.
  • Polygon - Inject this provider to use the polygon feature.

Now import the MapsTooltip, DataLabel, and Legend modules from the maps package and inject them into the Maps component using the Maps.Inject method.

import { Maps, Legend, DataLabel, MapsTooltip } from '@syncfusion/ej2-maps';
Maps.Inject(Legend, DataLabel, MapsTooltip);

Important: Always inject modules before using their associated features. If you try to enable a feature without injecting its module, it will not work.

Render shapes from GeoJSON data

Maps use the GeoJSON format to represent geographic features. GeoJSON is a standard format for encoding geographic data structures using JSON. This section explains how to bind GeoJSON data to render shapes on your map.

Understanding GeoJSON Structure

GeoJSON data contains geographic features with geometry and properties. Here’s a simplified example:

let usMap: Object = {
    "type": "FeatureCollection",
    "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
    "features": [
        { 
            "type": "Feature", 
            "properties": { 
                "iso_3166_2": "MA", 
                "name": "Massachusetts", 
                "admin": "United States of America" 
            }, 
            "geometry": { 
                "type": "MultiPolygon", 
                "coordinates": [ [ [ [ -70.801756294617277, 41.248076234530558 ] ] ] ] 
            }
        }
        // ... more features
    ]
};

For a complete world map, you can use the following structure:

export let world_map: object = {
    "type": "FeatureCollection",
    "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
    "features": [
        { 
            "type": "Feature", 
            "properties": { 
                "admin": "Afghanistan", 
                "name": "Afghanistan", 
                "continent": "Asia" 
            }, 
            // ... geometry data
        }
        // ... more countries
    ]
};

Binding GeoJSON to Maps

The Maps component renders geographic features through layers. Each layer can display different geographic data. To render shapes:

  1. Add a layer to the layers collection
  2. Bind your GeoJSON data to the shapeData property
import { Maps } from '@syncfusion/ej2-maps';
import { world_map } from './world-map.ts';
let map: Maps = new Maps({
   layers: [
        {
            shapeData: world_map
        }
    ]
});
map.appendTo('#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Maps</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="world-map.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container' style="height: 500px; width: 700px">
        <div id='element'></div>
    </div>

</body>

</html>

Note: Refer to the data values for world_map here.

Bind data source to map

The following properties in layers are used for binding a data source to the map.

  • dataSource
  • shapeDataPath
  • shapePropertyPath

The dataSource property takes a collection value as input. For example, a list of objects can be provided as input. This data is further used in tooltips, data labels, bubbles, legends, and color mapping.

The shapeDataPath property is used to refer to the data ID in the dataSource. The shapePropertyPath property is used to refer to the column name in shapeData to identify the shape. Both properties are related to each other. When the values of the shapeDataPath property in the dataSource and the value of shapePropertyPath in the shapeData match, the associated object from the dataSource is bound to the corresponding shape.

The JSON object “electionData” is used as a data source below.

import { Maps } from '@syncfusion/ej2-maps';
import { world_map } from './world-map.ts';
let map: Maps = new Maps({
   layers: [
        {
            shapeData: world_map,
            dataSource: [
                { "Country": "China", "Membership": "Permanent" },
                { "Country": "France", "Membership": "Permanent" },
                { "Country": "Russia", "Membership": "Permanent" },
                { "Country": "Kazakhstan", "Membership": "Non-Permanent" },
                { "Country": "Poland", "Membership": "Non-Permanent" },
                { "Country": "Sweden", "Membership": "Non-Permanent" }],
            shapePropertyPath: 'name',
            shapeDataPath: 'Country'
        }
    ]
});
map.appendTo('#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Maps</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="world-map.js"></script>

    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container' style="height: 500px; width: 700px">
        <div id='element'></div>
    </div>

</body>

</html>

Note: Refer to the data values for world_map here.

Apply Color Mapping

Color mapping customizes shape colors based on data values. Specify the data field to evaluate using the colorValuePath property in shapeSettings. Then define color assignments in the colorMapping property.

Specify the color and value in the colorMapping property. Here, ‘#D84444’ is specified for ‘Trump’ and ‘#316DB5’ is specified for ‘Clinton’.

//tslint:disable
import { Maps } from '@syncfusion/ej2-maps';
import { world_map } from './world-map.ts';
let map: Maps = new Maps({
   layers: [
        {
            shapeData: world_map,
            dataSource: [
                {  "Country": "China", "Membership": "Permanent" },
                { "Country": "France", "Membership": "Permanent" },
                { "Country": "Russia", "Membership": "Permanent" },
                { "Country": "Kazakhstan", "Membership": "Non-Permanent" },
                { "Country": "Poland", "Membership": "Non-Permanent" },
                { "Country": "Sweden", "Membership": "Non-Permanent" }],
            shapePropertyPath: 'name',
            shapeDataPath: 'Country',
            colorValuePath: 'Membership',
            shapeSettings: {
                colorValuePath: 'Membership',
                colorMapping: [
                {
                    value: 'Permanent', color: '#D84444'
                },
                {
                    value: 'Non-Permanent', color: '#316DB5'
                }]
            }
        }
    ]
});
map.appendTo('#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Maps</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="world-map.js"></script>

    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container' style="height: 500px; width: 700px">
        <div id='element'></div>
    </div>

</body>

</html>

Color Mapping Types

The Maps component supports multiple color mapping types:

  • Equal Color Mapping: Assign specific colors to specific values (shown above)
  • Range Color Mapping: Apply colors based on value ranges (e.g., 0-100, 100-500, 500+)
  • Desaturation Color Mapping: Use a single color with varying opacity based on values

Tip: Always use contrasting colors for better accessibility and readability. Consider color-blind friendly palettes for wider audience reach.

Add Title for Maps

Titles provide context about the map content. Use the titleSettings property to add a descriptive title:

//tslint:disable
import { Maps } from '@syncfusion/ej2-maps';
import { world_map } from './world-map.ts';
let map: Maps = new Maps({
            titleSettings: {
                text: 'USA Election Results'
            },
   layers: [
        {
            shapeData: world_map,
            dataSource: [
                { "Country": "China", "Membership": "Permanent" },
                { "Country": "France", "Membership": "Permanent" },
                { "Country": "Russia", "Membership": "Permanent" },
                { "Country": "Kazakhstan", "Membership": "Non-Permanent" },
                { "Country": "Poland", "Membership": "Non-Permanent" },
                { "Country": "Sweden", "Membership": "Non-Permanent" }],
            shapePropertyPath: 'name',
            shapeDataPath: 'Country',
            shapeSettings: {
                colorValuePath: 'Membership',
                colorMapping: [
                {
                    value: 'Permanent', color: '#D84444'
                },
                {
                    value: 'Non-Permanent', color: '#316DB5'
                }]
            }
        }
    ]
});
map.appendTo('#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Maps</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="world-map.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container' style="height: 500px; width: 700px">
        <div id='element'></div>
    </div>
</body>

</html>

Enable Legend

Legends identify shape categories and colors. Enable the legend by setting the visible property to true in the legendSettings object, and inject the Legend module:

import { Maps, Legend } from '@syncfusion/ej2-maps';
import { world_map } from './world-map.ts';
Maps.Inject(Legend);
let map: Maps = new Maps({
   layers: [
        {
            titleSettings: {
                text: 'USA Election Results'
            },
            shapeData: world_map,
            dataSource: [
                {  "Country": "China", "Membership": "Permanent" },
                { "Country": "France", "Membership": "Permanent" },
                { "Country": "Russia", "Membership": "Permanent" },
                { "Country": "Kazakhstan", "Membership": "Non-Permanent" },
                { "Country": "Poland", "Membership": "Non-Permanent" },
                { "Country": "Sweden", "Membership": "Non-Permanent" }],
            shapePropertyPath: 'name',
            shapeDataPath: 'Country',
            shapeSettings: {
                colorValuePath: 'Membership',
                colorMapping: [
                {
                    value: 'Permanent', color: '#D84444'
                },
                {
                    value: 'Non-Permanent', color: '#316DB5'
                }]
            }
        }
    ],
    legendSettings: {
        visible: true
    }
});
map.appendTo('#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Maps</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="world-map.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container' style="height: 500px; width: 700px">
        <div id='element'></div>
    </div>

</body>

</html>

Add Data Label

Data labels display additional information directly on shapes. Enable data labels by setting the visible property to true in the dataLabelSettings object, and inject the DataLabel module:

import { Maps, Legend, DataLabel } from '@syncfusion/ej2-maps';
import { world_map } from './world-map.ts';
Maps.Inject(Legend, DataLabel);
let map: Maps = new Maps({
   layers: [
        {
            shapeData: world_map,
            shapeSettings: {
                autofill: true
            },
            dataLabelSettings: {
                visible: true,
                labelPath: 'name',
                smartLabelMode: 'Trim'
            }
        }
    ]
});
map.appendTo('#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Maps</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="world-map.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container' style="height: 500px; width: 700px">
        <div id='element'></div>
    </div>

</body>

</html>

Enable Tooltip

Tooltips display information on hover and are useful when space constraints prevent using data labels. Enable tooltips by setting the visible property to true in the tooltipSettings object, and inject the MapsTooltip module:

import { Maps, DataLabel, MapsTooltip } from '@syncfusion/ej2-maps';
import { world_map } from './world-map.ts';
Maps.Inject(DataLabel, MapsTooltip);

let map: Maps = new Maps({
   layers: [
        {
            shapeData: world_map,
            shapeSettings: {
                autofill: true
            },
            dataLabelSettings: {
                visible: true,
                labelPath: 'name',
                smartLabelMode: 'Trim'
            },
            tooltipSettings: {
                visible: true,
                valuePath: 'name'
            }
        }
    ]
});
map.appendTo('#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Maps</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="world-map.js"></script>

    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container' style="height: 500px; width: 700px">
        <div id='element'></div>
    </div>

</body>

</html>

See also