csb00
csb00

Reputation: 1161

Adding a second custom tooltip for charts in ChartsJs

I am trying to add a second custom tooltip for a doughnut chart in ChartsJs. However, now that I added a new set of data (labels2) and a new function (labels2). The doughnut appears, but the tooltips don't. Could somebody look at the code below or in my JSFiddle and see what could potentially be wrong?
This is my first time working with chartsjs and charts overall.

Here is the code for the function:

// HTML
    <canvas id="myChart" height="100"></canvas>

    //JS    
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
  type: 'doughnut',
  data: {
    labels: ["Red", "Blue", "Yellow"],
     //**LABELS FOR SECOND TOOLTIP**??
    labels2: ["One", "Two", "Three"],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3],
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
        'rgba(54, 162, 235, 0.2)',
        'rgba(255, 206, 86, 0.2)'
      ],
      borderColor: [
        'rgba(255,99,132,1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)'
      ],
      borderWidth: 1
    }]
  },
  options: {
    tooltips: {
     // Disable the on-canvas tooltip
        enabled: false,
      custom: function(tooltipModel){
        // Tooltip Element
                var tooltipEl = document.getElementById("myChart");

            // Create element on first render
            if (!tooltipEl){
            tooltipEl = document.getElementById("div");
            tooltipEl.id = 'myChart';
            tooltipEL.innerHTML = '<table></table>';
            document.body.appendChild(tooltipEl);
            }

             // Hide if no tooltip
            if (tooltipModel.opacity === 0){
            tooltipEl.style.opacity = 0;
            return;
            }

             // Set caret Position
            tooltipEl.classList.remove('above', 'below', 'no-transform');
            if (tooltipModel.yAlign) {
            tooltipEl.classList.add(tooltipModel.yAlign);
            } else {
            tooltipEl.classList.add('no-transform');
            }

            function getBody(bodyItem) {
             return bodyItem.lines;
            }
            // Set Text
             if (tooltipModel.body) {
                    var titleLines = tooltipModel.title || [];
                    var bodyLines = tooltipModel.body.map(getBody);

                    var innerHtml = '<thead>';

                    titleLines.forEach(function(title) {
                        innerHtml += '<tr><th>' + title + '</th></tr>';
                    });
                    innerHtml += '</thead><tbody>';

                    bodyLines.forEach(function(body, i) {
                        var colors = tooltipModel.labelColors[i];
                        var style = 'background:' + colors.backgroundColor;
                        style += '; border-color:' + colors.borderColor;
                        style += '; border-width: 2px';
                        var span = '<span style="' + style + '"></span>';
                        innerHtml += '<tr><td>' + span + body + '</td></tr>';
                    });
                    innerHtml += '</tbody>';

                    var tableRoot = tooltipEl.querySelector('table');
                    tableRoot.innerHTML = innerHtml;
                }

                // `this` will be the overall tooltip
               var position = this._chart.canvas.getBoundingClientRect();

                 tooltipEl.style.opacity = 1;
                tooltipEl.style.position = 'absolute';
                tooltipEl.style.left = position.left + window.pageXOffset + tooltipModel.caretX + 'px';
                tooltipEl.style.top = position.top + window.pageYOffset + tooltipModel.caretY + 'px';
                tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily;
                tooltipEl.style.fontSize = tooltipModel.bodyFontSize + 'px';
                tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle;
                tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px'
                tooltipEl.style.pointerEvents = 'none';



      },
      callbacks: {
        title: function(tooltipItem, data) {
          return data['labels'][tooltipItem[0]['index']];
        },
        label: function(tooltipItem, data) {
          return data['datasets'][0]['data'][tooltipItem['index']];
        },
        //**FUNCTION FOR SECOND TOOLTIP
        **label2: function(tooltipItem, data){
            return data['data'][0]['data'][tooltipItem['index']];
        },**
        afterLabel: function(tooltipItem, data) {
          var dataset = data['datasets'][0];
          var percent = Math.round((dataset['data'][tooltipItem['index']] / dataset["_meta"][0]['total']) * 100)
          return '(' + percent + '%)';
        }
      },
      backgroundColor: '#FFF',
      titleFontSize: 16,
      titleFontColor: '#0066ff',
      bodyFontColor: '#000',
      bodyFontSize: 14,
      displayColors: false
    }
  }
})

Upvotes: 0

Views: 310

Answers (1)

uminder
uminder

Reputation: 26190

If you define your HTML as follows, it should work.

<div>
  <canvas id="myChart" height="100"></canvas>
    <div id="chartjs-tooltip">
       <table></table>
    </div>
</div>

var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
  type: 'doughnut',
  data: {
labels: ["Red", "Blue", "Yellow"],
labels2: ["One", "Two", "Three"],
datasets: [{
  label: '# of Votes',
  data: [12, 19, 3],
  backgroundColor: [
    'rgba(255, 99, 132, 0.2)',
    'rgba(54, 162, 235, 0.2)',
    'rgba(255, 206, 86, 0.2)'
  ],
  borderColor: [
    'rgba(255,99,132,1)',
    'rgba(54, 162, 235, 1)',
    'rgba(255, 206, 86, 1)'
  ],
  borderWidth: 1
}]
  },
  options: {
tooltips: {
  // Disable the on-canvas tooltip
  enabled: false,
  custom: function(tooltipModel) {
    // Tooltip Element
    var tooltipEl = document.getElementById("chartjs-tooltip");

    // Hide if no tooltip
    if (tooltipModel.opacity === 0) {
      tooltipEl.style.opacity = 0;
      return;
    }

    // Set caret Position
    tooltipEl.classList.remove('above', 'below', 'no-transform');
    if (tooltipModel.yAlign) {
      tooltipEl.classList.add(tooltipModel.yAlign);
    } else {
      tooltipEl.classList.add('no-transform');
    }

    function getBody(bodyItem) {
      return bodyItem.lines;
    }
    // Set Text
    if (tooltipModel.body) {
      var titleLines = tooltipModel.title || [];
      var bodyLines = tooltipModel.body.map(getBody);

      var innerHtml = '<thead>';

      titleLines.forEach(function(title) {
        innerHtml += '<tr><th>' + title + '</th></tr>';
      });
      innerHtml += '</thead><tbody>';

      bodyLines.forEach(function(body, i) {
        var colors = tooltipModel.labelColors[i];
        var style = 'background:' + colors.backgroundColor;
        style += '; border-color:' + colors.borderColor;
        style += '; border-width: 2px';
        var span = '<span style="' + style + '"></span>';
        innerHtml += '<tr><td>' + span + body + '</td></tr>';
      });
      innerHtml += '</tbody>';

      var tableRoot = tooltipEl.querySelector('table');
      tableRoot.innerHTML = innerHtml;
    }

    // `this` will be the overall tooltip
    var position = this._chart.canvas.getBoundingClientRect();

    tooltipEl.style.opacity = 1;
    tooltipEl.style.position = 'absolute';
    tooltipEl.style.left = position.left + window.pageXOffset + tooltipModel.caretX + 'px';
    tooltipEl.style.top = position.top + window.pageYOffset + tooltipModel.caretY + 'px';
    tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily;
    tooltipEl.style.fontSize = tooltipModel.bodyFontSize + 'px';
    tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle;
    tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px'
    tooltipEl.style.pointerEvents = 'none';
  },
  callbacks: {
    title: function(tooltipItem, data) {
      return data['labels'][tooltipItem[0]['index']];
    },
    label: function(tooltipItem, data) {
      return data['datasets'][0]['data'][tooltipItem['index']];
    },
    label2: function(tooltipItem, data) {
      return data['data'][0]['data'][tooltipItem['index']];
    },
    afterLabel: function(tooltipItem, data) {
      var dataset = data['datasets'][0];
      var percent = Math.round((dataset['data'][tooltipItem['index']] / dataset["_meta"][0]['total']) * 100)
      return '(' + percent + '%)';
    }
  },
  backgroundColor: '#FFF',
  titleFontSize: 16,
  titleFontColor: '#0066ff',
  bodyFontColor: '#000',
  bodyFontSize: 14,
  displayColors: false
}
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<div>
    <canvas id="myChart" height="100"></canvas>
    <div id="chartjs-tooltip">
        <table></table>
    </div>
</div>

Upvotes: 1

Related Questions