Plugin: Overlap Buster (experimental)

This tutorial will show how you can use OverlapBuster plugin (available since version 4.6.2) to make overlapping items such as bullets, map markers, or just about any other element "explode" to sides when hovered, for easy access to them

NOTE OverlapBuster is a plugin. For information about using plugins, refer to this article.

Disclaimer

Please read this, it's important!

OverlapBuster is an experimental plugin. We made it because we thought it might be useful and because it seemed like a fun exercise.

Although it has a bunch of configuration options, it is NOT GUARANTEED TO WORK for your particular chart situation. There are too many chaos factors involved when displaying scatter data without any particular grid-like structure, so it's impossible to account for all of them.

We did our best, and we'll continue looking into making this plugin better, but if you try it, and it does not work as expected, you need to accept a chance of possibility that it may not be for you after all.

Purpose

Sometimes elements on a chart or map overlap each other. This may cause some of them totally inaccessible, or event invisible, if they are being obstructed by some other element.

Some bullets/markers on above examples are hardly accessible or even visible, because they are being obstructed by other elements.

That's where OverlapBuster plugin comes into play.

Using the plugin, we can make clusters of closely packed items temporarily explode, giving each of them a bit more space and thus more possibility for a user to interact with them, e.g. hover or touch.

Using the plugin

Including the module

Before you can use this plugin you need to make sure you include it.

If you are using it in a TypeScript/ES6 application, you can import it as module. For pure JavaScript applications you'll need to include a .js vesion

import * as am4plugins_overlapBuster from "@amcharts/amcharts4/plugins/overlapBuster"; 
<script src="//cdn.amcharts.com/lib/4/plugins/overlapBuster.js"></script> 

Enabling

Before we can use the plugin, we need to do two things:

  1. Instantiate it on a chart object.
  2. Specify which a list of objects that will be checked against overlapping.

As with any add-on that follows plugin interface, we instantiate an object of plugin class and push it into target object's (in our case series) plugins list.

let overlap = chart.plugins.push(new am4plugins_overlapBuster.OverlapBuster());
overlap.targets.push(bullet);
var overlap = chart.plugins.push(new am4plugins_overlapBuster.OverlapBuster()); 
overlap.targets.push(bullet);
{
  // ...
  "plugins": [{
    "type": "OverlapBuster",
    "callback": function() {
      this.targets.push(this.target.series.getIndex(0).bullets.getIndex(0));
    }
  }]
}

As you may correctly figured out from the code snippet above, we specify what objects to check for overlapping by pushing them into plugin's targets list.

The beauty of it is that you can push anything there. For example, it's not limited to bullets from a single series - you can push bullets from all the series of the chart. They'll be checked against overlapping with each other.

Configuring

The plugin works out-of-the-box, without any configuration. However there are a few settings you can use to tweak its functionality.

SettingTypeDefaultComment
collapseDelaynumber500Number of milliseconds to keep cluster of elements exploded after they are no longer hovered.
revealRationumber0.7At least how much of each element's body must be cleared from overlapping.
The number is relative to actual size of the element. E.g. setting it to 1 will ensure that not a single pixel of each element overlap.
tolerancenumber2The bigger the number the bigger area around hovered element is checked for any overlapping.
The number is relevant to hovered item size.
Setting it to 1 (one) will affect elements that touch with the hovered element. Setting to 2 will check area twice the size of the hovered element, etc.

Overlap objects

In order for the plugin to be able to work properly, its target objects need to be measurable.

Most of the elements already are.

However, some of those, e.g. map images, are not. They should be be configured to be measured.

Below how you do it for MapImage in a MapImageSeries:

imageSeries.mapImages.template.layout = "absolute";
imageSeries.mapImages.template.isMeasured = true;
imageSeries.mapImages.template.layout = "absolute";
imageSeries.mapImages.template.isMeasured = true;
{
  // ...
  "series": [{
    "type": "MapImageSeries",
    // ...
    "mapImages": {
      "layout": "absolute",
      "isMeasured": true
    }
  }]
}

Now you can use imageSeries.mapImages.template as a proper target for OverlapBuster.

Examples

XYChart

See the Pen amCharts 4: OverlapBuster (XYChart) by amCharts team (@amcharts) on CodePen.

MapChart

See the Pen amCharts 4: OverlapBuster (MapChart) by amCharts team (@amcharts) on CodePen.