Wednesday, 26 April 2023

How to avoid positioning ChartJS's tooltip on specific datasets on a chart?

I'm using ChartJS to display stripes (ranges) and inside each stripe I'm display a line of the median value. I'm hiding the stripes' presence in both the legend and tooltip lists. That's done by adding this string in the dataset label: "HIDE!" and then just filtering out those items through the tooltip and legend options.

When I move the mouse over the chart, I've configured the tooltip to be positioned on the nearest vector, but that should only be hapenning on the line datasets, and not on the stripe datasets. Examples below:

Tooltip using a stripe as nearest vector (this is NOT ok):

problem

Tooltip using a line as nearest vector (this is ok):

tooltip on point

So the question is: How can I avoid positioning the tooltip tick on the stripes' vectors, and only use the lines' vectors for that? It seems that the filter option only hides the item from the legend list itself, but not from the graphic when it comes to position the tooltip div.

Here's my current code (you can check the jsfiddle as well):

<canvas id="rainbow"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.2.1/dist/chart.umd.min.js"></script>
<script>
var chart;
var aspectRatio = 2;
if(window.innerWidth < 600) {
    aspectRatio = 1;
}
var chartdata = {
    type: "line",
    data: {
        //months
        labels: ["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59","60"],
        datasets : [

            //##################################################

            {
                //tracking (white dotted line)
                type: 'line',
                data: [50.9,54.6,,62,,,68.3,68.9,70.5,73,74.4,,,77.5,79.7,,,82.4,,,85.7,,,88.9,90.6,90.1,,92,93,,,95.6,96.4,,99.1,98.9,,,,,,103.4,104.2,,,,,108.7,,,110.7,111.3,,111.6,,,113.5,114.1,115.7,116.3,],
                label: "name",
                borderColor: "#ffffff",
                backgroundColor: "#ffffff",
                pointRadius: 0,
                pointHitRadius: 1,
                borderWidth: 3,
                spanGaps: true,
                borderDash: [10,5]
            },

            //##################################################

            {
                //3 SD line [7]
                data: [54.7,59.5,63.2,66.1,68.6,70.7,72.5,74.2,75.8,77.4,78.9,80.3,81.7,83.1,84.4,85.7,87.0,88.2,89.4,90.6,91.7,92.9,94.0,95.0,95.8,96.4,97.4,98.4,99.4,100.3,101.3,102.2,103.1,103.9,104.8,105.6,106.5,107.3,108.1,108.9,109.7,110.5,111.2,112.0,112.7,113.5,114.2,114.9,115.7,116.4,117.1,117.7,118.4,119.1,119.8,120.4,121.1,121.8,122.4,123.1,123.7],
                label: "3 SD",
                backgroundColor: "#8ac4e8",
                borderColor: "#8ac4e8",
                pointRadius: 0,
                pointHitRadius: 5,
                borderWidth: 2
            },
            {
                //2 SD line [6]
                data: [52.9,57.6,61.1,64.0,66.4,68.5,70.3,71.9,73.5,75.0,76.4,77.8,79.2,80.5,81.7,83.0,84.2,85.4,86.5,87.6,88.7,89.8,90.8,91.9,92.6,93.1,94.1,95.0,96.0,96.9,97.7,98.6,99.4,100.3,101.1,101.9,102.7,103.4,104.2,105.0,105.7,106.4,107.2,107.9,108.6,109.3,110.0,110.7,111.3,112.0,112.7,113.3,114.0,114.6,115.2,115.9,116.5,117.1,117.7,118.3,118.9],
                label: "2 SD",
                backgroundColor: "#80a3e6",
                borderColor: "#80a3e6",
                pointRadius: 0,
                pointHitRadius: 5,
                borderWidth: 2
            },
            {
                //1 SD line [5]
                data: [51.0,55.6,59.1,61.9,64.3,66.2,68.0,69.6,71.1,72.6,73.9,75.3,76.6,77.8,79.1,80.2,81.4,82.5,83.6,84.7,85.7,86.7,87.7,88.7,89.3,89.9,90.8,91.7,92.5,93.4,94.2,95.0,95.8,96.6,97.4,98.1,98.9,99.6,100.3,101.0,101.7,102.4,103.1,103.8,104.5,105.1,105.8,106.4,107.0,107.7,108.3,108.9,109.5,110.1,110.7,111.3,111.9,112.5,113.0,113.6,114.2],
                label: "1 SD",
                backgroundColor: "#7780e4",
                borderColor: "#7780e4",
                pointRadius: 0,
                pointHitRadius: 5,
                borderWidth: 2
            },
            {
                //Median [4]
                data: [49.1,53.7,57.1,59.8,62.1,64.0,65.7,67.3,68.7,70.1,71.5,72.8,74.0,75.2,76.4,77.5,78.6,79.7,80.7,81.7,82.7,83.7,84.6,85.5,86.1,86.6,87.4,88.3,89.1,89.9,90.7,91.4,92.2,92.9,93.6,94.4,95.1,95.7,96.4,97.1,97.7,98.4,99.0,99.7,100.3,100.9,101.5,102.1,102.7,103.3,103.9,104.5,105.0,105.6,106.2,106.7,107.3,107.8,108.4,108.9,109.4],
                label: "Median",
                backgroundColor: "#8c77e4",
                borderColor: "#8c77e4",
                pointRadius: 0,
                pointHitRadius: 5,
                borderWidth: 2
            },
            {
                //-1 SD line [3]
                data: [47.3,51.7,55.0,57.7,59.9,61.8,63.5,65.0,66.4,67.7,69.0,70.3,71.4,72.6,73.7,74.8,75.8,76.8,77.8,78.8,79.7,80.6,81.5,82.3,82.9,83.3,84.1,84.9,85.7,86.4,87.1,87.9,88.6,89.3,89.9,90.6,91.2,91.9,92.5,93.1,93.8,94.4,95.0,95.6,96.2,96.7,97.3,97.9,98.4,99.0,99.5,100.1,100.6,101.1,101.6,102.2,102.7,103.2,103.7,104.2,104.7],
                label: "-1 SD",
                backgroundColor: "#aa78e5",
                borderColor: "#aa78e5",
                pointRadius: 0,
                pointHitRadius: 5,
                borderWidth: 2
            },
            {
                //-2 SD line [2]
                data: [45.4,49.8,53.0,55.6,57.8,59.6,61.2,62.7,64.0,65.3,66.5,67.7,68.9,70.0,71.0,72.0,73.0,74.0,74.9,75.8,76.7,77.5,78.4,79.2,79.7,80.0,80.8,81.5,82.2,82.9,83.6,84.3,84.9,85.6,86.2,86.8,87.4,88.0,88.6,89.2,89.8,90.4,90.9,91.5,92.0,92.5,93.1,93.6,94.1,94.6,95.1,95.6,96.1,96.6,97.1,97.6,98.1,98.5,99.0,99.5,99.9],
                label: "-2 SD",
                backgroundColor: "#c97be5",
                borderColor: "#c97be5",
                pointRadius: 0,
                pointHitRadius: 5,
                borderWidth: 2
            },
            {
                //-3 SD line [1]
                data: [43.6,47.8,51.0,53.5,55.6,57.4,58.9,60.3,61.7,62.9,64.1,65.2,66.3,67.3,68.3,69.3,70.2,71.1,72.0,72.8,73.7,74.5,75.2,76.0,76.4,76.8,77.5,78.1,78.8,79.5,80.1,80.7,81.3,81.9,82.5,83.1,83.6,84.2,84.7,85.3,85.8,86.3,86.8,87.4,87.9,88.4,88.9,89.3,89.8,90.3,90.7,91.2,91.7,92.1,92.6,93.0,93.4,93.9,94.3,94.7,95.2],
                label: "-3 SD",
                backgroundColor: "#dc7db7",
                borderColor: "#dc7db7",
                pointRadius: 0,
                pointHitRadius: 5,
                borderWidth: 2
            },

            //##################################################

            {
                //3 SD stripe [7]
                data: [55.6,60.45,64.25,67.15,69.7,71.8,73.6,75.35,76.95,78.6,80.15,81.55,82.95,84.4,85.75,87.05,88.4,89.6,90.85,92.1,93.2,94.45,95.6,96.55,97.4,98.05,99.05,100.1,101.1,102,103.1,104,104.95,105.7,106.65,107.45,108.4,109.25,110.05,110.85,111.7,112.55,113.2,114.05,114.75,115.6,116.3,117,117.9,118.6,119.3,119.9,120.6,121.35,122.1,122.65,123.4,124.15,124.75,125.5,126.1],
                label: "HIDE!3 SD",
                borderColor: "#7bb5d9",
                backgroundColor: "#7bb5d9",
                pointRadius: 0,
                pointHitRadius: 0,
                pointHoverRadius: 0,
                borderWidth: 1,
                fill: 9
            },
            {
                //2 SD stripe [6]
                data: [53.8,58.55,62.15,65.05,67.5,69.6,71.4,73.05,74.65,76.2,77.65,79.05,80.45,81.8,83.05,84.35,85.6,86.8,87.95,89.1,90.2,91.35,92.4,93.45,94.2,94.75,95.75,96.7,97.7,98.6,99.5,100.4,101.25,102.1,102.95,103.75,104.6,105.35,106.15,106.95,107.7,108.45,109.2,109.95,110.65,111.4,112.1,112.8,113.5,114.2,114.9,115.5,116.2,116.85,117.5,118.15,118.8,119.45,120.05,120.7,121.3],
                label: "HIDE!2 SD",
                borderColor: "#7194d7",
                backgroundColor: "#7194d7",
                pointRadius: 0,
                pointHitRadius: 0,
                pointHoverRadius: 0,
                borderWidth: 1,
                fill: 10
            },
            {
                //1 SD stripe [5]
                data: [51.95,56.6,60.1,62.95,65.35,67.35,69.15,70.75,72.3,73.8,75.15,76.55,77.9,79.15,80.4,81.6,82.8,83.95,85.05,86.15,87.2,88.25,89.25,90.3,90.95,91.5,92.45,93.35,94.25,95.15,95.95,96.8,97.6,98.45,99.25,100,100.8,101.5,102.25,103,103.7,104.4,105.15,105.85,106.55,107.2,107.9,108.55,109.15,109.85,110.5,111.1,111.75,112.35,112.95,113.6,114.2,114.8,115.35,115.95,116.55],
                label: "HIDE!1 SD",
                borderColor: "#6871d5",
                backgroundColor: "#6871d5",
                pointRadius: 0,
                pointHitRadius: 0,
                pointHoverRadius: 0,
                borderWidth: 1,
                fill: 11
            },

            //##################################################

            {
                //Median stripe [4]
                data: [50.05,54.65,58.1,60.85,63.2,65.1,66.85,68.45,69.9,71.35,72.7,74.05,75.3,76.5,77.75,78.85,80,81.1,82.15,83.2,84.2,85.2,86.15,87.1,87.7,88.25,89.1,90,90.8,91.65,92.45,93.2,94,94.75,95.5,96.25,97,97.65,98.35,99.05,99.7,100.4,101.05,101.75,102.4,103,103.65,104.25,104.85,105.5,106.1,106.7,107.25,107.85,108.45,109,109.6,110.15,110.7,111.25,111.8],
                label: "HIDE!Median",
                borderColor: "#7d68d5",
                backgroundColor: "#7d68d5",
                pointRadius: 0,
                pointHitRadius: 0,
                pointHoverRadius: 0,
                borderWidth: 1,
                fill: 12
            },

            //##################################################

            {
                //-1 SD stripe [3]
                data: [48.2,52.7,56.05,58.75,61,62.9,64.6,66.15,67.55,68.9,70.25,71.55,72.7,73.9,75.05,76.15,77.2,78.25,79.25,80.25,81.2,82.15,83.05,83.9,84.5,84.95,85.75,86.6,87.4,88.15,88.9,89.65,90.4,91.1,91.75,92.5,93.15,93.8,94.45,95.1,95.75,96.4,97,97.65,98.25,98.8,99.4,100,100.55,101.15,101.7,102.3,102.8,103.35,103.9,104.45,105,105.5,106.05,106.55,107.05],
                label: "HIDE!-1 SD",
                borderColor: "#9b69d6",
                backgroundColor: "#9b69d6",
                pointRadius: 0,
                pointHitRadius: 0,
                pointHoverRadius: 0,
                borderWidth: 1,
                fill: 13
            },
            {
                //-2 SD stripe [2]
                data: [46.35,50.75,54,56.65,58.85,60.7,62.35,63.85,65.2,66.5,67.75,69,70.15,71.3,72.35,73.4,74.4,75.4,76.35,77.3,78.2,79.05,79.95,80.75,81.3,81.65,82.45,83.2,83.95,84.65,85.35,86.1,86.75,87.45,88.05,88.7,89.3,89.95,90.55,91.15,91.8,92.4,92.95,93.55,94.1,94.6,95.2,95.75,96.25,96.8,97.3,97.85,98.35,98.85,99.35,99.9,100.4,100.85,101.35,101.85,102.3],
                label: "HIDE!-2 SD",
                borderColor: "#ba6cd6",
                backgroundColor: "#ba6cd6",
                pointRadius: 0,
                pointHitRadius: 0,
                pointHoverRadius: 0,
                borderWidth: 1,
                fill: 14
            },
            {
                //-3 SD stripe [1]
                data: [44.5,48.8,52,54.55,56.7,58.5,60.05,61.5,62.85,64.1,65.3,66.45,67.6,68.65,69.65,70.65,71.6,72.55,73.45,74.3,75.2,76,76.8,77.6,78.05,78.4,79.15,79.8,80.5,81.2,81.85,82.5,83.1,83.75,84.35,84.95,85.5,86.1,86.65,87.25,87.8,88.35,88.85,89.45,89.95,90.45,91,91.45,91.95,92.45,92.9,93.4,93.9,94.35,94.85,95.3,95.75,96.2,96.65,97.1,97.55],
                label: "HIDE!-3 SD",
                borderColor: "#cd6ea8",
                backgroundColor: "#cd6ea8",
                pointRadius: 0,
                pointHitRadius: 0,
                pointHoverRadius: 0,
                borderWidth: 1,
                fill: 15
            },

            //##################################################

            {
                //artificial base
                data: [42.7,46.8,50,52.45,54.5,56.3,57.75,59.1,60.55,61.7,62.9,63.95,65,65.95,66.95,67.95,68.8,69.65,70.55,71.3,72.2,73,73.6,74.4,74.75,75.2,75.85,76.4,77.1,77.8,78.35,78.9,79.5,80.05,80.65,81.25,81.7,82.3,82.75,83.35,83.8,84.25,84.75,85.35,85.85,86.35,86.8,87.15,87.65,88.15,88.5,89,89.5,89.85,90.35,90.7,91.05,91.6,91.95,92.3,92.85],
                label: "HIDE!lower",
                borderColor: "transparent",
                backgroundColor: "transparent",
                pointRadius: 0,
                pointHitRadius: 5,
                borderWidth: 1,
                fill: false
            }
        ]
    },

    //configuration options
    options: {
        animation: true,
        aspectRatio: aspectRatio,
        interaction: {
            intersect: false,
            mode: 'index',
            axis: 'x'
        },
        scales: {
            x: {
                label: "time",
                grid: {
                    display: true
                },

            },
            y: {
                label: "meassure",
                grid: {
                    display: true
                },
                stacked: false,
                beginAtZero: false,
                position: "right",
                ticks: {
                    callback: function(val, index) {
                        return parseInt(val) + ' cm';
                    }
                }
            }
        },
        plugins: {
            tooltip: {
                position: 'nearest',
                caretSize: 7,
                caretPadding: 10,
                filter: function (tooltipItem, data) {
                    if(tooltipItem.dataset.label.includes('HIDE!')) {
                        return false;
                    }
                    return true;
                }
            },
            legend: {
                display: true,
                position: 'top',
                labels: {
                    font: {
                        size: 14,
                        family: 'Inter, "sans-serif"'
                    },
                    filter: function(item, chart) {
                        return !item.text.includes('HIDE!');
                    }
                }
            }
        }
    }
}
const orgdata = JSON.parse(JSON.stringify(chartdata));

//draw chart
document.addEventListener('DOMContentLoaded', function(event) {
    var ctx = document.getElementById('rainbow').getContext('2d');
    chart = new Chart(ctx, chartdata);
});
</script>


from How to avoid positioning ChartJS's tooltip on specific datasets on a chart?

No comments:

Post a Comment