Chartjs Datasets overlapping and z-index
Asked Answered
P

2

11

I have the below Chart implemented using chart.js version 3.x.

https://jsfiddle.net/Lxya0u98/12/

I have multiple datasets in my charts to achieve the behavior I want.

I am facing an issue with the datasets overlapping. In the chart, I have end of the blue color line overlapping with the green color dot dataset. Is there a way to avoid this issue?

I have the below two datasets:

// Data set for the Big Dot
{
   showLine: false,
   borderWidth: 0,
   lineTension: 0,
   borderColor: colorVal,
   backgroundColor: colorVal,
   pointBackgroundColor: colorVal,
   pointBorderColor: colorVal,
   pointBorderWidth: 2,
   pointRadius: 15,
};

// Data set for the Connecting Lines
{
   showLine: true,
   lineTension: 0,
   borderWidth: 5,
   borderColor: colorVal,
   pointRadius: 0,
   pointBorderWidth: 0,
   spanGaps: true,
};

Is there a Z-Index for the Datasets so that they appear on top of the previous one in the stack?

Pipkin answered 24/12, 2020 at 10:30 Comment(0)
L
21

The option dataset.order has similar effect as the z-index.

  • Datasets with higher order are drawn first
  • Datasets with no or lower order are drawn last, hence appear on top

Therefore, adding order: 1 to your line datasets should solve the problem.

var newDataLine = {
  ...
  order: 1
};
Lemire answered 26/12, 2020 at 8:22 Comment(2)
I was also searching in the documentation but I was not able to find it. It will be helpful if you can post the link to the documentation.Pipkin
In my answer, dataset.order is already linked to the corresponding section in the documentation.Lemire
L
2

Instead of defining multiple datasets, you could proceed as follows:

  • First convert your line chart into a scatter chart.
  • Then draw the lines directly on the canvas using the Plugin Core API. The API offers a range of hooks that may be used for performing custom code. You can use the beforeDraw hook to draw connection lines of different colors between data points and to the open end of the chart.

Note that you have to define xAxes.ticks.max in order to obtain the open end line at the right of the chart.

Please take a look at below runnable code snippet and see how it works.

new Chart('line-chart', {
  type: "scatter",
  plugins: [{
    beforeDraw: chart => {
      var ctx = chart.chart.ctx;
      ctx.save();
      var xAxis = chart.scales['x-axis-1'];
      var yAxis = chart.scales['y-axis-1'];
      var dataset = chart.data.datasets[0];
      var y = yAxis.getPixelForValue(0);
      dataset.data.forEach((value, index) => {
        var xFrom = xAxis.getPixelForValue(value.x);
        var xTo;
        if (index + 1 < dataset.data.size) {
          xTo = xAxis.getPixelForValue(dataset.data[index + 1].x);
        } else {
          xTo = xAxis.right;
        }        
        ctx.strokeStyle = dataset.backgroundColor[index];
        ctx.lineWidth = 4;
        ctx.beginPath();
        ctx.moveTo(xFrom, y);
        ctx.lineTo(xTo, y);
        ctx.stroke();        
      });
      ctx.restore();
    }
  }],
  data: {
    datasets: [{
      data: [
        { x: 0, y: 0 },
        { x: 1, y: 0 },
        { x: 2, y: 0 }
      ],
      backgroundColor: ['red', 'blue', 'green'],
      borderColor: ['red', 'blue', 'green'],
      pointRadius: 8,
      pointHoverRadius: 8,
    }],
  },
  options: {
    layout: {
      padding: {
        left: 10,
        right: 10
      }
    },
    legend: {
      display: false
    },
    tooltips: {
      enabled: false
    },
    scales: {
      yAxes: [{
        ticks: {
          display: false
        },
        gridLines: {
          display: false,
        }
      }],
      xAxes: [{
        ticks: {
          display: false,
          max: 3
        },
        gridLines: {
          display: false
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="line-chart" height="30"></canvas>
Lemire answered 25/12, 2020 at 11:32 Comment(1)
Thanks for the approach, but using the above solution breaks the behaviour that I want to have in the chart. Is there a way we can simply set the z-index of the datasets in the chart?Pipkin

© 2022 - 2024 — McMap. All rights reserved.