Chartjs-plugin-datalabels: Adding multiple datalabels types on chart

Created on 20 Jun 2018  路  14Comments  路  Source: chartjs/chartjs-plugin-datalabels

Hello ! I was wondering if it was possible to use different datalabels types on a graph.
Here is what I currently have :
sans titre 1
I am adding the black datalabels with the plugin but didn't find a way to display my blue datalabels by also using the plugin so I'm currently using onComplete from chart.js which is not optimal at all.

If a similar feature or workaround is not already available, it would be great to be able to do something like this :

datalabels: [{ // datalabelsType1 },{ // datalabelsType2 }]

enhancement resolved

Most helpful comment

There is no built-in feature that enables multiple labels for a single value, though I agree that could be useful. However, I'm not fan of the datalabels: [] array approach because it's a pain to make it mergeable easily, for example if you define multiple labels at the plugin level and want to override options for a specific label at the dataset level:

options: {
  plugins: {
    datalabels: [{
      // first label options
      color: 'green'
    }, {
      // second label options
      color: 'red'
    }]
  }
},
data: {
  datasets: [{
    // how to make the second label color 'blue' instead of 'red'?
    datalabels: ??? 
  },
  // ...
},

That's a recurrent issue we have in Chart.js with scale options. Also, it doesn't work well with default options since the array would override it. So ideally we should support a map of options instead of an array, but in this case, we have no way to differentiate an object of options (multiple labels) from the actual options object (single label), that we still need to support.

One solution could be to introduce a new option named labels:

options: {
  plugins: {
    datalabels: {
      color: 'blue',      // labels will be 'blue' by default
      labels: {           // 2 labels for each values
        l1: {             // first label options
          ...             // color fallback to 'blue'
        },
        l2: {             // second label options
          color: 'red',   // override the default color
          ...
        }
      }
    }
  }
},
data: {
  datasets: [{
    datalabels: {           // options for the first dataset
      labels: {
        l1: {
          color: 'yellow'   // override the first label color
        }
                            // l2 still displayed 'red'
      }
    }
  }, {
    datalabels: {
        color: 'pink'       // override the default color
        labels: {
            l2: false|null  // disable the second label
        }
    }
  },
  // ...
},

Thoughts?

All 14 comments

There is no built-in feature that enables multiple labels for a single value, though I agree that could be useful. However, I'm not fan of the datalabels: [] array approach because it's a pain to make it mergeable easily, for example if you define multiple labels at the plugin level and want to override options for a specific label at the dataset level:

options: {
  plugins: {
    datalabels: [{
      // first label options
      color: 'green'
    }, {
      // second label options
      color: 'red'
    }]
  }
},
data: {
  datasets: [{
    // how to make the second label color 'blue' instead of 'red'?
    datalabels: ??? 
  },
  // ...
},

That's a recurrent issue we have in Chart.js with scale options. Also, it doesn't work well with default options since the array would override it. So ideally we should support a map of options instead of an array, but in this case, we have no way to differentiate an object of options (multiple labels) from the actual options object (single label), that we still need to support.

One solution could be to introduce a new option named labels:

options: {
  plugins: {
    datalabels: {
      color: 'blue',      // labels will be 'blue' by default
      labels: {           // 2 labels for each values
        l1: {             // first label options
          ...             // color fallback to 'blue'
        },
        l2: {             // second label options
          color: 'red',   // override the default color
          ...
        }
      }
    }
  }
},
data: {
  datasets: [{
    datalabels: {           // options for the first dataset
      labels: {
        l1: {
          color: 'yellow'   // override the first label color
        }
                            // l2 still displayed 'red'
      }
    }
  }, {
    datalabels: {
        color: 'pink'       // override the default color
        labels: {
            l2: false|null  // disable the second label
        }
    }
  },
  // ...
},

Thoughts?

Thanks for your answer. I'm still pretty new to chart.js so I don't really have a full overview of its inner workings, I can't really find a solution of my own.
Your solution looks neat though and I don't find any problem with its architecture. Would love to see it implemented.

Hi there, I am currently struggling with the same problem, and I don't really get any of the solutions you have shown. Would it be possible to get a deeper explanation of what exactly are you doing?

Have a great day.

@Tajlang These aren't solutions but possible enhancements of the plugin, currently there is no way to have multiple datalabels styles on a single chart using the plugin.

I managed to do a workaround.
Basically in the datasets I inputed another "hidden" data object with its own datalabels settings. This way the line/points are hidden while the label get drawn on the chart. You only need to sum the stacked values, so the data labels gets displayed at the very top.

dataset

Chart options:

plugins: {
  datalabels: {
    color: '#fff',
    align: 'center',
    anchor: 'center',
    font: { weight: 'bold' },
  }
}

datasets:

{ data: [0, 0, 0, 0, 0, 12000000, 0], label: 'Fluorine' },
{ data: [0, 0, 0, 0, 0, 0, 13672800], label: 'Neon' },
{ data: [0, 0, 0, 0, 0, 12000000, 13672800], label: 'Hidden line', 
  type: 'line', 
  showLine: false, 
  pointRadius: 0, 
  pointHoverRadius: 0,
  datalabels: { 
    align: 'end', 
    anchor: 'end',
    font: { weight: '400' },
    color: '#444',
  }
}

How can we impose responsive font i.e., like
font: { size: '1.5rem' }

@Lenophie @Tajlang @mrVers @redoper1 @omarsedki multiple labels per data element is now implemented in e1347fc28fc8f8d890b33acb1e06011e7fdb54c9. I know it's been a long time but can some of you test this feature before I release a new version?

chartjs-plugin-datalabels.min.js | documentation | sample

@simonbrunel I'm not one of the original requesters, but so far the feature works as expected for me. Think you'll release soon?

Thanks @ScottDavidSanders for your tests. I would like to release a new version next week if no bug discovered with this new feature.

You're welcome, although I'm just using it for a simple horizontal bar graph with the value at the end of the bar and the label on top of the bar. If @anihow is still around, https://github.com/chartjs/chartjs-plugin-datalabels/issues/44 should probably be resolved.

Thanks for your hard work, I coincidentally needed this exact feature a day or two before you implemented it. Way to read my mind!

@simonbrunel sorry for delay, I just tested it and it works really nicely, at least for our purpose. I will try to test it more during the weekend if I can find any bugs.

@redoper1 no worries :) Please let me know if you have been able to test this new feature a bit more.

@simonbrunel yeah, I was testing it with multiple scenarios which came into my mind and it looked like everything was working flawlessly. Maybe somebody will discover some bug, but I couldn't find even one.

Thanks @ScottDavidSanders and @redoper1, this feature is now part of version v0.7.0 released today.

Was this page helpful?
0 / 5 - 0 ratings