3

I'm creating charts using Chart.js and I want to show the labels for the bars in the legend, not the title of the dataset (there is only one), please see the below image as an example:

Example of desired legend

My current legend just looks like this: My current legend

I have looked through the docs but to no avail, I found them very confusing actually.

Here is my current code:

var chart_0 = new Chart($('#cp_chart_0'), {
      type: 'bar'
    , data: {
          labels: ['Blue','Green','Yellow','Red','Purple','Orange']
        , datasets: [{
              label: 'Dataset 1'
            , borderWidth: 0
            , backgroundColor: ['#2C79C5','#7FA830','#7B57C3','#ED4D40','#EC802F','#1DC6D3']
            , data: ['12','2','5','0','9','1']
        }]
      }
});

Thanks!

bbeckford
  • 4,467
  • 6
  • 34
  • 48

3 Answers3

2

In one of the most recent releases of Chart.js 2.1.x, they added back this functionality. So go get the latest release first. Then insert the code below.

It is located under the options and legend. Here is how you use it:

options: {
    legend: {
        position: 'right'
    }
}
Tot Zam
  • 8,406
  • 10
  • 51
  • 76
JPeG
  • 811
  • 6
  • 11
  • That's great thanks for the tip! I ended up going with Hugo's answer to split into multiple datasets and created my own legend with `chart_0.generateLegend()` so I have more control over it - but after splitting into multiple datasets this worked too. – bbeckford Jul 22 '16 at 17:48
1

Easiest way is to provide your data with multiple sets :

  data: {
      labels: ['total votes']
    , datasets: [{
          label: 'Blue'
        , backgroundColor: ['#2C79C5']
        , data: ['12']
    },{
          label: 'Green'
        , backgroundColor: ['#7FA830']
        , data: ['2']
    },
    ...
    ]
  }

But you can generate a custom labels using generateLabels - http://www.chartjs.org/docs/#chart-configuration-legend-configuration

Or even customise the whole legend, including formatting, with legendCallback - http://www.chartjs.org/docs/#chart-configuration-common-chart-configuration

Hugo Silva
  • 6,748
  • 3
  • 25
  • 42
  • That did it, thanks! I split into multiple sets then created my own legend with `chart_0.generateLegend()` so I have more control over it. – bbeckford Jul 22 '16 at 17:48
0

This solution uses Chart.js version 3. You can pre-process your data using the Plugin Core API. The API offers different hooks that may be used for executing custom code.

I use the beforeInit hook to create individual datasets for each defined label/value pair. Note that the data of these new datasets are defined in point format (for instance [{ x: 1, y: 12 }]):

beforeInit: chart => {
  let dataset = chart.config.data.datasets[0];
  chart.config.data.datasets = chart.config.data.labels.map((l, i) => ({
    label: l,
    data: [{ x: i + 1, y: dataset.data[i] }],
    backgroundColor: dataset.backgroundColor[i],
    categoryPercentage: 1
  }));
  chart.config.data.labels = undefined;
}

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

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

The labels on x1 need to be collected and defined programmatically each time the hidden state of a dataset changes. This can be done in the beforeLayout hook.

beforeLayout: chart => chart.options.scales.x1.labels = chart.config.data.datasets.filter((ds, i) => !chart.getDatasetMeta(i).hidden).map(ds => ds.label)

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

new Chart('chart', {
  type: 'bar',
  plugins: [{
    beforeInit: chart => {      
      let dataset = chart.config.data.datasets[0];
      chart.config.data.datasets = chart.config.data.labels.map((l, i) => ({
        label: l,
        data: [{ x: i + 1, y: dataset.data[i] }],
        backgroundColor: dataset.backgroundColor[i],
        categoryPercentage: 1
      }));
      chart.config.data.labels = undefined;
    },
    beforeLayout: chart => chart.options.scales.x1.labels = chart.config.data.datasets.filter((ds, i) => !chart.getDatasetMeta(i).hidden).map(ds => ds.label)
  }],
  data: {
    labels: ['Blue', 'Green', 'Yellow', 'Red', 'Purple', 'Orange'],
    datasets: [{
      data: ['12', '2', '5', '0', '9', '1'],
      backgroundColor: ['#2C79C5', '#7FA830', '#FFF200', '#ED4D40', '#800080', '#EC802F']
    }]
  },
  options: {
    interaction: {
      intersect: true,
      mode: 'nearest'
    },
    plugins: {
      legend: {
        position: 'right'
      },
      tooltip: {
        callbacks: {
          title: () => undefined
        }
      }
    },   
    scales: {
      y: {
        beginAtZero: true
      },
      x: {
        display: false
      },
      x1: {
        offset: true,
        gridLines: {
          display: false
        }
      }
    }
  }
});
canvas {
  max-width: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.0/chart.min.js"></script>
<canvas id="chart" height="120"></canvas>
uminder
  • 23,831
  • 5
  • 37
  • 72