Ordering zIndex of series lines and bullets

This tutorial will show how you can control layout and ordering of LineSeries lines and their bullets.

Intro

Suppose we have a LineSeries with bullets. By default bullets are drawn on top of the actual lines.

Now, suppose we have several LineSeries - each with its own bullets. Some of the lines intersect with lines of other series. Some bullets overlap with bullets of other series. And even some of the lines cross bullets of other series.

In the above complicated scenario, no matter which order series are defined, and how their zIndex setting are set, bullets will always come on top of the lines.

This is done on purpose, as bullets are more indicative and possibly interactive than line segments.

On engine level it works in such way that bullets are placed in chart's bulletsContainer, while series/lines themselves are placed in chart's seriesContaniner, which has lower zIndex and thus is always drawn behind bulletsContainer.

Now that we know the under-the-hood details, let's see how we can change this and re-organize all of that the way we need.

All bullets behind lines

Let's turn the table - make all lines display above all bullets - by increasing the zIndex of seriesContainer:

chart.seriesContainer.zIndex = 10;
chart.seriesContainer.zIndex = 10;
{
  // ...
  "seriesContainer": {
    "zIndex": 10
  }
}

Mixed order of lines and bullets

Suppose the above approach does not work for us. We want bullets over its own series line, but behind lines of another series.

In this case, shuffling zIndex of seriesContainer and bulletsContainer won't help - one will always be in front of the other. We need some other solution.

And that solution is to move our bullets to the seriesContainer, so that layouting mechanism evaluates the order of drawing for all of those elements in the same space. In other words, bullets needs to become siblings of the lines within same container.

Luckily, it's easy to do.

Each series has a reference to its own container where it places its bullets, also called bulletsContainer.

IMPORTANT Here it's important not to confuse chart's and series' bulletsContainer. The two are different. Each series places its own bullets into its own bulletsContainer which in turn goes into chart's bulletsContainer.

Moving elements between containers is as easy as setting their parent property.

So, all we have to do is to set series' bulletsContainer parent to be seriesContainer.

series.bulletsContainer.parent = chart.seriesContainer;
series.bulletsContainer.parent = chart.seriesContainer;
{
  // ...
  "seriesContainer": {
    "id": "seriesContainer"
  },
  "bulletsContainer": {
    "parent": "seriesContainer"
  }
}

Now, if we run this chart, we'll see that later series lines overlap bullets of earlier series, but they do not overlap own bullets.

Mission accomplished.

Example

See the Pen amCharts 4: ordering lines and bullets in same zIndex space by amCharts team (@amcharts) on CodePen.