Leonardi
Leonardi

Reputation: 53

Bar chart.js legend showing "undefined"

I'm working with chart.js and need to make a legend on horizontalBar, but isn't working because my data have 5 values and on legend label is showing only one and the value is "undefined", this undefined value control all chart colors.

Here is my code:

horizontalMeters = new Chart("chartHorizontalBar", {
    type: "bar",
    data: {
      labels: ["red", "blue", "green"],
      datasets: [{
        backgroundColor: ["red", "blue", "green"],
        data: [123, 321, 213]
      }]
    },
    options: {
      indexAxis: 'y',
      plugins: {
        legend: {
          display: true,
          position: "right",
        }       
      },
    }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"
    integrity="sha512-TW5s0IT/IppJtu76UbysrBH9Hy/5X41OTAbQuffZFU6lQ1rdcLHzpU5BzVvr/YFykoiMYZVWlr/PX1mDcfM9Qg=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script
    src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0-rc.1/chartjs-plugin-datalabels.min.js"
    integrity="sha512-+UYTD5L/bU1sgAfWA0ELK5RlQ811q8wZIocqI7+K0Lhh8yVdIoAMEs96wJAIbgFvzynPm36ZCXtkydxu1cs27w=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    
    
<canvas id="chartHorizontalBar"></canvas>

I'm using chart.js v3.7 and a datalabels plugin v2.0, i don't know if this plugin and version have a conflict, but i make a Doughnot Chart with the same CDN's and that one works

The code:

doughnotQualities = new Chart("chartDoughnutBar", {
    type: "doughnut",
    data: {
      labels: ["red", "blue", "green"],
      datasets: [{
        backgroundColor: ["red", "blue", "green"],
        data: [123, 321, 213]
      }]
    },
    options: {
      plugins: {
        legend: { 
          display: true, 
          position: "right"
        },
      },
    }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"
    integrity="sha512-TW5s0IT/IppJtu76UbysrBH9Hy/5X41OTAbQuffZFU6lQ1rdcLHzpU5BzVvr/YFykoiMYZVWlr/PX1mDcfM9Qg=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <script
    src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0-rc.1/chartjs-plugin-datalabels.min.js"
    integrity="sha512-+UYTD5L/bU1sgAfWA0ELK5RlQ811q8wZIocqI7+K0Lhh8yVdIoAMEs96wJAIbgFvzynPm36ZCXtkydxu1cs27w=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    
<canvas id="chartDoughnutBar"></canvas>

That's the difference between charts: enter image description here

enter image description here

Does anyone know how to solve this?

Upvotes: 3

Views: 4576

Answers (3)

Avraham Weinstein
Avraham Weinstein

Reputation: 894

In your dataset object, just add label:''. This will remove the undefined interpulated string.

Upvotes: 0

uminder
uminder

Reputation: 26170

This answer explains how to solve the problem with a vertical bar chart.

The code needs to be slightly adapted to also work for a horizontal bar chart.

Please take a look at the following code and see how it could be done in your case.

new Chart('myChart', {
  type: 'bar',
  plugins: [{
    afterInit: chart => {
      let dataset = chart.data.datasets[0];
      chart.data.datasets = chart.data.labels.map((l, i) => ({
        label: l,
        data: [{ x: dataset.data[i], y: i }],
        backgroundColor: dataset.backgroundColor[i],
        categoryPercentage: 1
      }));
      chart.data.labels = undefined;
    },
    beforeLayout: chart => {
      chart.options.scales.y1.labels = chart.data.datasets.filter((ds, i) => !chart.getDatasetMeta(i).hidden).map(ds => ds.label);
    }
  }],
  data: {
    labels: ['Red', 'Blue', 'Green'],
    datasets: [{
      data: [123, 321, 213],
      backgroundColor: ['red', 'blue', 'green']
    }]
  },
  options: {
    indexAxis: 'y',
    maintainAspectRatio: false,
    plugins: {
      legend: {
        position: 'right'
      },
      tooltip: {
        callbacks: {
          title: () => null
        }
      }
    },
    scales: {
      y: {
        display: false
      },
      y1: {
        offset: true
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"></script>
<canvas id="myChart"></canvas>

Upvotes: 0

LeeLenalee
LeeLenalee

Reputation: 31421

It shows undefined since it takes the label of the dataset, for doughnut and pie charts chart.js overrides the legend generator to use the labels array instead.

You can use multiple datasets with null values and then set the skipNull options to true like so:

Chart.register(ChartDataLabels)

horizontalMeters = new Chart("chartHorizontalBar", {
  type: "bar",
  data: {
    labels: ["red", "blue", "green"],
    datasets: [{
      backgroundColor: "red",
      label: "red",
      data: [123, null, null]
    }, {
      backgroundColor: "blue",
      label: "blue",
      data: [null, 321, null]
    }, {
      backgroundColor: "green",
      label: "green",
      data: [null, null, 213]
    }]
  },
  options: {
    indexAxis: 'y',
    skipNull: true,
    plugins: {
      legend: {
        display: true,
        position: "right",
      }
    },
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js" integrity="sha512-TW5s0IT/IppJtu76UbysrBH9Hy/5X41OTAbQuffZFU6lQ1rdcLHzpU5BzVvr/YFykoiMYZVWlr/PX1mDcfM9Qg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0-rc.1/chartjs-plugin-datalabels.min.js" integrity="sha512-+UYTD5L/bU1sgAfWA0ELK5RlQ811q8wZIocqI7+K0Lhh8yVdIoAMEs96wJAIbgFvzynPm36ZCXtkydxu1cs27w==" crossorigin="anonymous"
  referrerpolicy="no-referrer"></script>


<canvas id="chartHorizontalBar"></canvas>

Edit:
To use the datalabels plugin you will need to register it either inline or globally as in my example.

Upvotes: 4

Related Questions