Search code examples
reactjschartsdatasetlabel

showing more than one label in the dataset and add % to the data


I have my dataset and I need to display 3 labels but when I add more it only displays one , and I want to be able to have label with different colors too , my other problem is that I want to add "%" to the data but It say "Expression needed " .

Here is my datasets :

datasets: [{
      labels: ["Book 1", "Book 2" , "Book 3" ],
      data: [8%, 24%, 92%, 30% , 5%],
      backgroundColor: ["yellow", "red", "blue", "blue" , "red" ],
      barThickness:30
    }]

Solution

  • The labels attribute is part of data, but is not an element of the dataset you should write it like this: data={labels, dataset}. Your data length and the number of colors should also match the number of labels. I added 2 more books (book4 and book5) labels so we have the same number of labels, data, and colors.

    To add the '%' sign, you can modify the label as you want with the options object. With this object, you can provide a callback function to customize the labels. The namespace is options.plugins.tooltip.callbacks. More in here: Tooltip | Chart.js

    The label you mention that it only displays 1 is not precisely a label, but the legend of the chart. Since the name of each book is right below each bar I removed the legend with the options object. The namespace is options.plugins.legend

    Following is the Bar object and an image of how it looks

    <Bar 
      width={100} 
      height={50} 
      data = {{
        labels: ["Book1","Book2","Book3","Book4","Book5"],
        datasets: [{
          data: [8, 24, 92, 30, 5],
          backgroundColor: ["yellow", "red", "blue", "orange", "pink"],
          
        }
      ]
      }}
      options={{
        plugins: {
          legend: {
            display: false
          },
          tooltip: {
            enabled: true,
            callbacks: {
              label: (context) => {
                let label = context.dataset.label || '';
    
                  if (label) {
                      label += ': ';
                  }
                  if (context.parsed.y !== null) {
                      label += context.parsed.y + '%';
                  }
                  return label;
              }
            }
          }
        },
        
      }}
    />
    

    enter image description here

    If what you want is to show each bar and have a legend on top of each bar with the name of the book then what you need to do is to treat each bar as a different dataset. For each dataset, add the book name in the label attribute and for the labels array, leave only 1 value so it stays as one section, you can write whatever you want or leave it blank as "". In this case, the legend is necessary, so the only difference in the options object is that the legend attribute is omitted and set to its default: true

    <Bar 
      width={100} 
      height={50} 
      data = {{
        labels: [""],
        datasets: [{
          label:'Book1',
          data: [8],
          backgroundColor: ["yellow"],
          
        },
        {
          label:'Book2',
          data: [24],
          backgroundColor: ["red"],
          
        },
        {
          label:'Book3',
          data: [92],
          backgroundColor: ["blue"],
          
        },
        {
          label:'Book4',
          data: [30],
          backgroundColor: ["orange"],
          
        },
        {
          label:'Book5',
          data: [5],
          backgroundColor: ["pink"],
          
        }
      ]
      }}
      options={{
        plugins: {
          tooltip: {
            enabled: true,
            callbacks: {
              label: (context) => {
                let label = context.dataset.label || '';
    
                  if (label) {
                      label += ': ';
                  }
                  if (context.parsed.y !== null) {
                      label += context.parsed.y + '%';
                  }
                  return label;
              }
            }
          }
        },
        
      }}
    />
    

    enter image description here