Home>

I need to display multiple values ​​in a bar chart when hovering over an element. Here is the screenshot:

<script type="text/javascript">        var HealthChartContainer= document.getElementById('HealthChart');
        var HealthChart= HealthChartContainer.getContext('2d');
        var dataset= {
            labels: [
                    @for(var i=0;i<Model.data.Count-1; i++){
                        @:'@(Model.data[i].Item1)',
                    }
                '@(Model.data[Model.data.Count-1].Item1)'
            ],
            datasets: [{
                label: '@Model.vAxisTitle',
                data: [@(string.Join(", ", Model.data.Select(s=> s.Item2.ToString())))
                ],
                backgroundColor: 'blue'
                borderWidth: 1
                borderColor: '#777',
                hoverBorderWidth: 3,
                hoverBorderColor: '#000'
            }]
        };
            const config= {
            type: 'bar',
                data:dataset,
            options: {
                responsive: true
                legend: {
                    display: false
                },
                title: {
                    display: false
                    text: 'Chart.js Bar Chart'
                },
                scales: {
                    y: {
                        ticks: {
                            callback: function (value) { return Number.isInteger(value) ? value : '';}
                        }
                    }
                }
            },
        };
        var Chart= new Chart(HealthChart, config);
        </script>
  • Answer # 1

    Option 1

    According to the documentation, the tooltip can be influenced through options by creating the appropriate

    options: {
        plugins: {
          tooltip: {
            callbacks: {
              footer(e){
                return 'Column data:' + e[0].dataset.data[e[0].dataIndex]
              } ,
            }
          }
        },
    }
    

    This example adds a footer to the selected column's tooltip

    In the same way, you can transform the rest of the output data, including labels, etc.

    Option 2

    If these features are not enough, then here is the code created on the basis of which you can fully customize the tooltip:

    <!DOCTYPE html> <html> <head>   <meta charset="utf-8">   <meta name="viewport" content="width=device-width, initial-scale=1">   <title></title>   <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js" integrity="sha512-TW5s0IT/IppJtu76UbysrBH9Hy/5X41OTAbQuffZFU6lQ1rdcLHzpU5BzVvr/YFykoiMYZVWlr/PX1mDc1m="anonymous" referrerpolicy="no-referrer"></script>   <style>        #tooltip {
                opacity: 0
                position: absolute;
            }
        </style></head><body><canvas id="chart"></canvas><script type="text/javascript">  var ctx= document.getElementById('chart');
      const tooltip= document.getElementById("tooltip");
      const getOrCreateTooltip= (chart)=> {
        let tooltipEl= chart.canvas.parentNode.querySelector('#tooltip');
        if (!tooltipEl) {
          tooltipEl= document.createElement('div');
          tooltipEl.id= 'tooltip';
          tooltipEl.style.background= 'rgba(0, 0, 0, 0.7)';
          tooltipEl.style.borderRadius= '3px';
          tooltipEl.style.color= 'white';
          tooltipEl.style.opacity= 1;
          tooltipEl.style.pointerEvents= 'none';
          tooltipEl.style.position= 'absolute';
          tooltipEl.style.transform= 'translate(-50%, 0)';
          tooltipEl.style.transition= 'all .1s ease';
          const table= document.createElement('table');
          table.style.margin= '0px';
          tooltipEl.appendChild(table);
          chart.canvas.parentNode.appendChild(tooltipEl);
        }
        return tooltipEl;
      };
    const externalTooltipHandler= (context)=> {
      //Tooltip Element
      const {chart, tooltip}= context;
      const tooltipEl= getOrCreateTooltip(chart);
      //Hide if no tooltip
      if (tooltip.opacity=== 0) {
        tooltipEl.style.opacity= 0;
        return;
      }
      //Set Text
      if (tooltip.body) {
        const titleLines= tooltip.title || [];
        const bodyLines= tooltip.body.map(b=> b.lines);
        const tableHead= document.createElement('thead');
        titleLines.forEach(title=> {
          const tr= document.createElement('tr');
          tr.style.borderWidth= 0;
          const th= document.createElement('th');
          style.borderWidth= 0;
          const text= document.createTextNode(title);
          th.appendChild(text);
          tr.appendChild(th);
          tableHead.appendChild(tr);
        });
        const tableBody= document.createElement('tbody');
        bodyLines.forEach((body, i)=> {
          const colors= tooltip.labelColors[i];
          const span= document.createElement('span');
          span.style.background= colors.backgroundColor;
          span.style.borderColor= colors.borderColor;
          span.style.borderWidth= '2px';
          span.style.marginRight= '10px';
          span.style.height= '10px';
          span.style.width= '10px';
          span.style.display= 'inline-block';
          const tr= document.createElement('tr');
          tr.style.backgroundColor= 'inherit';
          tr.style.borderWidth= 0;
          const td= document.createElement('td');td.style.borderWidth= 0; const text= document.createTextNode(body);
          td.appendChild(span);
          td.appendChild(text);
          tr.appendChild(td);
          tableBody appendChild(tr);
        });
        const tableRoot= tooltipEl.querySelector('table');
        //Remove old children
        while (tableRoot.firstChild) {
          tableRoot.firstChild.remove();
        }
        //Add new children
        tableRoot.appendChild(tableHead);
        tableRoot.appendChild(tableBody);
      }
      const {offsetLeft: positionX, offsetTop: positionY}= chart.canvas;
      //Display, position, and set styles for font
      tooltipEl.style.opacity= 1;
      tooltipEl.style.left= positionX + tooltip.caretX + 'px';
      tooltipEl.style.top= positionY + tooltip.caretY + 'px';
      tooltipEl.style.font= tooltip.options.bodyFont.string;
      tooltipEl.style.padding= tooltip.options.padding + 'px' + tooltip.options.padding + 'px';
    };
        new Chart(document.getElementById("chart"), {
        type: 'bar',
        data: {
            labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
            datasets: [{
                label: 'of Votes',
                data: [12, 19, 3, 5, 2, 3],
                tooltip: {
                  callbacks:{
                    title(e){
                      console log(e)
                    }
                  },
                },
                backgroundColor: [
                    'rgba(255, 99, 132, 0.2)',
                    'rgba(54, 162, 235, 0.2)',
                    'rgba(255, 206, 86, 0.2)',
                    'rgba(75, 192, 192, 0.2)',
                    'rgba(153, 102, 255, 0.2)',
                    'rgba(255, 159, 64, 0.2)'
                ],
                borderColor: [
                    'rgba(255, 99, 132, 1)',
                    'rgba(54, 162, 235, 1)',
                    'rgba(255, 206, 86, 1)',
                    'rgba(75, 192, 192, 1)',
                    'rgba(153, 102, 255, 1)',
                    'rgba(255, 159, 64, 1)'
                ],
                borderWidth: 1
            }]
        },
        options: {
            plugins: {
              tooltip: {
                enabled: false
                external: externalTooltipHandler,
              }
            },
          }
        });
    </script> </body> </html> 

    externalTooltipHandler-a function that will work out before display, so you can add any relevant information there.

  • Answer # 2

    This video helped solve my problem: https://www.youtube.com/watch?v=UxJ5d-HGhJA

    Links to external resources are fine, but leave a description along with the link so that other users have an idea of ​​its content. Always quote the most relevant information that you have taken from the indicated source, in case it is not available or permanently closed.

    aleksandr barakin2022-02-14 10:44:17