End-User Interaction

The dxVectorMap widget provides a number of features that make your map interactive, hence more attractive to an end-user. Among them, you will find panning and zooming of a map, selection of map elements, click handling, and others. You can adjust these features to your requirements. Refer to the corresponding topic of this guide to get detailed information on how to configure the feature of your interest.

Panning

When a map in the VectorMap widget goes beyond the size of the container, panning can be used to view the regions that do not fit the container. To pan a map, the user drags the mouse pointer or one finger (when using a touchscreen device) along or across the map. Panning can also be performed using the arrows of a pan control, which is a part of the control bar. Clicking the button located in the center of the pan control resets panning settings.

Technically, panning is changing the view area. VectorMap provides a number of options and methods for operating with the view area. Their capabilities are described in the following subtopics.

Show Example:
AngularJS
Knockout
jQuery

In this example, the map is initially centered on Chicago using the center option. Then, each time you pan, the updated coordinates of the center appear under the map. This behavior is accomplished by implementing the onCenterChanged callback function.

<div ng-controller="vectorMapController">
    <div style="height:400px; max-width:750px; margin: 0 auto" dx-vector-map="vectorMapCfg"></div>
    <div ng-bind="text" style="height:25px; text-align:center; margin-top: 5px"></div> 
</div>
var markerData = [
    { coordinates: [-87.627778, 41.881944], attributes: { text: 'Chicago' } }
];

var i = 0;

angular
    .module('myApp', ['dx'])
    .controller('vectorMapController', function ($scope) {
        $scope.text = "",
        $scope.vectorMapInstance = {};
        $scope.vectorMapCfg = {
            layers: [{
                type: 'area',
                dataSource: '/Content/data/vectorMap-sources/usa.txt',
                palette: 'Soft',
                paletteSize: 10,
                customize: function (elements) {
                    angular.forEach(elements, function (element) {
                        element.applySettings({ paletteIndex: i++ % 10 });
                    });
                }
            }, {
                type: 'marker',
                dataSource: markerData,
                label: {
                    enabled: true,
                    dataField: 'text'
                }
            }],
            tooltip: {
                enabled: true,
                customizeTooltip: function () {
                    return { text: this.attribute('name') };
                }
            },
            onCenterChanged: function (info) {
                var updatedCoordinates = info.center;
                $scope.text = 'Center coordinates: (' + updatedCoordinates[0].toPrecision(4) + ', ' + updatedCoordinates[1].toPrecision(4) + ')';
            },
            bounds: [-135, 60, -65, 20],
            center: [-87.627778, 41.881944] // the map is initially centered on Chicago
        }
    });

angular.element(document).ready(function () {
   angular.bootstrap(document, ['myApp']);
});

In this example, the map is initially centered on Chicago using the center option. Then, each time you pan, the updated coordinates of the center appear under the map. This behavior is accomplished by implementing the onCenterChanged callback function.

<div style="height:400px; max-width:750px; margin: 0 auto" data-bind="dxVectorMap: vectorMapCfg"></div>
<div style="height:25px; text-align:center; margin-top: 5px" data-bind="text: text"></div>
var markerData = [
    { coordinates: [-87.627778, 41.881944], attributes: { text: 'Chicago' } }
];

var i = 0;

var viewModel = {
    text: ko.observable(),
    vectorMapInstance: {},
    vectorMapCfg: {
        layers: [{
            type: 'area',
            dataSource: '/Content/data/vectorMap-sources/usa.txt',
            palette: 'Soft',
            paletteSize: 10,
            customize: function (elements) {
                ko.utils.arrayForEach(elements, function (element) {
                    element.applySettings({ paletteIndex: i++ % 10 });
                });
            }
        }, {
            type: 'marker',
            dataSource: markerData,
            label: {
                enabled: true,
                dataField: 'text'
            }
        }],
        tooltip: {
            enabled: true,
            customizeTooltip: function () {
                return { text: this.attribute('name') };
            }
        },
        onCenterChanged: function (info) {
            var updatedCoordinates = info.center;
            viewModel.text('Center coordinates: (' + updatedCoordinates[0].toPrecision(4) + ', ' + updatedCoordinates[1].toPrecision(4) + ')');
        },
        bounds: [-135, 60, -65, 20],
        center: [-87.627778, 41.881944] // the map is initially centered on Chicago
    }
};

ko.applyBindings(viewModel);

In this example, the map is initially centered on Chicago using the center option. Then, each time you pan, the updated coordinates of the center appear under the map. This behavior is accomplished by implementing the onCenterChanged callback function.

<div id="vectorMapContainer" style="height:400px; max-width:750px; margin: 0 auto"></div>
<div id="textArea" style="height:25px; text-align:center; margin-top: 5px"></div>
var markerData = [
    { coordinates: [-87.627778, 41.881944], attributes: { text: 'Chicago' } }
];

$(function () {
    $('#vectorMapContainer').dxVectorMap({
        layers: [{
            type: 'area',
            dataSource: '/Content/data/vectorMap-sources/usa.txt',
            palette: 'Soft',
            paletteSize: 10,
            customize: function (elements) {
                $.each(elements, function (i, element) {
                    element.applySettings({ paletteIndex: i % 10 });
                });
            }
        }, {
            type: 'marker',
            dataSource: markerData,
            label: {
                enabled: true,
                dataField: 'text'
            }
        }],
        tooltip: {
            enabled: true,
            customizeTooltip: function () {
                return { text: this.attribute('name') };
            }
        },
        onCenterChanged: function (info) {
            var updatedCoordinates = info.center;
            $('#textArea').html('');
            $('#textArea').html('Center coordinates: (' + updatedCoordinates[0].toPrecision(4) + ', ' + updatedCoordinates[1].toPrecision(4) + ')');
        },
        bounds: [-135, 60, -65, 20],
        center: [-87.627778, 41.881944] // the map is initially centered on Chicago
    });
});

Set Initial Location

By default, any map is centered on a (0, 0) geographical point. To center the map on a different point, specify the center option that accepts an array of two values representing the longitude and the latitude of a point.

JavaScript
var vectorMapCfg = {
    // ...
    center: [-87.627778, 41.881944] // centers the map on Chicago
};

If you need to restrict the view area to specific coordinates, set the bounds option. This option accepts an array of geographical coordinates in the following format: [minLongitude, maxLatitude, maxLongitude, minLatitude].

JavaScript
var vectorMapCfg = {
    // ...
    bounds: [-135, 60, -65, 20] // displays the USA by default
};

Pan in Code

When you need to place the center into a different geographical point, use the center(centerCoordinates) method. Call this method with an array of two values: the longitude and the latitude of the new center, similar to the array the center option accepts.

JavaScript
vectorMapInstance.center([-106.61, 35.110833]); // moves the center to Albuquerque

Calling the same method without arguments returns the current coordinates of the center.

Similarly, you can change the current view area using the viewport(viewportCoordinates) method. It accepts an array of geographical coordinates in the following format: [minLongitude, maxLatitude, maxLongitude, minLatitude].

JavaScript
vectorMapInstance.viewport([15, 10, 110, 75]); // navigates the map to Eurasia

To get the current coordinates of the view area, call the same method without arguments. Note that changing the view area with the viewport(viewportCoordinates) methods may raise the center change and zoom change events if the center coordinates and zoom factor have been changed when you set new coordinates for the view area.

Handle the Center Change Event

When panning is performed, the center change event is raised. You can handle this event using a callback function assigned to the onCenterChanged option. When implementing this function, use the object passed to it as the parameter. Fields of this object are described in the onCenterChanged option description. Among these fields, you can find the updated center coordinates.

JavaScript
var vectorMapCfg = {
    // ...
    onCenterChanged: function (info) {
        // specify required actions here
    }
};

Zooming

Zooming allows the end-user to enlarge a map in order to view those parts of it that are difficult to distinguish. To zoom in and zoom out of a map, the user can scroll the mouse wheel or use the spread and pinch gestures (when using a touchscreen device). Zooming can also be performed using a zoom bar, which is a part of the control bar.

When zoomed, a map does not exceed the container size. Instead, it leaves only a certain region of itself visible. In order to navigate to concealed regions of the map, panning must be used.

Apart from zooming in UI, VectorMap supplies you with several options and methods configuring and managing zooming in code. For more information about these options, navigate to the following subtopics.

Show Example:
AngularJS
Knockout
jQuery

In this example, the map is initially zoomed 3 times using the zoomFactor option. Then, each time you perform zooming, the updated value of the zoom factor appears under the map. This behavior is accomplished by implementing the zoomChanged callback function.

<div ng-controller="vectorMapController">
    <div style="height:400px; max-width:750px; margin: 0 auto" dx-vector-map="vectorMapCfg"></div>
    <div ng-bind="text" style="height:25px; text-align:center; margin-top: 5px"></div> 
</div>
var i = 0;

angular
    .module('myApp', ['dx'])
    .controller('vectorMapController', function ($scope) {
        $scope.text = "",
        $scope.vectorMapCfg = {
            layers: [{
                type: 'area',
                dataSource: '/Content/data/vectorMap-sources/world.txt',
                palette: 'Default',
                paletteSize: 9,
                customize: function (elements) {
                    angular.forEach(elements, function (element) {
                        element.applySettings({ paletteIndex: i++ % 9 });
                    });
                }
            }],
            zoomFactor: 3,
            onZoomFactorChanged: function (info) {
                var updatedZoomFactor = info.zoomFactor;
                $scope.text = 'Current zoom factor: ' + updatedZoomFactor.toPrecision(3);
            }
        }
    });

angular.element(document).ready(function () {
   angular.bootstrap(document, ['myApp']);
});

In this example, the map is initially zoomed 3 times using the zoomFactor option. Then, each time you perform zooming, the updated value of the zoom factor appears under the map. This behavior is accomplished by implementing the zoomChanged callback function.

<div style="height:400px; max-width:750px; margin: 0 auto" data-bind="dxVectorMap: vectorMapCfg"></div>
<div style="height:25px; text-align:center; margin-top: 5px" data-bind="text: text"></div>
var i = 0;

var viewModel = {
    text: ko.observable(),
    vectorMapCfg: {
        layers: [{
            type: 'area',
            dataSource: '/Content/data/vectorMap-sources/world.txt',
            palette: 'Default',
            paletteSize: 9,
            customize: function (elements) {
                ko.utils.arrayForEach(elements, function (element) {
                    element.applySettings({ paletteIndex: i++ % 9 });
                });
            }
        }],
        zoomFactor: 3,
        onZoomFactorChanged: function (info) {
            var updatedZoomFactor = info.zoomFactor;
            viewModel.text('Current zoom factor: ' + updatedZoomFactor.toPrecision(3));
        }
    }
};

ko.applyBindings(viewModel);

In this example, the map is initially zoomed 3 times using the zoomFactor option. Then, each time you perform zooming, the updated value of the zoom factor appears under the map. This behavior is accomplished by implementing the zoomChanged callback function.

<div id="vectorMapContainer" style="height:400px; max-width:750px; margin: 0 auto"></div>
<div id="textArea" style="height:25px; text-align:center; margin-top: 5px"></div>
$(function () {
    $('#vectorMapContainer').dxVectorMap({
        layers: [{
            type: 'area',
            dataSource: '/Content/data/vectorMap-sources/world.txt',
            palette: 'Default',
            paletteSize: 9,
            customize: function (elements) {
                $.each(elements, function (i, element) {
                    element.applySettings({ paletteIndex: i % 9 });
                });
            }
        }],
        zoomFactor: 3,
        onZoomFactorChanged: function (info) {
            var updatedZoomFactor = info.zoomFactor;
            $('#textArea').html('');
            $('#textArea').html('Current zoom factor: ' + updatedZoomFactor.toPrecision(3));
        }
    });
});

Set Initial Zoom

In code, zoom is measured by a zoom factor. The zoom factor represents the relation between the width (or height) after and the width (or height) before zooming. Simply put, the zoom factor shows how much a map is zoomed relatively to its original size. For example, the zoom factor equaling 2 means that the map is twice larger than the original.

For setting initial zoom, assign a number greater than 1 to the zoomFactor option.

JavaScript
var vectorMapCfg = {
    // ...
    zoomFactor: 2.5 // zooms the map 2.5 times
};

Zoom in Code

To perform zooming in code, use the zoomFactor(zoomFactor) method. When calling this method, pass the required value of the zoom factor as the argument as it is illustrated by the code snippet below.

JavaScript
vectorMapInstance.zoomFactor(1.5); // zooms the map 1.5 times

Calling the same method without arguments returns the current value of the zoom factor.

Handle the Zoom Change Event

You can perform specific actions when the zoom factor has been changed. Implement a callback function performing these actions and assign it to the onZoomFactorChanged option. When implementing the function, use the object passed to it as the parameter. Fields of this object are described in the onZoomFactorChanged option description. Among these fields, you can find the updated zoom factor.

JavaScript
var vectorMapCfg = {
    // ...
    onZoomFactorChanged: function (info) {
        // specify required actions here
    }
};

Hovering

In the VectorMap widget, when a user hovers the mouse pointer over a map element (an area or a marker), this element changes its appearance. This state of the element is called "hovered state".

Of all map elements, only areas and markers can be in the hovered state. To learn how to configure their hover-related features, see the Area Hover and Marker Hover topics.

Additionally, an area or a marker in the hovered state can be accompanied by a tooltip, which displays descriptive information about the area or marker. For more information on how to configure tooltips, refer to the tooltip object description.

Show Example:
AngularJS
Knockout
jQuery

In this example, map areas and markers change their color to yellow with the red border when the mouse pointer hovers over them. This behavior is specified by the hoveredBorder and hoveredBorderColor options.

<div ng-controller="vectorMapController">
    <div style="height:400px; max-width:750px; margin: 0 auto" dx-vector-map="vectorMapCfg"></div>
</div>
var markerData = [
    { text: 'Sacramento', coordinates: [-121.2808, 38.3320] },
    { text: 'Austin', coordinates: [-97.75, 30.25] },
    { text: 'Albany', coordinates: [-73.7572, 42.6525] },
    { text: 'Tallahassee', coordinates: [-84.2533, 30.455] },
    { text: 'Springfield', coordinates: [-89.65, 39.783] },
    { text: 'Harrisburg', coordinates: [-76.8756, 40.2697] },
    { text: 'Columbus', coordinates: [-82.9833, 39.9833] },
    { text: 'Atlanta', coordinates: [-84.39, 33.755] },
    { text: 'Lansing', coordinates: [-84.5467, 42.7336] },
    { text: 'Raleigh', coordinates: [-78.6447, 35.8189] }
];

angular
    .module('myApp', ['dx'])
    .controller('vectorMapController', function ($scope) {
        $scope.vectorMapCfg = {
            layers: [{
                type: 'area',
                dataSource: '/Content/data/vectorMap-sources/usa.txt',
                hoveredColor: 'yellow',
                hoveredBorderColor: 'red'
            }, {
                type: 'marker',
                dataSource: markerData,
                hoveredColor: 'yellow',
                hoveredBorderColor: 'red'
            }],
            bounds: [-135, 60, -65, 20],
            zoomFactor: 1.5
        }
    });

angular.element(document).ready(function () {
   angular.bootstrap(document, ['myApp']);
});

In this example, map areas and markers change their color to yellow with the red border when the mouse pointer hovers over them. This behavior is specified by the hoveredBorder and hoveredBorderColor options.

<div style="height:400px; max-width:750px; margin: 0 auto" data-bind="dxVectorMap: vectorMapCfg"></div>
var markerData = [
    { text: 'Sacramento', coordinates: [-121.2808, 38.3320] },
    { text: 'Austin', coordinates: [-97.75, 30.25] },
    { text: 'Albany', coordinates: [-73.7572, 42.6525] },
    { text: 'Tallahassee', coordinates: [-84.2533, 30.455] },
    { text: 'Springfield', coordinates: [-89.65, 39.783] },
    { text: 'Harrisburg', coordinates: [-76.8756, 40.2697] },
    { text: 'Columbus', coordinates: [-82.9833, 39.9833] },
    { text: 'Atlanta', coordinates: [-84.39, 33.755] },
    { text: 'Lansing', coordinates: [-84.5467, 42.7336] },
    { text: 'Raleigh', coordinates: [-78.6447, 35.8189] }
];

var viewModel = {
    vectorMapCfg: {
        layers: [{
            type: 'area',
            dataSource: '/Content/data/vectorMap-sources/usa.txt',
            hoveredColor: 'yellow',
            hoveredBorderColor: 'red'
        }, {
            type: 'marker',
            dataSource: markerData,
            hoveredColor: 'yellow',
            hoveredBorderColor: 'red'
        }],
        bounds: [-135, 60, -65, 20],
        zoomFactor: 1.5
    }
};

ko.applyBindings(viewModel);

In this example, map areas and markers change their color to yellow with the red border when the mouse pointer hovers over them. This behavior is specified by the hoveredBorder and hoveredBorderColor options.

<div id="vectorMapContainer" style="height:400px; max-width:750px; margin: 0 auto"></div>
var markerData = [
    { text: 'Sacramento', coordinates: [-121.2808, 38.3320] },
    { text: 'Austin', coordinates: [-97.75, 30.25] },
    { text: 'Albany', coordinates: [-73.7572, 42.6525] },
    { text: 'Tallahassee', coordinates: [-84.2533, 30.455] },
    { text: 'Springfield', coordinates: [-89.65, 39.783] },
    { text: 'Harrisburg', coordinates: [-76.8756, 40.2697] },
    { text: 'Columbus', coordinates: [-82.9833, 39.9833] },
    { text: 'Atlanta', coordinates: [-84.39, 33.755] },
    { text: 'Lansing', coordinates: [-84.5467, 42.7336] },
    { text: 'Raleigh', coordinates: [-78.6447, 35.8189] }
];

$(function () {
    $('#vectorMapContainer').dxVectorMap({
        layers: [{
            type: 'area',
            dataSource: '/Content/data/vectorMap-sources/usa.txt',
            hoveredColor: 'yellow',
            hoveredBorderColor: 'red'
        }, {
            type: 'marker',
            dataSource: markerData,
            hoveredColor: 'yellow',
            hoveredBorderColor: 'red'
        }],
        bounds: [-135, 60, -65, 20],
        zoomFactor: 1.5
    });
});

Area Hover

Hover-related area settings reside in the layer configuration object. By default, areas already respond to hovering over them, so there is no need to specify any options. But if this feature is not required, assign false to the hoverEnabled field of the area layer.

JavaScript
var vectorMapCfg = {
    // ...
    layers: [{
        type: 'area',
        // ...
        hoverEnabled: false
    }]
};

If you did not switch the hovering off, specify the appearance of areas in the hovered state using the hoveredColor and hoveredBorderColor options. Both of them specify the color, only the former specifies it for areas, while the latter specifies it for area borders.

JavaScript
var vectorMapCfg = {
    // ...
    layers: [{
        type: 'area',
        // ...
        hoveredColor: 'blue', // paints areas blue in the hovered state
        hoveredBorderColor: 'red' // paints area borders red in the hovered state
    }]
};

Note that specified directly in the area layer, the hoveredColor and hoveredBorderColor options are applied to all map areas at once. If you need to set these options for a specific area, specify them within the object returned by the customize function. When implementing this function, use an Area object to identify the area. This object is accessible using the function's argument as well as using the this object.

JavaScript
var vectorMapCfg = {
    // ...
    layers: [{
        type: 'area',
        // ...
        hoveredColor: 'blue', // paints areas blue in the hovered state
        customize: function (elements) {
            $.each(elements, function (i, element) {
                if (element.attribute('name') == 'Kansas'
                    element.applySettings({ hoveredColor: 'green' }); // paints 'Kansas' green in the hovered state
            });
        }
    }]
};

Marker Hover

Hover-related marker settings reside in its layer configuration object. Map markers have all the same hovering options that map areas have: hoverEnabled switches the hovering on/off, hoveredColor and hoveredBorderColor specify the color of markers and their borders.

JavaScript
var vectorMapCfg = {
    // ...
    layers: [{
        type: 'marker',
        // ...
        hoverEnabled: true, // enables hovering (as hovering is enabled by default, may not be set)
        hoveredColor: 'blue', // paints markers blue in the hovered state
        hoveredBorderColor: 'red' // paints marker borders red in the hovered state
    }]
};

Being set directly in the marker layer, the color-specifying options are applied to all map markers at once. To set these options for a specific marker, specify them within the object returned by the customize function. When implementing this function, use a Marker object to identify the marker. This object is accessible using the function's argument as well as using the this object.

JavaScript
var vectorMapCfg = {
    // ...
    layers: [{
        type: 'marker',
        // ...
        hoveredColor: 'blue', // paints markers blue in the hovered state
        customize: function (elements) {
            $.each(elements, function (i, element) {
                if (element.attribute('text') == 'Memphis') {
                    element.applySettings({ hoveredColor: 'green' }); // paints 'Memphis' green in the hovered state
                }
            });
        }
    }]
};

Click Handling

VectorMap allows you to handle clicks on the map. The onClick function is called each time an end-user clicks the map.

The following subtopics explain how to implement a callback function for three click cases.

Area Click

To handle a click on a map area, implement a callback function and assign it to the onClick option. Inside the function, check whether a layer element was clicked and whether the layer type of the element is 'area'. When implementing this callback function, use the object passed to it as the parameter. Fields of this object are described in the onClick option description. Fields and methods of this object are documented in the Layer Element class description.

JavaScript
var vectorMapCfg = {
    // ...
    onClick: function (e) {
        var clickedElement = e.target;
        if (clickedElement != null && clickedElement.layer.type == "area") {
            // specify required actions here
        }
    }
};

Frequently, it is required that you select an area on a click. Learn how to implement this from the Implement Selection topic.

Marker Click

Handling a click on a marker and handling a click on an area are similar in nature. You need to implement a callback function and assign it to the onClick option. Inside the function, check whether a layer element was clicked and whether the layer type of the element is 'marker'. When implementing this callback function, use the object passed to it as the parameter. Fields of this object are described in the onClick option description. Fields and methods of this object are documented in the Layer Element class description.

JavaScript
var vectorMapCfg = {
    // ...
    onClick: function (e) {
        var clickedElement = e.target;
        if (clickedElement != null && clickedElement.layer.type == "marker") {
            // specify required actions here
        }
    }
};

Frequently, it is required that you select a marker on a click. Learn how to implement this from the Implement Selection topic.

Generic Click

When you need to handle any click on a map regardless of whether it was on an area or a marker, implement a callback function for the onClick option of the root configuration object. When implementing this function, use the object passed to it as the parameter. Fields of this object are described in the onClick option description. Among these fields, you can find an object that represents the jQuery event extended by the x and y fields. They contain the coordinates of the clicked point.

JavaScript
var vectorMapCfg = {
    // ...
    onClick: function (info) {
        // specify required actions here
    }
};

The X and Y coordinates are calculated relatively to the client area, i.e., the widget container. To convert them into map coordinates, use the convertCoordinates(x,y) method.

Show Example:
AngularJS
Knockout
jQuery

In this example, the coordinates of the clicked point are displayed below the map. Note that each clicked point is represented by a client area and geographical coordinates. The onClick function handling the click event accepts only client area coordinates. To convert them into geographical coordinates, the convertCoordinates(x,y) method is used.

<div ng-controller="vectorMapController">
    <div style="height:400px; max-width:750px; margin: 0 auto" dx-vector-map="vectorMapCfg"></div>
    <div class="textArea"><b>Clicked Point Coordinates</b></div>
    <div class="textArea" ng-bind="clientAreaCoordinates"></div>
    <div class="textArea" ng-bind="geographicalCoordinates"></div>
</div>
angular
    .module('myApp', ['dx'])
    .controller('vectorMapController', function ($scope) {
        $scope.clientAreaCoordinates = '';
        $scope.geographicalCoordinates = '';
        
        $scope.vectorMapInstance = {};
        $scope.vectorMapCfg = {
            layers: [{
                type: 'area',
                dataSource: '/Content/data/vectorMap-sources/usa.txt',
            }],
            bounds: [-118, 52, -80, 20],
            onClick: function (info) {
                var extEvent = info.jQueryEvent;
                $scope.clientAreaCoordinates = 'Client area coordinates: (' + extEvent.x.toPrecision(4) + ', ' + extEvent.y.toPrecision(4) + ')';
                
                var geogrCoords = $scope.vectorMapInstance.convertCoordinates(extEvent.x, extEvent.y);
                $scope.geographicalCoordinates = 'Geographical coordinates: (' + geogrCoords[0].toPrecision(4) + ', ' + geogrCoords[1].toPrecision(4) + ')'     ;
            },
            onInitialized: function (e) {
                $scope.vectorMapInstance = e.component;
            }
        }
    });

angular.element(document).ready(function () {
   angular.bootstrap(document, ['myApp']);
});
.textArea {
    height:20px;
    text-align:center;
    margin-top:5px
}

In this example, the coordinates of the clicked point are displayed below the map. Note that each clicked point is represented by a client area and geographical coordinates. The onClick function handling the click event accepts only client area coordinates. To convert them into geographical coordinates, the convertCoordinates(x,y) method is used.

<div style="height:400px; max-width:750px; margin: 0 auto" data-bind="dxVectorMap: vectorMapCfg"></div>
<div class="textArea"><b>Clicked Point Coordinates</b></div>
<div class="textArea" data-bind="text: clientAreaCoordinates"></div>
<div class="textArea" data-bind="text: geographicalCoordinates"></div>
var viewModel = {
    clientAreaCoordinates: ko.observable(),
    geographicalCoordinates: ko.observable(),
    
    vectorMapInstance: {},
    vectorMapCfg: {
        layers: [{
            type: 'area',
            dataSource: '/Content/data/vectorMap-sources/usa.txt',
        }],
        bounds: [-118, 52, -80, 20],
        onClick: function (info) {
            var extEvent = info.jQueryEvent;
            viewModel.clientAreaCoordinates('Client area coordinates: (' + extEvent.x.toPrecision(4) + ', ' + extEvent.y.toPrecision(4) + ')');
            
            var geogrCoords = viewModel.vectorMapInstance.convertCoordinates(extEvent.x, extEvent.y);
            viewModel.geographicalCoordinates('Geographical coordinates: (' + geogrCoords[0].toPrecision(4) + ', ' + geogrCoords[1].toPrecision(4) + ')');
        },
        onInitialized: function (e) {
            viewModel.vectorMapInstance = e.component;
        }
    }
};

ko.applyBindings(viewModel);
.textArea {
    height:20px;
    text-align:center;
    margin-top:5px
}

In this example, the coordinates of the clicked point are displayed below the map. Note that each clicked point is represented by a client area and geographical coordinates. The onClick function handling the click event accepts only client area coordinates. To convert them into geographical coordinates, the convertCoordinates(x,y) method is used.

<div id="vectorMapContainer" style="height:400px; max-width:750px; margin: 0 auto"></div>
<div class="textArea"><b>Clicked Point Coordinates</b></div>
<div class="textArea" id="clientAreaCoordinates"></div>
<div class="textArea" id="geographicalCoordinates"></div>
$(function () {
    $('#vectorMapContainer').dxVectorMap({
        layers: [{
            type: 'area',
            dataSource: '/Content/data/vectorMap-sources/usa.txt',
        }],
        bounds: [-118, 52, -80, 20],
        onClick: function (info) {
            var extEvent = info.jQueryEvent;
            $('#clientAreaCoordinates').html('');
            $('#clientAreaCoordinates').html('Client area coordinates: (' + extEvent.x.toPrecision(4) + ', ' + extEvent.y.toPrecision(4) + ')');
            
            var map = $('#vectorMapContainer').dxVectorMap('instance');
            var geogrCoords = map.convertCoordinates(extEvent.x, extEvent.y);
            $('#geographicalCoordinates').html('');
            $('#geographicalCoordinates').html('Geographical coordinates: (' + geogrCoords[0].toPrecision(4) + ', ' + geogrCoords[1].toPrecision(4) + ')');
        }
    });
});
.textArea {
    height:20px;
    text-align:center;
    margin-top:5px
}

Selection

To make your map more interactive, supply your map with the selection feature. In the VectorMap widget, an end-user may be able to select areas and markers. While selected, the appearance of an area or a marker differs from unselected ones. This appearance can be configured separately.

Selection is configured identically for areas and markers. Therefore, in the following subtopics, when both areas and markers are in question, they are referred to as "map elements" for brevity.

Show Example:
AngularJS
Knockout
jQuery

In this example, map areas and markers can be selected by a click. Their appearance in the selected state is specified by the selectedColor and selectedBorderColor options. Selection is executed in the multiple selection mode. In addition, when an area or a marker changes its selection state, a message notifying you about that appears under the map.

<div ng-controller="vectorMapController">
    <div style="height:400px; max-width:750px; margin: 0 auto" dx-vector-map="vectorMapCfg"></div>
    <div style="height: 25px; text-align: center; margin-top: 5px" ng-bind-html="text"></div>
</div>
var markerData = [{
    coordinates: [-121.2808, 38.3320], 
    attributes: { name: 'Sacramento' }
},{
    coordinates: [-97.75, 30.25], 
    attributes: { name: 'Austin' }
},{
    coordinates: [-73.7572, 42.6525], 
    attributes: { name: 'Albany' }
},{
    coordinates: [-84.2533, 30.455], 
    attributes: { name: 'Tallahassee' }
},{
    coordinates: [-89.65, 39.783], 
    attributes: { name: 'Springfield' }
},{
    coordinates: [-76.8756, 40.2697], 
    attributes: { name: 'Harrisburg' }
},{
    coordinates: [-82.9833, 39.9833], 
    attributes: { name: 'Columbus' }
},{
    coordinates: [-84.39, 33.755], 
    attributes: { name: 'Atlanta' }
},{
    coordinates: [-84.5467, 42.7336], 
    attributes: { name: 'Lansing' }
},{
    coordinates: [-78.6447, 35.8189],
    attributes: { name: 'Raleigh' }
}];

angular
    .module('myApp', ['dx'])
    .controller('vectorMapController', function ($scope) {
        $scope.text = '';
        $scope.vectorMapCfg = {
            layers: [{
                type: 'area',
                dataSource: '/Content/data/vectorMap-sources/usa.txt',
                selectionMode: 'multiple',
                selectedColor: 'yellow',
                selectedBorderColor: 'red'
            }, {
                type: 'marker',
                dataSource: markerData,
                selectionMode: 'multiple',
                selectedColor: 'orange',
                selectedBorderColor: 'purple'
            }],
            bounds: [-135, 60, -65, 20],
            zoomFactor: 1.5,
            onClick: function (info) {
                var clickedElement = info.target;
                if (clickedElement != null)
                    clickedElement.selected(!clickedElement.selected());
            },
            onSelectionChanged: function (info) {
                var selectedElement = info.target;
                if (selectedElement != null) {
                    var type = selectedElement.layer.type;
                    var isSelected = selectedElement.selected() ? 'selected' : 'deselected';
                    var name = selectedElement.attribute('name');
                    
                    $scope.text = 'The <b>' + name + '</b> ' + type + ' has been ' + isSelected;
                }
            }
        }
    });

angular.element(document).ready(function () {
   angular.bootstrap(document, ['myApp']);
});

In this example, map areas and markers can be selected by a click. Their appearance in the selected state is specified by the selectedColor and selectedBorderColor options. Selection is executed in the multiple selection mode. In addition, when an area or a marker changes its selection state, a message notifying you about that appears under the map.

<div style="height:400px; max-width:750px; margin: 0 auto" data-bind="dxVectorMap: vectorMapCfg"></div>
<div style="height: 25px; text-align: center; margin-top: 5px" data-bind="html: text"></div>
var markerData = [{
    coordinates: [-121.2808, 38.3320], 
    attributes: { name: 'Sacramento' }
},{
    coordinates: [-97.75, 30.25], 
    attributes: { name: 'Austin' }
},{
    coordinates: [-73.7572, 42.6525], 
    attributes: { name: 'Albany' }
},{
    coordinates: [-84.2533, 30.455], 
    attributes: { name: 'Tallahassee' }
},{
    coordinates: [-89.65, 39.783], 
    attributes: { name: 'Springfield' }
},{
    coordinates: [-76.8756, 40.2697], 
    attributes: { name: 'Harrisburg' }
},{
    coordinates: [-82.9833, 39.9833], 
    attributes: { name: 'Columbus' }
},{
    coordinates: [-84.39, 33.755], 
    attributes: { name: 'Atlanta' }
},{
    coordinates: [-84.5467, 42.7336], 
    attributes: { name: 'Lansing' }
},{
    coordinates: [-78.6447, 35.8189],
    attributes: { name: 'Raleigh' }
}];

var viewModel = {
    text: ko.observable(),
    vectorMapCfg: {
        layers: [{
            type: 'area',
            dataSource: '/Content/data/vectorMap-sources/usa.txt',
            selectionMode: 'multiple',
            selectedColor: 'yellow',
            selectedBorderColor: 'red'
        }, {
            type: 'marker',
            dataSource: markerData,
            selectionMode: 'multiple',
            selectedColor: 'orange',
            selectedBorderColor: 'purple'
        }],
        bounds: [-135, 60, -65, 20],
        zoomFactor: 1.5,
        onClick: function (info) {
            var clickedElement = info.target;
            if (clickedElement != null)
                clickedElement.selected(!clickedElement.selected());
        },
        onSelectionChanged: function (info) {
            var selectedElement = info.target;
            if (selectedElement != null) {
                var type = selectedElement.layer.type;
                var isSelected = selectedElement.selected() ? 'selected' : 'deselected';
                var name = selectedElement.attribute('name');
                
                viewModel.text('The <b>' + name + '</b> ' + type + ' has been ' + isSelected);
            }
        }
    }
};

ko.applyBindings(viewModel);

In this example, map areas and markers can be selected by a click. Their appearance in the selected state is specified by the selectedColor and selectedBorderColor options. Selection is executed in the multiple selection mode. In addition, when an area or a marker changes its selection state, a message notifying you about that appears under the map.

<div id="vectorMapContainer" style="height:400px; max-width:750px; margin: 0 auto"></div>
<div id="textArea" style="height: 25px; text-align: center; margin-top: 5px"></div>
var markerData = [{
    coordinates: [-121.2808, 38.3320], 
    attributes: { name: 'Sacramento' }
},{
    coordinates: [-97.75, 30.25], 
    attributes: { name: 'Austin' }
},{
    coordinates: [-73.7572, 42.6525], 
    attributes: { name: 'Albany' }
},{
    coordinates: [-84.2533, 30.455], 
    attributes: { name: 'Tallahassee' }
},{
    coordinates: [-89.65, 39.783], 
    attributes: { name: 'Springfield' }
},{
    coordinates: [-76.8756, 40.2697], 
    attributes: { name: 'Harrisburg' }
},{
    coordinates: [-82.9833, 39.9833], 
    attributes: { name: 'Columbus' }
},{
    coordinates: [-84.39, 33.755], 
    attributes: { name: 'Atlanta' }
},{
    coordinates: [-84.5467, 42.7336], 
    attributes: { name: 'Lansing' }
},{
    coordinates: [-78.6447, 35.8189],
    attributes: { name: 'Raleigh' }
}];

$(function () {
    $('#vectorMapContainer').dxVectorMap({
        layers: [{
            type: 'area',
            dataSource: '/Content/data/vectorMap-sources/usa.txt',
            selectionMode: 'multiple',
            selectedColor: 'yellow',
            selectedBorderColor: 'red'
        }, {
            type: 'marker',
            dataSource: markerData,
            selectionMode: 'multiple',
            selectedColor: 'orange',
            selectedBorderColor: 'purple'
        }],
        bounds: [-135, 60, -65, 20],
        zoomFactor: 1.5,
        onClick: function (info) {
            var clickedElement = info.target;
            if (clickedElement != null)
                clickedElement.selected(!clickedElement.selected());
        },
        onSelectionChanged: function (info) {
            var selectedElement = info.target;
            if (selectedElement != null) {
                var type = selectedElement.layer.type;
                var isSelected = selectedElement.selected() ? 'selected' : 'deselected';
                var name = selectedElement.attribute('name');
                
                $('#textArea').html('The <b>' + name + '</b> ' + type + ' has been ' + isSelected);
            }
        }
    });
});

Implement Selection

In a common scenario, a map element must become selected when a user clicks it. Selection in this scenario is implemented using the onClick callback function. For more information on handling the click event for map elements, refer to the Area Click and Marker Click topics. The following code shows how to enable a user to select/deselect map elements by a click.

JavaScript
var vectorMapCfg = {
    // ...
    onClick: function (info) {
        var clickedElement = info.target;
        if (clickedElement != null)
            clickedElement.selected(!clickedElement.selected());
    }
};

In this code snippet, the selected method of a map element is first called without arguments to obtain the current selection state. Then, the same method is called once more, this time with the reverted value of the selection state passed as the argument.

Set the Selection Mode

Selection can be conducted in single or multiple mode. In single mode, which is enabled by default, only one map area or marker can be in the selected state at a time. In multiple mode, several map areas or markers can be in the selected state at the same time. To specify the required mode, use the selectionMode option of a layer.

JavaScript
var vectorMapCfg = {
    // ...
    layers: [{
        // ...
        selectionMode: 'single' // 'multiple' | 'none'
    }]
};

In addition, you can use the selectionMode option to disable the selection capability. For this purpose, assign 'none' to this option.

Customize the Appearance

The appearance of map elements in the selected state can be customized using the selectedColor and selectedBorderColor options. Both of them specify the color, only the former specifies it of map elements, while the latter specifies it of their borders.

JavaScript
var vectorMapCfg = {
    // ...
    layers: [{
        // ...
        selectedColor: 'blue', // paints the layer blue in the selected state
        selectedBorderColor: 'red' // paints the layer borders red in the selected state
    }]
};

Note that specified directly in the layer configuration object, the selectedColor and selectedBorderColor options are applied to all map elements at once. If you need to set these options for a specific area or marker, specify them within the object returned by the customize function. When implementing this function, use an elements array to get all layer elements. This object is passed to the customize function as the argument.

JavaScript
var vectorMapCfg = {
    // ...
    layers: [{
        type: 'area',
        // ...
        selectedColor: 'blue', // paints areas blue in the selected state
        customize: function (elements) {
            $.each(elements, function (i, element) {
                if (element.attribute('name') == 'California') {
                    element.applySettings({ selectedColor: 'green' }); // paints 'California' green in the selected state
                }
            });
        }
    }, {
        type: 'marker',
        // ...
        selectedColor: 'blue', // paints markers blue in the selected state
        customize: function (elements) {
            $.each(elements, function (i, element) {
                if (element.attribute('text') == 'Memphis')
                    element.applySettings({ selectedColor: 'blue' });  // paints the 'Memphis' area in blue
            });
        }
    }],
};

Set Initial Selection

Map elements may appear selected when the map is loaded. To accomplish this, implement the customize function that must return an object with the isSelected field set to true for those areas or markers that must appear selected. The following code snippet provides an example of implementing this function.

JavaScript
var vectorMapCfg = {
    // ...
    layers: [{
        type: 'area',
        // ...
        selectedColor: 'blue', // paints areas blue in the selected state
        customize: function (elements) {
            $.each(elements, function (i, element) {
                if (element.attribute('name') == 'Ohio') {
                    element.applySettings({ isSelected: true }); // makes 'Ohio' appear selected
                }
            });
        }
    }, {
        type: 'marker',
        // ...
        selectedColor: 'blue', // paints markers blue in the selected state
        customize: function (elements) {
            $.each(elements, function (i, element) {
                if (element.attribute('text') == 'Detroit')
                    element.applySettings({ isSelected: true }); // makes 'Detroit' appear selected
            });
        }
    }],
};

Select in Code

To select a map element in code, use its selected(state) method. Calling the same method without arguments returns the current selection state of the map element.

To call the selected method, you need to obtain the Layer Element object. If you are calling this method from a click-handling function, it is not an issue, because these objects are passed there as the argument. But in case you need to call it outside this function, call the getLayers(), getLayerByName() or getLayerByIndex() method.

JavaScript
var areas = mapInstance.getLayerByName('myAreaLayer'); // gets the area layer
areas[0].selected(true); // selects the area with index 0
var markers = mapInstance.getLayerByName('myMarkerLayer'); // gets the markers layer
markers[0].selected(true); // selects the marker with index 0

You can also clear selection settings for all map elements simultaneously using the clearSelection() method.

JavaScript
mapInstance.clearSelection(); // deselects all areas and markers

Handle the Selection Change Event

When an layer element is selected/deselected, the function assigned to the onSelectionChanged option is invoked. This function accepts an object as the parameter. Among fields of this object, you can find the selected/deselected element .

JavaScript
var vectorMapCfg = {
    // ...
    onSelectionChanged: function (info) {
        // specify required actions here
    }
};

To identify whether a map element has been selected or deselected, use its selected() method inside the selection-handling function.