1
votes

The dataset label in my chart.js bar chart does not show correct values. I am trying different chart configurations but nothing seems to work. Here is my JS Fiddle. What I want to achieve is that the bar chart should show values like 'HIGH : 30' or 'MED: 25' but right now the tooltip is showing only the first label (HIGH: 30, HIGH: 25, HIGH: 56) on all the 3 bars. This is strange. Need some assistance.

Some more details about what I tried so far: If I use arroChartConfig1 it gives tooltip title as HIGH for all graphs and label as HIGH: 30 (red bar), HIGH: 25 (yellow bar), HIGH: 56 (blue bar).

If I use arroChartConfig2 it gives correct title and labels but shows only one legend with label HIGH,MED,LOW.

If I use arroChartConfig3 distinct labels in legend but bar tooltip title and labels have values same as in arroChartConfig1.

Thanks in advance.

var oMyBarChart;
var ctx = document.getElementById("canvas").getContext("2d");
function GetSelectedChartType(sSelectedOption){
 return sSelectedOption.options[sSelectedOption.selectedIndex].value;
}
arroLevels = ["HIGH","MED","LOW"];
arroLevelsCount = [30,25,56];
arroLevelColors = 
['rgba(230,0,0,1)','rgba(255,255,79,1)','rgba(150,198,250,1)'];
arroDataset=[];
sChartType = GetSelectedChartType(document.getElementById('chartSelector'));
arroLevels.map(function(sValue,iIndex){
  let oData = [arroLevelsCount[iIndex]];
  let sColorData = arroLevelColors[iIndex];
  arroDataset.push({
      label: sValue,
      data: oData,
      backgroundColor: sColorData,
      pointStyle: 'triangle',
  });
 });
barChartData = {
    labels: arroLevels,
    datasets: arroDataset,
}

arroChartConfig1 = {
    type: sChartType,
    data: barChartData,
    options: {
        responsive: true,
        legend: {
          position: 'right',
          generateLabels: function(data){
            return data.text;
          }
        },
        title: {
          display: true,
          text: 'My Bar Chart'
        },
        tooltips: {
          callbacks:{
           label: function(ttitem,data){
              return ttitem.xLabel+": "+ttitem.yLabel
           }
         }
       }
     }
    }
arroChartConfig2 = {
      type: sChartType,
      data: {
       datasets: [{
          label: arroLevels,
          data: arroLevelsCount,
          backgroundColor: arroLevelColors,
          pointStyle: 'triangle',
        }],
        labels: arroLevels
      },
      options: {
        responsive: true,
        legend: {
          position: 'right',
          generateLabels: function(data){
            return data.text;
          }
        },
         title: {
           display: true,
           text: 'My Bar Chart'
         },
         tooltips: {
           callbacks:{
             label: function(ttitem,data){
               return ttitem.xLabel+": "+ttitem.yLabel
             }
           }
         }
       }
   }
arroChartConfig3 = {
      type: sChartType,
      data: {
        datasets: [{
          label: "HIGH",
          data: ["30"],
          backgroundColor: 'rgba(230,0,0,1)',
          pointStyle: 'triangle',
        },
        {
          label: "MED",
          data: ["25"],
          backgroundColor: 'rgba(255,255,79,1)',
          pointStyle: 'triangle',
        },
         {
          label: "LOW",
          data: ["56"],
          backgroundColor: 'rgba(150,198,250,1)',
          pointStyle: 'triangle',
        }],
        labels: ["HIGH","MED","LOW"]
      },
      options: {
        responsive: true,
        legend: {
          position: 'right',
         generateLabels: function(data){
           return data.text;
          }
        },
         title: {
           display: true,
          text: 'My Bar Chart'
         },
         tooltips: {
           callbacks:{
             title: function(ttitem,data){
                 return '';
             },
             label: function(ttitem,data){
               return ttitem.xLabel+": "+ttitem.yLabel;
             }
           }
         }
       }
   }
    //oMyBarChart = new Chart(ctx,arroChartConfig1);
    //oMyBarChart = new Chart(ctx,arroChartConfig2);
    oMyBarChart = new Chart(ctx,arroChartConfig3);
1

1 Answers

3
votes

It might be easier to achieve what you'd like if you would consider every element in your arroLevelsCount array as a standalone dataset. So the simplest config would look like this (and here's a JSFiddle of that):

arroChartConfig = {
  type: sChartType,
  data: {
    datasets: [{
      label: arroLevels[0],
      data: [arroLevelsCount[0] ],
      backgroundColor: arroLevelColors[0],
      pointStyle: 'triangle',
    }, 
    {
      label: arroLevels[1],
      data: [ arroLevelsCount[1] ],
      backgroundColor: arroLevelColors[1],
      pointStyle: 'triangle',
    },
    {
      label: arroLevels[2],
      data: [ arroLevelsCount[2] ],
      backgroundColor: arroLevelColors[2],
      pointStyle: 'triangle',
    }],
    labels: arroLevels
  },
  options: {
    tooltips: {
      callbacks: {
        title: function(chart, data) {
          return data.labels[chart[0].datasetIndex];
        }
      }
    }
  }
 }

But if you'd like to stick to your approach there are a few things to consider. The generateLabels option has to be inside of the labels option and the function passes the entire config as a parameter so you can't just return data.text, instead you have to iterate over the labels. The function generateLabels requires an array legend item as return.

Considering all points above the legend option could look like this:

legend: {
  position: 'right',
  labels: {            
    generateLabels: function(chart) {
        return chart.data.labels.map(function(label, i) {
            return {
                text: label,
                fillStyle: chart.data.datasets[0].backgroundColor[i]
            };
        });
    }
  }
}

Here is your updated JSFiddle.

Edit: To display the correct tooltip label color for your approach you should add the labelColor callback aswell and return the color depending on the hovered dataset.

labelColor: function(ttitem, data) {
          return {
            borderColor: arroLevelColors[ttitem.index],
            backgroundColor: arroLevelColors[ttitem.index]
          };

This is the second JSFiddle updated with the labelColor callback.