Always display ChartJS custom tooltips

泪湿孤枕 提交于 2019-12-10 19:07:10

问题


After following several guides on here and from the official docs, I am absolutely stuck.

I have some custom tooltips that will display a PNG graphic within it based on the name of the data in the custom tooltip.

I have found several solutions to hide tooltips, or set them all to be always displayed, but none of them seem to work as I would like. I want the standard tooltips hidden, and my custom ones always shown.

My code is as follows:

HTML:

<canvas id="pelagic" style="width:10vw;height:10vw;"></canvas>
<div id="chartjs-tooltip">
     <table></table>
</div>

CSS:

#chartjs-tooltip {
  opacity: 1;
  position: absolute;
  color: white;
  border-radius: 3px;
  -webkit-transition: all .1s ease;
  transition: all .1s ease;
  pointer-events: none;
  -webkit-transform: translate(-50%, 0);
  transform: translate(-50%, 0);
}

.chartjs-tooltip-key {
  display: inline-block;
  width: 10px;
  height: 10px;
}

Javascript

var ctx4 = document.getElementById("pelagic").getContext('2d');
var seafood_pelagic = {
    "labels":["Welsh Fleet Mackerel","Herring","Other Pelagic"],
    "datasets":[
        {
            "label":"2013",
            "data":["1.90","0.50","0.30","0.30","0.30"],
            "backgroundColor":["#95c11e","#007e3b","#3aa935","#14af97","#88f88f"],
            "borderWidth": "2",
            "borderColor":["#95c11e","#007e3b","#3aa935","#14af97","#88f88f"]
        }
        ]
};

var seafood_pelagic = new Chart(ctx4, {
    type: 'doughnut',
    data: seafood_pelagic,
    options: {
        showAllTooltips: true,
        cutoutPercentage: 85,
        responsive: false,
        animation: false,
        legend: {
            display: false
        },
        tooltips: {
            enabled: false,
            callbacks: {
                label: function(tooltipItem, data) { 
                    var indice = tooltipItem.index;                 
                    return  data.labels[indice];
                }
            },
            custom: customTooltips
        }
    }
});

var customTooltips = function(tooltip) {
    // Tooltip Element
    var tooltipEl = document.getElementById('chartjs-tooltip');
        // Hide if no tooltip
        if (tooltip.opacity === 0) {
            tooltipEl.style.opacity = 1;
            return;
        }
    if (!tooltipEl) {
        tooltipEl = document.createElement('div');
        tooltipEl.id = 'chartjs-tooltip';
        tooltipEl.innerHTML = '<table></table>';
        this._chart.canvas.parentNode.appendChild(tooltipEl);
            tooltipEl.style.opacity = 1;
    }
    function getBody(bodyItem) {
        return bodyItem.lines;
    }
    // Set Text
    if (tooltip.body) {
        var titleLines = tooltip.title || [];
        var bodyLines = tooltip.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 = tooltip.labelColors[i];
            var style = 'background:' + colors.backgroundColor;
            style += '; border-color:' + colors.borderColor;
            style += '; border-width: 2px';
            var span = '<span class="chartjs-tooltip-key" style="' + style + '"></span>';
            innerHtml += '<tr><td><img src="../images/' + body + '-pelagic.png">' + span +  '</td></tr>';
        });
        innerHtml += '</tbody>';

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

    var positionY = this._chart.canvas.offsetTop;
    var positionX = this._chart.canvas.offsetLeft;

    // 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.fontFamily = tooltip._bodyFontFamily;
    tooltipEl.style.fontSize = tooltip.bodyFontSize + 'px';
    tooltipEl.style.fontStyle = tooltip._bodyFontStyle;
    tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px';
};

Any ideas? It works as far as it displays the image on hover, and the image doesn't disappear until you hover over the next slice of the doughnut (rather than disappearing straight away like it usually does). I'm ready to bang my head against a brick wall!


回答1:


I'm facing similar problem - my custom tooltip did pop up, but didn't go away automatically. I found out the tooltips 'callbacks' and 'custom' config cannot be used together. I don't know if this is by design or a bug.

In below config, you will have to remove 'callbacks' section. You loose the formatting of the label, so your custom tooltip component should then be updated/altered so the formatting is done there).

 tooltips: {
        enabled: false,
        callbacks: {
            label: function(tooltipItem, data) { 
                var indice = tooltipItem.index;                 
                return  data.labels[indice];
            }
        },
        custom: customTooltips
    }



回答2:


Oh man, I suppose is late, but others could find useful your code, so I've to say that there's a little and trivial error:

if (tooltip.opacity === 0) {
    tooltipEl.style.opacity = 1;
    return;
}

You have to set tooltip element opacity to 0! 🙈



来源:https://stackoverflow.com/questions/52299884/always-display-chartjs-custom-tooltips

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!