Skip to content

Maps

ChartFactor has two types of maps: Vector Maps that are good for representing fixed regional information such as metrics about countries, provinces, etc. and is provided in the standard visualizations package, and Geo Maps that are good at representing information with high geospatial precision such as points, polygons, making use of of custom markers, etc. and is provided in the geo visualization package.

Vector Map

To define a Vector Map that shows the life expectancy of the world population by countries we must write the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    var metrics = [];
    var metric = cf.Metric('Life_expectancy', 'avg');
    var count = cf.Metric('count');

    // define attribute to group by
    var groups = [];
    var group = cf.Attribute('Country')
                    .limit(1000)         // The limit should be higher than the number of regions
                    .sort('desc', metric);

    metrics.push(metric);
    metrics.push(count);
    groups.push(group);

    var color = cf.Color();
    color.metric(metric)

    let myMap = cf.provider('Elasticsearch')
                    .source('life_expectancy_region')
                    .groupby(...groups)   // Is mandatory group by the region
                    .metrics(...metrics)
                    .set('shape', 'world')  // The 'map' or 'shape' to be used could be a string ej. 'world', 'usa' or a geojson with the shape
                    .set('color', color)
                    .graph('Vector Map')
                    .element('chart')
                    .execute();

Note

To set the map shape we recommend use shape, map is a legacy property that will be removed in the next major release.

The previous code will render a Vector Map like the one below: world vector map There are two maps available out of the box:

  • "world" - the world map
  • "usa" - the map of the United States by state

Custom Areas

ChartFactor Vector Maps support custom areas in GeoJson format. Here is an example of how to inject other maps, in this case Australia and use Custom Data:

1
2
3
4
5
6
7
8
9
    var metric = cf.Metric('Population');
    var australiaShape = // Australia GeoJson object
    var data = // Custom Data

    let myChart = cf.create()
                    .data(data)                       // Set custom data
                    .set('shape', australiaShape)       // Set map as GeoJson object
                    .graph('Vector Map')
                    .element('chart');

If you want see the full demo click here.

The previous code will render the following map: australia

Geo Map

Initialization

The Geo Map needs access to several external libraries that are included automatically when a Geo Map visualization is used. They are loaded from their default location. If the data application does not have extranet access however, you can specify an alternate location to load these resources. The table below shows the Geo Map dependencies.

Vairable Default Url
leafletLibUrl https://unpkg.com/leaflet@1.3.4/dist/leaflet.js
leafletCssUrl https://unpkg.com/leaflet@1.3.4/dist/leaflet.css
leafletClusterUrl https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js
leafletClusterCssUrl https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css
leafletClusterCssDefaultUrl https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css

Define the global variables above to update the location of these resources. The following example shows how to inject the location of a Geo Map dependency:

1
2
3
4
    <script>
        window.leafletLibUrl = 'https://unpkg.com/leaflet@1.3.4/dist/leaflet.js';
    </script>
    <script src="../../lib/CFToolkit.min.js"></script>

Markers

ChartFactor supports Geo Maps that render markers in specific latitudes and longitudes. Two types of queries are supported:

  • Agregate metrics arround a point (lat, lng) and an attribute. In this case, one marker represents one or many events happening on the marker location and the attribute value. Use the rows() function to specify the latitute, longitude, and additional attribute to group by. Note that the default limit for this query is 1000. Use the .limit(x) function to change this default.

  • Raw query that includes latitude, longitude, and any other fields. In this case, each marker represents a single event. Multiple events on the same location will render multiple markers. Use the fields() function to specify all the attributes the marker should include in its tooltip. Note that the default limit for this query is 100. Use the .limit(x) function to change this default.

In the example below, we have Geo Map Markers from the Chicago Taxi Trip datasource with an aggregate query with the pickup_latitude and pickup_longitude, also gruped by company and colored by the fare metric.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    var metrics = [
        cf.Metric('fare', 'sum'),
        cf.Metric('count')
    ];

    let myChart = cf.provider('Elasticsearch')
        .source('chicago_taxi_trips')
        .rows('pickup_latitude', 'pickup_longitude', 'company')
        .metrics(metrics)
        .set('zoom', 12)
        .set('center', [42.149151, -87.807541])
        .set('min', 0)
        .set('max', 20)
        .limit(100)  // 1000 by default 
        .graph('Geo Map')
        .element('chart')
        .execute();

The previous code will render a Geo Map like the one below: geo map markers

Custom Markers

To define a Geo Map custom marker you have to define a function that accepts the color of the marker and produces a css style like follow example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
let markerHtmlStyle = (color) => {
    return `
        background-color: ${color};
        width: 30px;
        height: 30px;
        display: block;
        left: -15px;
        top: -12px;
        position: relative;
        transform: rotate(45deg);
        border: 1px solid #FFFFFF;
        `;
};

let myChart = cf.provider('Elasticsearch')
    .source('chicago_taxi_trips')
    .fields('pickup_latitude', 'pickup_longitude', 'company')
    .set('zoom', 12)
    .set('center', [41.877741, -87.637939])
    .set('minZoom', 3)
    .set('markerHtmlStyle', markerHtmlStyle)
    .set('layersControl', true)
    .set('ignoreCords', [0,0])
    .set('legend', 'right')
    .graph('Geo Map')
    .element('chart')
    .execute();

The previous code will render a Geo Map like the one below: geo map markers

Shapes (GeoJSON)

The following example renders a Geo Map with shapes for the different drop-off community areas in Chicago (taken from the Chicago Taxi Trips dataset):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
    var metrics = [
        cf.Metric('fare', 'sum'),
        cf.Metric('count')
    ];

    let color = cf.Color();

    color.metric(metrics[0]);
    color.palette(['#ccece6', '#99d8c9', '#66c2a4', '#41ae76', '#238b45', '#006d2c', '#00441b']);

    let myChart = cf.provider('Elasticsearch')
        .source('chicago_taxi_trips')
        .rows('dropoff_community_area_desc')
        .metrics(metrics)
        .set('shape', chicagoShape)
        .set('color', color)
        .graph('Geo Map')
        .element('chart');
        .execute();

The two requirements to render this visualization are: Provide the attribute to group by using the rows() function. In the example above, the attribute is dropoff_community_area_desc. Provide the shape file using the .set('shape', chicagoShape) function. The shape file must be in GeoJSON format.

Note that the default limit for this query is 1000. Use the .limit(x) function to change this default.

Each shape will be colored depending on the color metric values (e.g. fare). The color metric is the metric defined in the cf.Color() object or the first metric in the metrics array if no Color object is defined.

The previous code will render a Geo Map like the one below: geo map shapes

Custom Configurations for Maps

  1. enableZoom: Enables or disables the zoom and pan on the map. Example: .set('enableZoom', false). Zoom is enabled by default.
  2. zoom: Sest the initial zoom value of the map. Example: .set('zoom', 0.5). (1 by default)
  3. center: Sets the initial center of the map. Example: .set('center', [0,0]). It is null by default which translates to the center of the shape.
  4. showNameOnHover (Vector Map only): Set if the map should display the region name when the mouse goes over the region Example: .set('showNameOnOver', true). It is false by default.
  5. layersControl (Geo Map only): Turns the layer control on or off. Example: .set('layersControl', false). It is true by default.
  6. ignoreCords (Geo Map only): Ignore markers when they match a specified location. Example: .set('ignoreCords', [0, 0]). None by default. This is useful when the dataset includes invalid points as 0,0 for example.
  7. maxZoom and minZoom (Geo Map only): Set the max and min zoom levels. Example: .set('maxZoom', 10). Default maxZoom is 18 and default minZoom is 0.
  8. markerHtmlStyle (Geo Map only): this a function that receives a color parameter and should return a string that represent a css style to be aplied to the marker.

Listening To Custom Map Events

ChartFactor Toolkit Maps have special events to which you can subscribe to obtain current zoom information or the position where the map is located, here are some examples.

1
2
3
4
5
6
7
    myChart.on('mapzoom', (x)=>{
        console.log("Current map zoom: ", x.data);
    });

    myChart.on('mapmove', (x)=>{
        console.log("Current map center: ", x.data);
    });