Search code examples
jqueryhtmltooltipchart.js

Chart JS - single lines (points) tooltips


How do I get to ChartJS returns only the value of a point on the graph (on mouse over), instead of the whole dataset?

    <table>
<tr>
<td>
    <div style="width:30%">
        <div>
            <canvas id="canvas" height="600" width="1000"></canvas>

        </div>
    </div>
    </td>
    <td style="text-align:center;"><div id="placeholder" height="450" width="600"></div>

    <script>
    var lineChartData = {
        labels : [<?php echo $_SESSION['GRAFICO2']; ?>],
        datasets : [<?php echo $_SESSION[$_GET['vGrafico']]; ?>

        ]

    }


window.onload = function(){
    var ctx = document.getElementById("canvas").getContext("2d");
    window.myLine = new Chart(ctx).Line(lineChartData, {bezierCurve: false, pointDot : true, datasetStroke : true, showTooltips: true, pointHitDetectionRadius : 2, offsetGridLines : true, TooltipTemplate: "<%= label %> - <%= data %>"});
    legend(document.getElementById('placeholder'), lineChartData);
}

</script>

Like this now - than


Solution

  • You can do this by overriding the showTooltip of the chart and inRange methods of the points.

    Preview

    enter image description here


    Script

    ...
    var myChart = new Chart(ctx).Line(data);
    
    // Chart.js replaces the base inRange function for Line points with a function that checks only the x coordinate
    // we replace it with the original inRange fucntion (one that checks both x and y coordinates)
    myChart.datasets.forEach(function(dataset){
      dataset.points.forEach(function(point){
        point.inRange = Chart.Point.prototype.inRange;
      });
    });
    
    // Chart.js shows a multiTooltip based on the index if it detects that there are more than one datasets
    // we override it to show a single tooltip for the inRange element
    myChart.showTooltip = function(ChartElements, forceRedraw) {
      // this clears out the existing canvas - the actual Chart.js library code is a bit more optimized with checks for whether active points have changed, etc.
      this.draw();
      // draw tooltip for active elements (if there is one)
      Chart.helpers.each(ChartElements, function(Element){
          var tooltipPosition = Element.tooltipPosition();
          new Chart.Tooltip({
            x: Math.round(tooltipPosition.x),
            y: Math.round(tooltipPosition.y),
            xPadding: this.options.tooltipXPadding,
            yPadding: this.options.tooltipYPadding,
            fillColor: this.options.tooltipFillColor,
            textColor: this.options.tooltipFontColor,
            fontFamily: this.options.tooltipFontFamily,
            fontStyle: this.options.tooltipFontStyle,
            fontSize: this.options.tooltipFontSize,
            caretHeight: this.options.tooltipCaretSize,
            cornerRadius: this.options.tooltipCornerRadius,
            text: Chart.helpers.template(this.options.tooltipTemplate, Element),
            chart: this.chart,
            custom: this.options.customTooltips
          }).draw();
        }, this);
    }
    

    The obvious downside is that if there are 2 (or more) points close together, you'll see multiple tooltips that might possible overlap.


    Fiddle - http://jsfiddle.net/v7mtz64o/