DevExtreme Angular - Providing Data

This topic goes over different approaches to providing data for the dxVectorMap widget. In case of this widget, providing data presumes specifying data sources for map areas and markers.

Data for Areas

To provide data for areas, follow one of these approaches.

Using a Script

DevExtreme is shipped with a number of predefined data sources for the VectorMap widget. You can find these sources as .js-scripts in the Lib/js/vectormap-data folder of your DevExtreme package. Each data source contains an array describing a geographical territory. The following territories are available.

  • World (world.js)
  • Africa (africa.js)
  • Canada (canada.js)
  • Eurasia (eurasia.js)
  • Europe (europe.js)
  • USA (usa.js)
NOTE
Built-in maps were not created by DevExpress. They were taken from a free map data provider and converted to the VectorMap format with the parse() method. Refer to the Using a Binary Source section to learn how to display a custom map with the VectorMap widget.

To use one of these sources on your map, reference the corresponding file in the head of your HTML document. Note that this file should be referenced after the ChartJS library file (see topics in the Installation section).

HTML
<!DOCTYPE html>
  <html>
      <head>
          <meta charset="utf-8" />
          <!-- libraries required by DevExtreme go here -->
          <script type="text/javascript" src="js/dx.viz.js"></script>
          <script type="text/javascript" src="js/vectormap-data/world.js"></script>
      </head>
  </html>

Alternatively, the same data sources can be accessed and referenced using the DevExpress CDN.

HTML
<script type="text/javascript" src="https://cdn3.devexpress.com/jslib/18.2.18/js/vectormap-data/world.js"></script>
<script type="text/javascript" src="https://cdn3.devexpress.com/jslib/18.2.18/js/vectormap-data/africa.js"></script>
<script type="text/javascript" src="https://cdn3.devexpress.com/jslib/18.2.18/js/vectormap-data/canada.js"></script>
<script type="text/javascript" src="https://cdn3.devexpress.com/jslib/18.2.18/js/vectormap-data/eurasia.js"></script>
<script type="text/javascript" src="https://cdn3.devexpress.com/jslib/18.2.18/js/vectormap-data/europe.js"></script>
<script type="text/javascript" src="https://cdn3.devexpress.com/jslib/18.2.18/js/vectormap-data/usa.js"></script>

After that, set the data option for a layer to the array defined in the referenced file.

JavaScript
var vectorMapCfg = {
    // ...
    layers: [{
        type: 'area',
        dataSource: DevExpress.viz.map.sources.world
        // dataSource: DevExpress.viz.map.sources.africa
        // dataSource: DevExpress.viz.map.sources.canada
        // dataSource: DevExpress.viz.map.sources.eurasia
        // dataSource: DevExpress.viz.map.sources.europe
        // dataSource: DevExpress.viz.map.sources.usa
        // ...
    }, {
        // ...
    }]
}

Using a JSON object

If you have your data as a JSON object, assign its URI to the layers.dataSource option. This way, no other actions will be required.

JavaScript
var vectorMapCfg = {
    // ...
    layers: [{
        type: 'area',
        dataSource: '/Content/data/vectorMap-sources/usa.json'
        // ...
    }, {
        // ...
    }]
}

The JSON object used as a data source can be in the GeoJSON format. In such a case, this object should be a feature collection. Note that only the Polygon and MultiPolygon geometries are supported by the VectorMap widget. Properties of a GeoJSON object can be accessed using the layer's attributes(name) method.

Using a Binary Source

The VectorMap widget can also receive data for areas from a binary source. Usually, this source comes as a shapefile. Files of this format describe vector features that represent various geographical objects. VectorMap can receive shape coordinates from an .shp file and attributes from a .dbf file. Note that only polygon and polyline geometries can be used in a data source for the VectorMap widget.

There are two approaches to using a binary source as a data source for VectorMap.

Web Approach

NOTE
To use this approach, your web browser must support the DataView interface.

Reference an additional script in the head of your HTML document as follows. This script can be found in the Lib/js/vectormap-utils folder of your DevExtreme package.

HTML
<!DOCTYPE html>
  <html>
      <head>
          <meta charset="utf-8" />
          <!-- libraries required by DevExtreme go here -->
          <script type="text/javascript" src="js/dx.viz.js"></script>
          <script type="text/javascript" src="js/vectormap-utils/dx.vectormaputils.js"></script>
      </head>
  </html>

The referenced script contains the parse() method for parsing a binary source into the format supported by the VectorMap widget. There are two possible ways of using this method.

  • Using a Shapefile
    If you can access a required shapefile using the XMLHttpRequest, use the following construction.

    JavaScript
    DevExpress.viz.vectormaputils.parse('/shapeSources/world', { precision: 2 }, function (data) {
        $('#mapContainer').dxVectorMap({
            layers: [{
                type: 'area',
                dataSource: data
            }]
        });
    });

    In this code, the function's first argument specifies the URI of the source. Note that the file extension is omitted. In this case, both the world.shp and world.dbf files will be parsed. Add the .shp or .dbf extension if you need to parse a certain file. The second argument specifies the precision of the resulting shape coordinates. Within the callback function, which comes as the third argument, the resulting coordinates are assigned to the layer.dataSource option of the VectorMap widget.

  • Using Data from an ArrayBuffer Source
    The parse() method can also parse any source of the ArrayBuffer type. You can get a source of this type, for instance, by sending a request and specifying 'arraybuffer' as a response type.

    JavaScript
    var request = new XMLHttpRequest();
    request.open('GET', '/shapeSources/world.shp');
    request.responseType = 'arraybuffer';
    request.addEventListener('load', function () { 
        if (this.readyState === 4) {
            // shpArrayBuffer = this.response
        }
    });
    request.send(null);
    //Send a request for a .dbf file analogously 

    The following code demonstrates how to parse data of the 'arraybuffer' type and assign it as the dataSource field of the area layer.

    JavaScript
    var parseSources = { shp: shpArrayBuffer, dbf: dbfArrayBuffer },
        parseOptions = { precision: 2 },
    var data = DevExpress.viz.vectormaputils.parse(parseSources, parseOptions);
    
    $('#mapContainer').dxVectorMap({
        layers: [{
            type: 'area',
            dataSource: data
        }]
    });

    In this code, the parse(parseSources, parseOptions) method transforms the sources specified by the parseSources object into the format supported by VectorMap. Shape coordinates are converted with a precision specified by the parseOptions object.

The resulting shape coordinates can be accessed using the features field of the object returned by the parse() method or the object passed to the callback function. A particular shape attribute can be accessed by its name using the attribute(name) method of a map area.

Node.js Approach

If you develop using the Node.js platform, utilize a special script allowing you to parse binary sources and generate VectorMap-compatible files from them. This script can be found in the Lib/js/vectormap-utils folder of your DevExtreme package. Load this script as a module using the following code.

JavaScript
var vectormaputils = require('./dx.vectormaputils.node.js');

The next two subtopics describe the parsing and generating operations in details.

Parsing

There are two possible ways to parse binary data for VectorMap.

  • Using a Shapefile
    If you can access a required shapefile, use the following construction.

    JavaScript
    vectormaputils.parse('/shapeSources/world', { precision: 2 }, function (data) {
        $('#mapContainer').dxVectorMap({
            layers: [{
                type: 'area',
                dataSource: data
            }]
        });
    });

    In this code, the function's first argument specifies the URI of the source. Note that the file extension is omitted. In this case, both the world.shp and world.dbf files will be parsed. Add the .shp or .dbf extension if you need to parse a certain file. The second argument specifies the precision of the resulting shape coordinates. Within the callback function, which comes as the third argument, the resulting coordinates are assigned to the layer.dataSource option of the VectorMap widget.

  • Using Data from a Buffer Source
    The following code sample demonstrates how to use the parse() method for parsing data from any source of the Buffer type.

    JavaScript
    var parseSources = { shp: shpBuffer, dbf: dbfBuffer },
        parseOptions = { precision: 2 },
    var data = vectormaputils.parse(parseSources, parseOptions);
    
    $('#mapContainer').dxVectorMap({
        layers: [{
            type: 'area',
            dataSource: data
        }]
    });

    In this code, the parse(parseSources, parseOptions) method transforms the sources specified by the parseSources object into the format supported by VectorMap. Shape coordinates are converted with a precision specified by the parseOptions object.

No matter the way, the resulting shape coordinates can be accessed using the features field of the object returned by the parse() method or the object passed to the callback function. A particular shape attribute can be accessed by its name using the attribute(name) method of a map area.

Generating

In addition, you can generate VectorMap-compatible files from shapefiles to use them as a data source afterwards. For this purpose, use the processFiles(source, options) method.

JavaScript
var source = 'shapeSources/world.shp',
    options = {
        output: 'destinationFolder',
        precision: 2,
        isJSON: true
    };

vectormaputils.processFiles(source, options);

This method accepts the URI of the source shapefile as the first argument. When a folder (instead of a file) is passed as the first argument, all shapefiles from this folder will be processed.

The processFiles(source, options) method accepts processing options as the second argument. These options include:

  • output string
    Specifies a destination folder. This folder should be created in advance. When this option is not specified, the resulting file is placed in the folder where its source shapefile is located.

  • precision numeric
    Specifies a precision for shape coordinates. By default, no precision applies.

  • isJSON boolean
    Specifies the format of the resulting file. When this option is set to true, the resulting file has the '.json' extension and can be used in VectorMap as a JSON object. When this option is set to false, the resulting file has the '.js' extension and can be used in VectorMap as a script.

You can use the Node.js console for generating files as well. The accepted string has the following format.

node dx.vectormaputils.node.js Source [--output DestinationFolder] [--precision Precision] [--json]

To receive help on the parameters, type the following string in the console.

node dx.vectormaputils.node.js --help

Data for Markers

To provide data for map markers, assign an array of objects to the dataSource option of a corresponding layer. For any marker type, each object of the markers array must contain the coordinates field, which must be assigned to an array of two values: the first is the longitude and the second is the latitude of a map marker.

Optionally, you can specify the attributes field to store additional information for each marker there. Depending on the marker elementType used, the attributes object may contain different fields.

JavaScript
var markersArray = [{
    coordinates: [-121.2808, 38.3320],
    attributes: { text: 'Sacramento' }
}, {
    coordinates: [-97.75, 30.25],
    attributes: { text: 'Austin' }
}];

var vectorMapCfg = {
    // ...
    layers: [{
        type: 'marker',
        dataSource: markersArray
    }, {
        // ...    
    }]
}

The code above is sufficient for configuring markers of the dot type. For markers of other types, you need to specify several additional fields.

If you use markers of the bubble type, add a numeric field to each object in the markers array. The value of this field will define the size of the bubble marker. Then, assign this field to the marker layer using the dataField option.

JavaScript
var markersArray = [{
    coordinates: [-121.2808, 38.3320],
    attributes: {
        text: 'Sacramento',
        value: 10
    }
}, {
    coordinates: [-97.75, 30.25],
    attributes: {
        text: 'Austin',
        value: 7
    }
}];

var vectorMapCfg = {
    // ...
    layers: [{
        type: 'marker',
        dataSource: markersArray,
        elementType: 'bubble',
        dataField: 'value'
    }, {
        // ...    
    }]
}

To configure markers of the pie type, provide an additional field to each object in markersArray. This field must contain an array of values that define the slices of a pie marker. Then, assign this field to the marker layer using the dataField option.

JavaScript
var markersArray = [{
    coordinates: [-121.2808, 38.3320],
    attributes: {
        text: 'Sacramento',
        values: [9, 5, 14]
    }
}, {
    coordinates: [-97.75, 30.25],
    attributes: {
        text: 'Austin',
        values: [10, 2, 3]
    }
}];

var vectorMapCfg = {
    // ...
    layers: [{
        type: 'marker',
        dataSource: markersArray,
        elementType: 'pie',
        dataField: 'values'
    }, {
        // ...    
    }]
}

Moreover, you can use custom images as map markers. To do this, supply each object in the markers array with a field that contains the URL of the image. After that, assign this field to the marker layer using the dataField option.

JavaScript
var markersArray = [{
    coordinates: [-121.2808, 38.3320],
    attributes: {
        text: 'Sacramento',
        url: 'images/myimage1.jpg'
    }
}, {
    coordinates: [-97.75, 30.25],
    attributes: {
        text: 'Austin',
        url: 'images/myimage2.jpg'
    }
}];

var vectorMapCfg = {
    // ...
    layers: [{
        type: 'marker',
        dataSource: markersArray,
        elementType: 'image',
        dataField: 'url'
    }, {
        // ...    
    }]
}

You can also specify a data source for markers from a JSON object. For this purpose, assign the URL of this object to the dataSource option.