title: Chartjs - Insert additional data into chart tooltip
body: <p>I'm trying to insert additional data into the doughnut chart. 
  The controller pass to the view an array like this:</p>
  
  <pre><code>[
    0 =&gt; array:3 [
      "profit" =&gt; 20
      "sex" =&gt; array:3 [
        0 =&gt; 0
        1 =&gt; 8
        2 =&gt; 0
      ]
      "count" =&gt; 8
    ]
    1 =&gt; array:3 [
      "profit" =&gt; 101.5
      "sex" =&gt; array:3 [
        0 =&gt; 4
        1 =&gt; 4
        2 =&gt; 0
      ]
      "count" =&gt; 8
    ]
    ...
  ]
  </code></pre>
  
  <p>Using <code>chartjs</code> and the fied profit of all array elements I create this doughnut chart:
  <a href="https://i.stack.imgur.com/yf1yF.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/yf1yF.png" alt="doughnut chart"></a></p>
  
  <p>But I would customize the content of the <code>tooltip</code> so that the datas of the "sex" fieds are visible. I try with the following code but the varible <code>data</code> contains only the values contained in the chart.</p>
  
  <pre><code>config.options.tooltips.callbacks = {
    title: (tooltipItem, data) =&gt; {
      return data['labels'][tooltipItem[0]['index']];
    },
    label: (tooltipItem, data) =&gt; {
      return data['datasets'][0]['data'][tooltipItem['index']];
    },
    afterLabel: (tooltipItem, data) =&gt; {
      var dataset = data['datasets'][0];
      var percent = Math.round((dataset['data'][tooltipItem['index']] / dataset._meta[4].total) * 100)
  
      return `${percent} %`;
    },
    backgroundColor: '#FFF',
    titleFontSize: 16,
    titleFontColor: '#0066ff',
    bodyFontColor: '#000',
    bodyFontSize: 14,
    displayColors: false
  }
  </code></pre>
  
  <p>I pass the data in the <code>config object</code> in this way: <code>config.data.datasets[0].data = data.map(el =&gt; el.profit);
  </code>
  How do I add more data to the tooltip to get something like this?
  <a href="https://i.stack.imgur.com/4DTsT.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4DTsT.png" alt="enter image description here"></a></p>
  
  <p>This is my code:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>function createDonatsChart(ctx, title, data, labels, middleText, type) {
  
    Chart.pluginService.register({
      beforeDraw: function(chart) {
        if (chart.config.options.elements.center) {
          // Get ctx from string
          const ctx = chart.chart.ctx;
  
          // Get options from the center object in options
          const centerConfig = chart.config.options.elements.center;
          const fontStyle = centerConfig.fontStyle || 'Asap';
          const txt = centerConfig.text;
          const color = centerConfig.color || '#000';
          const maxFontSize = centerConfig.maxFontSize || 75;
          const sidePadding = centerConfig.sidePadding || 20;
          const sidePaddingCalculated = (sidePadding / 100) * (chart.innerRadius * 2)
          // Start with a base font of 30px
          ctx.font = `30px ${fontStyle}`;
  
          // Get the width of the string and also the width of the element minus 10 to give it 5px side padding
          const stringWidth = ctx.measureText(txt).width;
          const elementWidth = (chart.innerRadius * 2) - sidePaddingCalculated;
  
          // Find out how much the font can grow in width.
          const widthRatio = elementWidth / stringWidth;
          const newFontSize = Math.floor(30 * widthRatio);
          const elementHeight = (chart.innerRadius * 2);
  
          // Pick a new font size so it will not be larger than the height of label.
          const fontSizeToUse = Math.min(newFontSize, elementHeight, maxFontSize);
          const minFontSize = centerConfig.minFontSize;
          const lineHeight = centerConfig.lineHeight || 25;
          const wrapText = false;
  
          if (minFontSize === undefined) {
            minFontSize = 20;
          }
  
          if (minFontSize &amp;&amp; fontSizeToUse &lt; minFontSize) {
            fontSizeToUse = minFontSize;
            wrapText = true;
          }
  
          // Set font settings to draw it correctly.
          ctx.textAlign = 'center';
          ctx.textBaseline = 'middle';
          const centerX = ((chart.chartArea.left + chart.chartArea.right) / 2);
          const centerY = ((chart.chartArea.top + chart.chartArea.bottom) / 2);
          ctx.font = `${fontSizeToUse}px ${fontStyle}`;
          ctx.fillStyle = color;
  
          if (!wrapText) {
            ctx.fillText(txt, centerX, centerY);
            return;
          }
  
          const words = txt.split(' ');
          let line = '';
          let lines = [];
  
          // Break words up into multiple lines if necessary
          for (let n = 0; n &lt; words.length; n++) {
            const testLine = line + words[n] + ' ';
            const metrics = ctx.measureText(testLine);
            const testWidth = metrics.width;
            if (testWidth &gt; elementWidth &amp;&amp; n &gt; 0) {
              lines.push(line);
              line = words[n] + ' ';
            } else {
              line = testLine;
            }
          }
  
          // Move the center up depending on line height and number of lines
          centerY -= (lines.length / 2) * lineHeight;
  
          for (let n = 0; n &lt; lines.length; n++) {
            ctx.fillText(lines[n], centerX, centerY);
            centerY += lineHeight;
          }
  
          //Draw text in center
          ctx.fillText(line, centerX, centerY);
        }
      }
    });
  
    let config = {
      type: 'doughnut',
      data: {
        datasets: [{
          borderColor: '#121212',
          borderWidth: 8,
          backgroundColor: [
            '#49C6E5',
            '#EFC7C2',
            '#00BD9D',
            '#EF476F',
            '#FFD166',
          ]
        }],
        labels: labels
      },
      options: {
        responsive: true,
        tooltips: {
  
        },
        legend: {
          position: 'top',
          onClick: null
        },
        title: {
          display: true,
          color: '#6c757d',
          text: title,
          fontFamily: "'Asap', san-serif",
          fontSize: 20,
        },
        animation: {
          animateScale: true,
          animateRotate: true,
        },
        elements: {
          center: {
            text: middleText,
            color: '#6c757d',
            fontFamily: "'Asap', san-serif",
            sidePadding: 20,
            minFontSize: 12,
            lineHeight: 25,
          }
        },
      }
    };
  
    if ( type == 0 ) {
      config.options.events = [];
      config.data.datasets[0].data = data;
    }
    else {
    //   config.data.datasets[0].data = data.map(el =&gt; el.profit);
    //   config.options.tooltips.enabled = true;
    //   config.options.tooltips.callbacks = {
    //     title: (tooltipItem, data) =&gt; {
    //       return data['labels'][tooltipItem[0]['index']];
    //     },
    //     label: (tooltipItem, data) =&gt; {
    //       return data['datasets'][0]['data'][tooltipItem['index']];
    //     },
    //     afterLabel: (tooltipItem, data) =&gt; {
    //       var dataset = data['datasets'][0];
    //       var percent = Math.round((dataset['data'][tooltipItem['index']] / dataset._meta[4].total) * 100)
          
    //       return `${percent} %`;
    //     },
    //     backgroundColor: '#FFF',
    //     titleFontSize: 16,
    //     titleFontColor: '#0066ff',
    //     bodyFontColor: '#000',
    //     bodyFontSize: 14,
    //     displayColors: false
    //   }
      config.data.datasets[0].data = data.map(el =&gt; el.profit);
    }
  
    Chart.defaults.global.defaultFontFamily = 'Asap';
    Chart.defaults.doughnut.cutoutPercentage = 80;
  
    new Chart(ctx, config);
  }
  
  
  
  
  
  const data = [
    {
      count: 8,
      profit: 20,
      sex: [0, 8, 0]
    }, 
    {
      count: 8,
      profit: 101.5,
      sex: [4, 4, 0]
    },
    {
      count: 1,
      profit: 12.5,
      sex: [1, 0, 0]
    },
    {
      count: 2,
      profit: 4,
      sex: [2, 0, 0]
    },
    {
      count: 5,
      profit: 56.5,
      sex: [5, 0, 0]
    }
  ];
  
  
  createDonatsChart(
    document.getElementById('profitPerTarget').getContext('2d'),
    'Target (di chi compra)',
    data,
    ['14-17', '18-24', '25-30', '31-40', 'Over 40'],
    `Totale ${(data.map(el =&gt; el.profit).reduce((a, b) =&gt; a + b, 0))} \u20AC`,
    1
  );</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>html, body {
    background-color: #121212;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"&gt;&lt;/script&gt;
  &lt;canvas id="profitPerTarget" height="500" style="padding: 10px"&gt;&lt;/canvas&gt;</code></pre>
  </div>
  </div>
  </p>