Introduction

You can use KeyLines with Leaflet.js to visualise and analyse geospatial data on a map.

Leaflet provides a map to use as a background. Instead of running a layout, KeyLines will lay out your chart onto the map according to the latitude and longitude locations of your nodes.

The available map functions and map options are documented in the API Reference.

See also the Insurance Fraud Analysis, Leaflet Integration and Using Images with Leaflet demos for examples of visualising geospatial data.

Using KeyLines with Leaflet

If you want to plot your chart onto a map, you need to make sure Leaflet.js is loaded into the page before showing the map.

You can include the leaflet.js JS bundle and leaflet.css stylesheet in your app as HTML tags:

<head>
  <link rel="stylesheet" type="text/css" href="path/to/leaflet.css"/>
  <script type="text/javascript" src="path/to/leaflet.js"></script>
</head>

Alternatively, you can include the JS bundle and stylesheet using a bundler such as Webpack.

To display the map in the background, call the show() function:

chart.map().show();

When a map is shown, nodes are laid out according to the lat (latitude) and lng (longitude) properties in the pos object. Nodes without geospatial data aren't drawn on the map.

let data = {
  type: 'LinkChart',
  items: [
    {
      id: 'node1',
      type: 'node',
      c: '#43976C',
      pos: { lat: 52.19794, lng: 0.12822 },
    },
  ],
};

You can customise various options by calling chart.map().options():

chart.map().options({ animate: false })     // plots the chart onto a map without animation
 .then(chart.map().show());

If you don't set the backColour or gradient chart options, the map will use Leaflet's default background colour (light grey) behind the tiles.

As Leaflet controls the chart background, some of the view controlling APIs cannot be used. See Special behaviour for more details.

If KeyLines detects a Leaflet version older than 1.3.4, it'll throw an exception and the map won't be drawn.
If a version between 1.3.4 - 1.8.0 is found, KeyLines draws the map and generates a warning in the developer console.
For versions 1.9.x, KeyLines draws the map. Newer versions may not have been tested but should function regardless.

Map layers

KeyLines integrates with Leaflet by adding its own tile, overlay and control layers. To set any options defined in the Leaflet API, use the leaflet property in chart.map().options().

To manipulate Leaflet directly, call chart.map().leafletMap(), which returns an object of type L.map. You can use this to listen for map events and attach them to handler functions:

chart.on('view-change', () => {
  const zoom = chart.map().leafletMap().getZoom();
  chart.setProperties({ id: '.', e: Math.pow(zoom / 14, 2) }, true);
});

Read more about L.map in the relevant version of the Leaflet API Reference.

Map tiles

Map tiles are managed by the Leaflet library and configured by KeyLines. You can use any tile provider you like, as is demonstrated in the Map tiles examples above.

To configure the tile layer, set the tiles property in chart.map().options():

chart.map().options({
  tiles: {
    id: 'tiles-open',
    url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
    attribution: '© OpenStreetMap',
    src: '/im/mapbasics/openstreetmap.png',
    noWrap: true
  }
});

If you don't specify a template in the url property, KeyLines will use OpenStreetMap as a default tile provider. If you don't want to create a tile layer, set tiles to null.

By default, map tiles wrap around the world. This means you won't display the edges of the map tiles, so you can see Asia to the west of Europe if you pan far enough. To disable the wrapping of map tiles, set the noWrap Leaflet property to true in the tiles property.

If you reference a map tile URL or object that's on a different domain to KeyLines, your browser will display it, but KeyLines won't be able to render it to a data URL. See Cross-Origin Images (CORS) for more info.

View changes

You can limit pan boundaries and zoom levels using the maxBounds, minZoom and maxZoom Leaflet properties on the Leaflet object, for example:

const southwest = [42.2, -71.3];
const northeast = [42.5, -70.9];
chart.map().options({
  leaflet: {
    maxBounds: [southwest, northeast],    //  restricts the view to an area
    maxZoom: 18,                          //  limit for zooming in
    minZoom: 10                           //  limit for zooming out
  }
});

You may also want to configure zoom behaviour using the zoomSnap Leaflet property, as shown in our Use Images with Leaflet demo. Leaflet will snap the zoom to the nearest integer - but note that this can be restrictive if you have limited the viewport.

Read more about maxBounds, minZoom, maxZoom and zoomSnap in the relevant version of the L.map options documentation in the Leaflet API Reference.

Leaflet supports additional functionality through plugins which you can add directly to the Leaflet map. Note that KeyLines integration is not tested against third party Leaflet plugins.

Events

KeyLines, Leaflet and any map overlays you add all have their own events systems. Usually, the KeyLines events will fire first, then the overlays and finally the Leaflet events.

Most interaction behaviour will require combining the information from all these events to work out how the user has interacted with the chart.

We recommend using the Leaflet events to trigger your functions and storing any data from KeyLines or overlay events to use once all the events have returned.

When using your own custom DOM elements such as tooltips, annotations or context menus, make sure that your HTML elements have a z-index value higher than 1000. This ensures they always appear on top of the chart and can be interacted with.

Converting Latitude and Longitude to View Coordinates

You can convert latitude and longitude coordinates to view coordinates by accessing the L.latLng Leaflet API:

const latLng = L.latLng(lat, lng);
chart.map().leafletMap().getBounds().contains(latLng);

Read more about L.latLng in the relevant version of the Leaflet API Reference.

Special Behaviour

Some KeyLines functionalities are different when a map is used:

  • Annotations are not shown on a Leaflet map.
  • Links are always shown as direct links.
  • Nodes cannot be dragged from their geographic positions.
  • When the map is shown, handMode is automatically set to true.
  • Combos cannot be open. Any open combos are closed when the map is shown.
  • If you drag the map with hand mode enabled, returning from the drag handlers won't affect the drag action.
  • By default, Leaflet will zoom the chart in on a double-click (or double-tap). To disable this, set this in Leaflet directly:
chart.map().leafletMap().doubleClickZoom.disable()

    Be aware of the following restrictions on chart API functions while the map is shown:

    arrange()Not supported. Open combos are closed in maps and will be reopened when the network is shown again.
    combo().combine()Setting the open property in the combo definition has no effect.
    combo().open()  |  combo().close()Not supported. Open combos are closed in maps and will be reopened when the network is shown again.
    combo().transfer()  |  combo().arrange()The arrangement of the items inside the combo may not be optimal when the network is shown and combo is reopened.
    createLink()Not supported.
    export()
    • The extents option is ignored and KeyLines always generates the on-screen view of the chart.
    • The fitTo option is ignored and the output size always corresponds to the size of the on-screen view.
    • For PDF export, if the on-screen view is larger than the size of the generated PDF, it is scaled to fit the size of the PDF.
    • The image may not include items from some custom Leaflet layers, including markers and shadows.
    load()Loading chart data after calling chart.map().show() clears any existing map and reverts to a network. Load the chart data before showing a map or use merge() to load the data.
    layout()Not supported. Nodes are laid out according to their latitude and longitude.
    options()Do not change bands, overview or watermark.
    pan()Not supported. Pan the chart by accessing the flyTo method for L.map directly. See the relevant version of the Leaflet API Reference.
    merge()  |  setItem()Do not use to set x or y properties.
    setProperties()  |  animateProperties()Do not use to set x or y properties, or use regular expressions to set lat or lng properties.
    show()Should only be used to show nodes that have a pos object with lat and lng properties.
    toDataURL()
    • The fit option is ignored and KeyLines always generates the on-screen view of the chart.
    • The width and height parameters are ignored.
    • The image may not include items from some custom Leaflet layers, including markers and shadows.
    viewOptions()Do not call with arguments to update the view settings. See View Changes for more details.
    zoom()Do not specify the time option. Customise the animation time by accessing the flyTo method for L.map directly. See the relevant version of the Leaflet API Reference.