score:4

Accepted answer

You can convert your target values into floating bars where individual bars are specified with the syntax [min, max]. Given an array of values named targetData, it can be converted with Array.map() as follows.

targetData.map(v => [v - 1, v + 1])

Further you need to define individual stacked xAxis for both datasets. In order to have the original target values displayed in the tooltips, a toolips.callback.label function is also needed.

Please have a look at below runnable code snippet.

const actualData = [100, 180, 120, 80, 140, 170, 160];
const targetData = [110, 150, 140, 100, 120, 110, 170];

new Chart("chart", {
  type: "bar",
  data: {
    labels: ["KPI 1", "KPI 2", "KPI 3", "KPI 4", "KPI 5", "KPI 6", "KPI 7"],
    datasets: [{
        label: "Actual",
        backgroundColor: 'rgba(0, 0, 255, 0.2)',
        data: actualData,
        xAxisID: "x-axis-actual"
      },
      {
        label: "Target",
        backgroundColor: 'rgba(255, 0, 128, 1)',
        data: targetData.map(v => [v - 1, v + 1]),
        xAxisID: "x-axis-target"
      }
    ]
  },
  options: {
    tooltips: {
      callbacks: {
        label: (tooltipItem, data) => {
          const v = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
          return Array.isArray(v) ? (v[1] + v[0]) / 2 : v;
        }
      }
    },
    scales: {
      xAxes: [{
          id: "x-axis-target",
          stacked: true
        },
        {
          display: false,
          offset: true,
          stacked: true,
          id: "x-axis-actual",
          gridLines: {
            offsetGridLines: true
          }
        }
      ],
      yAxes: [{
        ticks: {
          beginAtZero: true
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="chart" height="120"></canvas>


Related Query

More Query from same tag