user4675957
user4675957

Reputation: 243

chartjs show dot point on hover over line chart

I am using Chartjs v.1.0.2 and trying to set a point dot only to appear on hover over chart. After it it should be removed. I have managed to show it, by changing the object value, but it is not fluid motion and it doesn't show point always. This also doesn't hide it on hover out. How can it be fluid and hide when mouse is not over?

window.onload = function(){

        var ctx = $("#chart1").get(0).getContext("2d");
                var chart1 = new Chart(ctx).Line(data1, options);


                $("#chart1").hover(function(e) {
                    var activeBars = chart1.getPointsAtEvent(e); 
                    activeBars[0].display = true;
//                    console.log(activeBars[0]);
                    chart1.update();
                 });

    };

    var data1 = {
            labels: ["January", "February", "March", "April", "May", "June", "July"],
            datasets: [
                {
                    label: "My First dataset",
                    fillColor: "rgba(95,186,88,0.7)",
                    strokeColor: "rgba(95,186,88,1)",
                    pointColor: "rgba(95,186,88,1)",
                    pointStrokeColor: "#fff",
                    pointHighlightFill: "#fff",
                    pointHighlightStroke: "rgba(220,220,220,1)",
                    data: [65, 59, 80, 81, 56, 55, 40]
                }
            ]
    };



var options = {
    responsive: true,
    bezierCurve : false,
    scaleShowLabels: false,
    scaleFontSize: 0,
    pointDot : false,
    scaleBeginAtZero: true,
    scaleShowHorizontalLines: false,
    scaleShowVerticalLines: true,
    scaleGridLineColor : "rgba(232,232,232)",
    showTooltips: true,

    customTooltips: function (tooltip) {
        var tooltipEl = $('#chartjs-tooltip');

        if (!tooltip) {
            tooltipEl.css({
                opacity: 0
            });
            return;
        }

        tooltipEl.removeClass('above below');
        tooltipEl.addClass(tooltip.yAlign);

        // split out the label and value and make your own tooltip here
        var parts = tooltip.text.split(":");
        var innerHtml = '<span>' + parts[0].trim() + '</span> : <span><b>' + parts[1].trim() + '</b></span>';
        tooltipEl.html(innerHtml);

        tooltipEl.css({
            opacity: 1,
            left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
            top: tooltip.chart.canvas.offsetTop + tooltip.y + 'px',
            fontFamily: tooltip.fontFamily,
            fontSize: tooltip.fontSize,
            fontStyle: tooltip.fontStyle,
        });
    }

};

simplified fiddle

Upvotes: 13

Views: 32887

Answers (5)

bodja
bodja

Reputation: 196

Tested with Chart.js v2.6.0

Global setting will do the trick:

Chart.defaults.global.hover.intersect = false;

Or directly in chart config:

options: {
  hover: {
    intersect: false;
  }
}

And point settings for dataset.

  • initial color of the point should be transparent
  • hover color must be set to the desired color

e.g.

datasets: [{
  label: 'My First dataset',
  borderColor: 'rgb(255, 99, 132)',
  backgroundColor: 'rgb(255, 99, 132)',
  data: [10, 30, 46, 2, 8, 50, 0],
  fill: false,
  pointBorderColor: 'rgba(0, 0, 0, 0)',
  pointBackgroundColor: 'rgba(0, 0, 0, 0)',
  pointHoverBackgroundColor: 'rgb(255, 99, 132)',
  pointHoverBorderColor: 'rgb(255, 99, 132)'}],...

const mode = 'index';
const intersect = false;
const config = {
  type: 'line',
  data: {
    labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
    datasets: [{
      label: 'My First dataset',
      borderColor: 'rgb(255, 99, 132)',
      backgroundColor: 'rgb(255, 99, 132)',
      data: [10, 30, 46, 2, 8, 50, 0],
      fill: false,
      pointBorderColor: 'rgba(0, 0, 0, 0)',
      pointBackgroundColor: 'rgba(0, 0, 0, 0)',
      pointHoverBackgroundColor: 'rgb(255, 99, 132)',
      pointHoverBorderColor: 'rgb(255, 99, 132)',
    }, {
      label: 'My Second dataset',
      borderColor: 'rgb(54, 162, 235)',
      backgroundColor: 'rgb(54, 162, 235)',
      data: [7, 49, 46, 13, 25, 30, 22],
      fill: false,
      pointBorderColor: 'rgba(0, 0, 0, 0)',
      pointBackgroundColor: 'rgba(0, 0, 0, 0)',
      pointHoverBackgroundColor: 'rgb(54, 162, 235)',
      pointHoverBorderColor: 'rgb(54, 162, 235)',
    }]
  },
  options: {
    responsive: true,
    title: {
      display: true,
      text: 'Mode: index, intersect = false'
    },
    tooltips: {
      mode: 'index',
      intersect: intersect,
    },
    hover: {
      mode: mode,
      intersect: intersect
    },
  }
};
const ctx = document.getElementById('canvas').getContext('2d');
const chart = new Chart(ctx, config);
<canvas id="canvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>

Upvotes: 14

Teocci
Teocci

Reputation: 8865

This is a six years old question but I think in 2022 we can use ChartJS version 4.0.1.

ChartJS supports interactions behavior, and they can be configured via interaction, hover or tooltips settings on the chart configuration.

For this we will use the hover setting and select the index mode. This mode finds an item at the same index. If the intersect setting is false the nearest item, in the x direction, is used to determine the index.

Here is a working snippet

const data = {
  labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
  datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      borderWidth: 1
    },
    {
      label: '# of Points',
      data: [7, 11, 5, 8, 3, 7],
      borderWidth: 1
    }
  ]
}
const options = {
  maintainAspectRatio: false,
  elements: {
    point: {
      hoverRadius: 6,
    },
  },
  hover: {
    mode: 'index',
    intersect: false,
  },
}
  
const config = {
  type: 'line',
  data,
  options,
}

const $chart = document.getElementById('chart')
const chart = new Chart($chart, config)
<div class="wrapper" style="width: 98vw; height: 180px">
  <canvas id="chart"></canvas>
</div>

<script src="https://unpkg.com/[email protected]/dist/chart.umd.js"></script>

Upvotes: 1

schaazzz
schaazzz

Reputation: 568

Edit: The following solution is for Chart.js v1.0.2 (the latest version at the time this solution was proposed). Please refer to this answer which provides a solution for Chart.js v2.x.x.


I ran into a similar situation a while back and resolved this by making the default point dot "invisible" as follows:

  • setting pointDotRadius to 1
  • setting pointStrokeColor to white with the alpha set to 0

The two steps above make the default point dot very small, this, in combination with the transparent point stroke, makes the default point dot invisible. Now if we make the pointDotStrokeWidth large enough, we can achieve the desired hover effect. i.e.

  • set pointDotStrokeWidth to a larger value (I used 8)
  • set the desired values for pointColor, pointHighlightFill, pointHighlightStroke

[Note: the same effect can be achieved by making pointColor transparent but if you are plotting multiple datasets, then the tooltip wouldn't show the corresponding line color next to the data value.]

Example below (or you can checkout this Fiddle: ChartJS - Show Points on Hover):

var data = {
  labels: ["Point0", "Point1", "Point2", "Point3", "Point4"],
  datasets: [
    {
      label: "My Chart",
      fillColor: "rgba(87, 167, 134, 0.2)",
      strokeColor: "rgba(87, 167, 134, 1)",
      pointColor: "rgba(87, 167, 134, 1)",
      pointStrokeColor: "rgba(255, 255, 255, 0)",
      pointHighlightFill: "rgba(87, 167, 134, 0.7)",
      pointHighlightStroke: "rgba(87, 167, 134, 1)",
      data: [5, 39, 109, 19, 149]
    }
  ]
};
var ctx = document.getElementById("my_chart").getContext("2d");
myChart = new Chart(ctx).Line(data, {
  responsive : true,
  bezierCurve: false,
  datasetFill: true,
  pointDotRadius: 1,
  pointDotStrokeWidth: 8,
  pointHitDetectionRadius: 20,
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<canvas id="my_chart"></canvas>

Upvotes: 5

Shameem Ahmed Mulla
Shameem Ahmed Mulla

Reputation: 656

Try using mouseover and mouseout as shown below. Similarly you can also use mouseenter and mouseleave methods to handle events.

$("#chart1").mouseover(function(e) {
                var activeBars = chart1.getPointsAtEvent(e); 
                activeBars[0].display = true;
                chart1.update();
             });

$("#chart1").mouseout(function(e) {
                var activeBars = chart1.getPointsAtEvent(e); 
                activeBars[0].display = false;
                chart1.update();
             });

Upvotes: 0

potatopeelings
potatopeelings

Reputation: 41065

$("#chart1").mouseover(function(e) {
    chart1.datasets[0].points[0].display = true;
    chart1.update();
 });
$("#chart1").mouseout(function(e) {
    chart1.datasets[0].points[0].display = false;
    chart1.update();
 });

Upvotes: 1

Related Questions