admin管理员组

文章数量:1323385

In ChartJS's pie and doughnut charts there is a legend option for every data that you can click to hide the data, this behavior changes with bar and line charts, when there is only a single legend option for the entire dataset, and when clicking it, it hides the entire dataset.

Is there any way to have a legend option for each data in bar/line charts?

Here's a example with a bar and a pie chart using the exact same configuration, you can see in the pie chart you can hide the slices individually, while in the bar chart you can only hide the entire dataset

var barCfg = {
  type: 'bar',
  data: {
    labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
        'rgba(54, 162, 235, 0.2)',
        'rgba(255, 206, 86, 0.2)',
        'rgba(75, 192, 192, 0.2)',
        'rgba(153, 102, 255, 0.2)',
        'rgba(255, 159, 64, 0.2)'
      ],
      borderColor: [
        'rgba(255, 99, 132, 1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)',
        'rgba(75, 192, 192, 1)',
        'rgba(153, 102, 255, 1)',
        'rgba(255, 159, 64, 1)'
      ],
      borderWidth: 1
    }]
  }
};

var pieCfg = {
  type: 'pie',
  data: {
    labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
        'rgba(54, 162, 235, 0.2)',
        'rgba(255, 206, 86, 0.2)',
        'rgba(75, 192, 192, 0.2)',
        'rgba(153, 102, 255, 0.2)',
        'rgba(255, 159, 64, 0.2)'
      ],
      borderColor: [
        'rgba(255, 99, 132, 1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)',
        'rgba(75, 192, 192, 1)',
        'rgba(153, 102, 255, 1)',
        'rgba(255, 159, 64, 1)'
      ],
      borderWidth: 1
    }]
  }
};

var barChart = new Chart(
document.getElementById('barChart').getContext('2d'), barCfg);

var pieChart = new Chart(
document.getElementById('pieChart').getContext('2d'), pieCfg);

JSFiddle

In ChartJS's pie and doughnut charts there is a legend option for every data that you can click to hide the data, this behavior changes with bar and line charts, when there is only a single legend option for the entire dataset, and when clicking it, it hides the entire dataset.

Is there any way to have a legend option for each data in bar/line charts?

Here's a example with a bar and a pie chart using the exact same configuration, you can see in the pie chart you can hide the slices individually, while in the bar chart you can only hide the entire dataset

var barCfg = {
  type: 'bar',
  data: {
    labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
        'rgba(54, 162, 235, 0.2)',
        'rgba(255, 206, 86, 0.2)',
        'rgba(75, 192, 192, 0.2)',
        'rgba(153, 102, 255, 0.2)',
        'rgba(255, 159, 64, 0.2)'
      ],
      borderColor: [
        'rgba(255, 99, 132, 1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)',
        'rgba(75, 192, 192, 1)',
        'rgba(153, 102, 255, 1)',
        'rgba(255, 159, 64, 1)'
      ],
      borderWidth: 1
    }]
  }
};

var pieCfg = {
  type: 'pie',
  data: {
    labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
        'rgba(54, 162, 235, 0.2)',
        'rgba(255, 206, 86, 0.2)',
        'rgba(75, 192, 192, 0.2)',
        'rgba(153, 102, 255, 0.2)',
        'rgba(255, 159, 64, 0.2)'
      ],
      borderColor: [
        'rgba(255, 99, 132, 1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)',
        'rgba(75, 192, 192, 1)',
        'rgba(153, 102, 255, 1)',
        'rgba(255, 159, 64, 1)'
      ],
      borderWidth: 1
    }]
  }
};

var barChart = new Chart(
document.getElementById('barChart').getContext('2d'), barCfg);

var pieChart = new Chart(
document.getElementById('pieChart').getContext('2d'), pieCfg);

JSFiddle

Share Improve this question asked Aug 11, 2021 at 15:13 brodrigsbrodrigs 3642 silver badges18 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 3

Looking at the ChartJS API it looks like hide(datasetIndex, dataIndex?) would be what you are looking for.

Hide is called when you click a legend (without dataIndex) to hide the dataset. When you call it with a dataIndex it behaves a little bit differently. Here is a fiddle to show what i mean: JSFiddle

chart onClick:

function chartOnClick(evt) {
    let chart = evt.chart
    const points = chart.getElementsAtEventForMode(evt, 'nearest', {}, true);
    
    if (points.length) {
        const firstPoint = points[0];
        //var label = myChart.data.labels[firstPoint.index];
        //var value = myChart.data.datasets[firstPoint.datasetIndex].data[firstPoint.index];
        let datasetIndex = firstPoint.datasetIndex, index = firstPoint.index;
        
        if (firstPoint.element.hidden != true) {
            chart.hide(datasetIndex, index);
        } else {
            chart.show(datasetIndex, index);
        }
    }
}

options: { // chart options
    onClick: chartOnClick
}

If that works for you, then great, but if you want it to disappear pletely, then you would need to delete the data from the array like this:

chart.data.datasets[datasetIndex].data.splice(index, 1);
chart.update();

Just keep a copy of the original array with all the data. You would likely have a "restore" button somewhere, that would set the data back when you click it:

chart.data = myData;
chart.update();

Here is a fiddle with the latter behaviour: JSFiddle (lacking the restore button, but it should be very easy to add)

ChartJS's BarCharts expect your data to belong to a single category thats why you only one button to show/hide all bars.

You easily fix this by changing the structure of your data so that each value has its own label. Instead of,

    datasets: [{
      label: 'A',
      data: [1, 2, 3]
    }]

your data should look like,

    datasets: [{
      label: 'A',
      data: [1]
    },{
      label: 'B',
      data: [2]
    },{
      label: 'C',
      data: [3]
    }]

var barCfg = {
  type: 'bar',
  data: {
    labels: ['Red'],
    datasets: [{
       label: 'Person 1',
       data: [12],
       backgroundColor: ['#FFC857']
     }, {
       label: 'Person 2',
       data: [19],
       backgroundColor: ['#E9724C']
     },{
       label: 'Person 3',
       data: [3],
       backgroundColor: ['#C5283D']
     },{
       label: 'Person 4',
       data: [5],
       backgroundColor: ['#481D24']
     },{
       label: 'Person 5',
       data: [2],
       backgroundColor: ['#ff1Dff']
     },{
       label: 'Person 6',
       data: [3],
       backgroundColor: ['#48ffff']
     }]
  }
};

var pieCfg = {
  type: 'pie',
  data: {
    labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
        'rgba(54, 162, 235, 0.2)',
        'rgba(255, 206, 86, 0.2)',
        'rgba(75, 192, 192, 0.2)',
        'rgba(153, 102, 255, 0.2)',
        'rgba(255, 159, 64, 0.2)'
      ],
      borderColor: [
        'rgba(255, 99, 132, 1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)',
        'rgba(75, 192, 192, 1)',
        'rgba(153, 102, 255, 1)',
        'rgba(255, 159, 64, 1)'
      ],
      borderWidth: 1
    }]
  }
};

var barChart = new Chart(
document.getElementById('barChart').getContext('2d'), barCfg);

var pieChart = new Chart(
document.getElementById('pieChart').getContext('2d'), pieCfg);
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/chart.min.js"></script>

<canvas id="barChart"></canvas>
<canvas id="pieChart"></canvas>

JSFiddle fork just for the record: https://jsfiddle/pqva7yso/

本文标签: javascriptChartJSShowhide data individually instead of entire dataset on barline chartsStack Overflow