[Chartjs]-Always show last tooltip on all datasets, leave the rest to display on hover? ChartJS

3👍

I would try to use chartjs-plugin-datalabels for such task.

You can try it out directly on their pages – scriptable interactions

setup

Setting some random data:

var DATA_COUNT = 8;
var labels = [];

Utils.srand(100);

for (var i = 0; i < DATA_COUNT; ++i) {
  labels.push('' + i);
}

var DATA_COUNT = 8;
var labels = [];

Utils.srand(100);

for (var i = 0; i < DATA_COUNT; ++i) {
  labels.push('' + i);
}

config

Here I did some changes

{
  type: 'line',
  data: {
    labels: labels,
    datasets: [{
      label: 'France',
      backgroundColor: Utils.color(0),
      borderColor: Utils.color(0),
      data: Utils.numbers({
        count: DATA_COUNT,
        min: 10,
        max: 100
      }),
      datalabels: {
        align: function(context) {
          return context.active ? 'start' : 'center';
        }
      }
    }, {
      label: 'Canada',
      backgroundColor: Utils.color(1),
      borderColor: Utils.color(1),
      data: Utils.numbers({
        count: DATA_COUNT,
        min: 0,
        max: 100
      })
    }, {
      label: 'USA',
      backgroundColor: Utils.color(2),
      borderColor: Utils.color(2),
      data: Utils.numbers({
        count: DATA_COUNT,
        min: 0,
        max: 100
      }),
      datalabels: {
        align: function(context) {
          return context.active ? 'end' : 'center';
        }
      }
    }]
  },
  options: {
    plugins: {
      datalabels: {
        backgroundColor: function(context) {
          return context.active ? context.dataset.backgroundColor : 'white';
        },
        borderColor: function(context) {
          return context.dataset.backgroundColor;
        },
        borderRadius: function(context) {
          return context.active ? 0 : 1;
        },
        borderWidth: 1,
        color: function(context) {
          return context.active ? 'white' : context.dataset.backgroundColor;
        },
        font: {
          weight: 'bold'
        },
        formatter: function(value, context) {
          value = Math.round(value * 100) / 100;
          if (context.dataIndex === context.dataset.data.length - 1) {
            return context.dataset.label + '\n' + value + '%';
          } else {
            return context.active
              ? context.dataset.label + '\n' + value + '%'
              : ''
          }
        },
        offset: 8,
        padding: 0,
        textAlign: 'center'
      }
    },

    // Core options
    aspectRatio: 5 / 3,
    layout: {
      padding: {
        bottom: 16,
        right: 40,
        left: 8,
        top: 40
      }
    },
    hover: {
      mode: 'index',
      intersect: false
    },
    elements: {
      line: {
        fill: false
      }
    },
    scales: {
      yAxes: [{
        stacked: true
      }]
    }
  }
} 

The main part here is:

formatter: function(value, context) {
          value = Math.round(value * 100) / 100;
          if (context.dataIndex === context.dataset.data.length - 1) {
            return context.dataset.label + '\n' + value + '%';
          } else {
            return context.active
              ? context.dataset.label + '\n' + value + '%'
              : ''
          }
        },

The formatter: where I show the label permanently only for context.dataIndex === context.dataset.data.length - 1.

In other cases if it is inactive I show only empty box in other case (hover) I show the information.

How does it look?

  • No hover

No hover with mouse

  • Hover with mouse

Hover with mouse

-1👍

So this is the entire hmtl file with all relevant code. As I said, I am no programmer. This effort is from loads of trial and error, including several bits of code from stackoverflow questions.

<script>
    $(document).ready(function () {
        showtempGraph();
    });

    function showtempGraph()
    {
        {
            $.post("temperaturedata.php",
            function (data)
            {
                console.log(data);
                var temptime = [];
                var temp = [];

                for (var i in data) {
                    temptime.push(data[i].timestamp);
                    temp.push(data[i].temperature);
                }
                
                var tempmin = Math.min(...temp);
                var tempmax = Math.max(...temp);

                var charttempdata = {
                    labels: temptime,
                    datasets: [
                        {
                            label: 'Temperatur',
                            pointRadius: 3,
                            backgroundColor: 'rgba(26, 137, 245, 0.2)',
                            borderColor: 'rgba(26, 137, 245, 1)',
                            hoverBackgroundColor: 'rgba(255, 255, 255, 1)',
                            hoverBorderColor: 'rgba(255, 255, 255, 1)',
                            pointBackgroundColor: 'rgba(12, 68, 122, 1)',
                            pointHoverBorderColor: "rgba(255, 255, 255, 0.8)",
                            data: temp
                        }
                    ]
                };

                var graphtempTarget = $("#tempgraphCanvas");

                var linetempGraph = new Chart(graphtempTarget, {
                    type: 'line',
                    data: charttempdata,
                    options: {
                        maintainAspectRatio: false,
                        tooltips: {
                            enabled: true,
                            custom: function(tooltip) {
                                if (!tooltip) return;
                                tooltip.displayColors = false;
                            },
                            callbacks: {
                                title: function(tooltipItems, tempdata) {
                                return 'Klokken: ' + tooltipItems[0].xLabel;    
                                },
                                label: function(tooltipItem, tempdata) {
                                return 'Temperatur: ' + Number(tooltipItem.yLabel).toFixed(2) + '°C';
                                }
                            }

                        },
                        legend: {
                            display: false,
                        },
                        responsive: true,
                        scales: {
                          xAxes: [{
                            type: 'time',
                            time: {
                                displayFormats: {
                                    hour: 'HH:mm'
                                },
                                tooltipFormat: 'HH:mm',
                            },
                            unit : 'day',
                            gridLines: {
                              color: '#999999',
                              lineWidth: 1
                            },
                            ticks: {
                                fontColor: "#fff",
                                }                               
                          }],
                          yAxes: [
                          { 
                            type: 'linear',
                            position: 'left',
                            gridLines: {
                              color: '#999999',
                              lineWidth: 1
                            },
                            ticks: {
                                fontColor: "#fff",
                                }
                          }, {
                            type: 'linear',
                            position: "right",
                            afterUpdate: function(scaleInstance) {
                              console.dir(scaleInstance);
                            },
                            gridLines: {
                              color: '#999999)',
                              lineWidth: 0.5
                            },
                            ticks: {
                                stepSize: tempmax - tempmin,
                                min: tempmin,
                                max: tempmax,
                                mirror: true,
                                padding: -10,
                                fontColor: "#fff",
                                fontSize: 18,
                                callback: function(value) {
                                    return value + '°C';
                                }
                            },
                            scaleLabel: {
                                display: true,
                                labelString: '°C',
                                fontColor: "#fff",
                                fontSize: 14
                            }                               
                          }]
                        },
                    }
                });
            });
        }
    }
    </script>

Leave a comment