1

does anyone know if this is possible? Basically I want the chart to have labels for example [Jan, Feb, March] and I want to be able to toggle these values on and off. Seems like such a simple thing but is proving problematic.

Billy
  • 13
  • 2
  • 1
    One of these Chart.js v2 related answers may help: https://stackoverflow.com/a/64389544/2358409 https://stackoverflow.com/a/64328566/2358409 – uminder May 13 '21 at 08:18
  • @uminder the answer you gave on the other question is where I am now, but I wan the [A B C D E ] to be labelled below each bar – Billy May 13 '21 at 08:31
  • The first link points to an answer that uses a custom HTML legend. It's quite complex but it should solve your problem. – uminder May 13 '21 at 08:36

1 Answers1

1

You can create a separate dataset for each bar and define the data in point format as follows:

data: [{ x: 1, y: 16 }]

Further you need to define a second x-axis that will contain the labels.

{
  offset: true,
  gridLines: {
    display: false
  }
}

The labels on the second x-axis need to be collected and defined programmatically each time the hidden state of a dataset changes. This can be done with the Plugin Core API. The API offers different hooks that may be used for executing custom code. In your case, you can use the beforeLayout hook.

plugins: [{
  beforeLayout: chart => chart.chart.options.scales.xAxes[1].labels = chart.chart.data.datasets.filter(ds => !ds._meta[0].hidden).map(ds => ds.label)
}]

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

new Chart(document.getElementById('chart'), {
  type: 'bar',
  plugins: [{
    beforeLayout: chart => chart.chart.options.scales.xAxes[1].labels = chart.chart.data.datasets.filter(ds => !ds._meta[0].hidden).map(ds => ds.label)
  }],
  data: {
    datasets: [{
        label: 'A',
        data: [{ x: 1, y: 16 }],
        backgroundColor: 'rgba(255, 99, 132, 0.2)',
        borderColor: 'rgb(255, 99, 132)',
        borderWidth: 1,
        categoryPercentage: 1
      },
      {
        label: 'B',
        data: [{ x: 2, y: 22 }],
        backgroundColor: 'rgba(255, 159, 64, 0.2)',
        borderColor: 'rgb(255, 159, 64)',
        borderWidth: 1,
        categoryPercentage: 1
      },
      {
        label: 'C',
        data: [{ x: 3, y: 18 }],
        backgroundColor: 'rgba(255, 205, 86, 0.2)',
        borderColor: 'rgb(255, 205, 86)',
        borderWidth: 1,
        categoryPercentage: 1
      },
      {
        label: 'D',
        data: [{ x: 4, y: 13 }],
        backgroundColor: 'rgba(75, 192, 192, 0.2)',
        borderColor: 'rgb(75, 192, 192)',
        borderWidth: 1,
        categoryPercentage: 1
      },
      {
        label: 'E',
        data: [{ x: 5, y: 5 }],
        backgroundColor: 'rgba(54, 162, 235, 0.2)',
        borderColor: 'rgb(54, 162, 235)',
        borderWidth: 1,
        categoryPercentage: 1
      },
      {
        label: 'F',
        data: [{ x: 6, y: 16 }],
        backgroundColor: 'rgba(153, 102, 255, 0.2)',
        borderColor: 'rgb(153, 102, 255)',
        borderWidth: 1,
        categoryPercentage: 1
      },
    ]
  },
  options: {
    tooltips: {
      callbacks: {
        title: () => undefined
      }
    },
    scales: {
      yAxes: [{
        ticks: {
          beginAtZero: true
        }
      }],
      xAxes: [{
          display: false
        },
        {
          offset: true,
          gridLines: {
            display: false
          }
        }
      ]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.min.js"></script>
<canvas id="chart" height="80"></canvas>
uminder
  • 23,831
  • 5
  • 37
  • 72
  • Also, the solution doesn't work if you have already some datasets hidden from the begging. – Kida Aug 22 '22 at 12:55
  • To manage more charts on one page you should use `ds._meta[chart.id]` instead of `ds._meta[0]` – Kida Aug 23 '22 at 06:41