Hi,
I'm using Chart.js v2 and I want to be able to have a vertical line when moving the mouse, which displays the current tooltip, when the point is hit. Have found many things on StackOverflow, but they were written for Chart.js v1 + not what I needed.
I know, an Image doesn't help much, but anyway, here's what it should look like (imagine moving the mouse):

@visualcookie have you tried using https://github.com/chartjs/chartjs-plugin-annotation and updating it on mousemove?
@etimberg Have heard about it, but I have no idea on how to update it on mousemove tbh.
another alternative would be to use the work in #3718 (will be released in v2.5) and write a plugin that responds to onEvent and uses that to configure some kind of internal setting for drawing. I'll try and put together a sample tonight in a fiddle
@visualcookie here's a quick sample of my plugin idea. https://jsfiddle.net/hev1nonk/ It tracks the mouse movements to draw the vertical line. If you have lots of points the tooltip will be mostly correct. At the moment, there is no support for interpolated tooltips so you'd have to do that yourself but it's a starting point
@etimberg Great, thanks. How would this work with multiple Charts? I'm currently getting errors in console:
Uncaught TypeError: Cannot read property 'x' of undefined
at Object.afterDraw (main.min.js:1)
at Object.notify (main.min.js:4)
at t.Controller.draw (main.min.js:3)
at i.o.render (main.min.js:3)
at Object.startDigest (main.min.js:2)
at main.min.js:2
afterDraw @ main.min.js:1
notify @ main.min.js:4
draw @ main.min.js:3
o.render @ main.min.js:3
startDigest @ main.min.js:2
(anonymous) @ main.min.js:2
main.min.js:1
Uncaught TypeError: Cannot read property 'x' of undefined
at Object.afterDraw (main.min.js:1)
at Object.notify (main.min.js:4)
at t.Controller.draw (main.min.js:3)
at t.Controller.render (main.min.js:3)
at t.Controller.update (main.min.js:3)
at t.Controller.resize (main.min.js:2)
at main.min.js:2
at main.min.js:3
afterDraw @ main.min.js:1
notify @ main.min.js:4
draw @ main.min.js:3
render @ main.min.js:3
update @ main.min.js:3
resize @ main.min.js:2
(anonymous) @ main.min.js:2
(anonymous) @ main.min.js:3
main.min.js:1
Uncaught TypeError: Cannot read property 'x' of undefined
at Object.afterDraw (main.min.js:1)
at Object.notify (main.min.js:4)
at t.Controller.draw (main.min.js:3)
at t.Controller.render (main.min.js:3)
at t.Controller.update (main.min.js:3)
at t.Controller.resize (main.min.js:2)
at main.min.js:2
at main.min.js:3
EDIT After trying a bit, I found where it might happen but I have no idea how to fix it. onEvent won't get triggered somehow.
Nevermind, reading should help. Copied your Chart.js Libcode for now and hope 2.5 will land soon. :D
Altough... errors are still there. Cannot read property 'x' of undefined
@visualcookie that's probably happening because of var x = chart.options.customLine.x; and the customLine sub options doesn't exist in all charts.
There are 2 solutions to this.
Check for options being defined before using them
if (chart.options.myLine) {
var x = chart.options.myLine;
...
}
Don't use a global plugin
Instead of doing Chart.plugins.register(plugin) you could do the following (also new in v2.5)
new Chart(ctx, {
type: 'line',
data: data,
options: {
plugins: [plugin] // only applies to the charts it is added to
}
});
Works, thanks. 👍
@visualcookie Did you achieve the result?
If yes, please share with us – would be super to have that feature native on Chart.js.
@hmaesta how would you adapt this to the latest version? https://jsfiddle.net/hev1nonk/15/
@fexra I ended up giving up on this approach.
Maybe @visualcookie can help, even though he did not even answer my comment from months ago.
I updated example from @etimberg to make it working for me:
`var ctx = document.getElementById('chart').getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April'],
datasets: [{
data: [10, 0, 20, 30],
label: 'First dataset'
}]
},
options: {
customLine: {
color: 'black'
},
tooltips: {
intersect: false
}
},
plugins: [{
beforeEvent: function(chart, e) {
if ((e.type === 'mousemove')
&& (e.x >= e.chart.chartArea.left)
&& (e.x <= e.chart.chartArea.right)
) {
chart.options.customLine.x = e.x;
}
},
afterDraw: function(chart, easing) {
var ctx = chart.chart.ctx;
var chartArea = chart.chartArea;
var x = chart.options.customLine.x;
if (!isNaN(x)) {
ctx.save();
ctx.strokeStyle = chart.options.customLine.color;
ctx.moveTo(chart.options.customLine.x, chartArea.bottom);
ctx.lineTo(chart.options.customLine.x, chartArea.top);
ctx.stroke();
ctx.restore();
}
}
}]
})`
@ydudchak and all
thanks to comment this post, your examples are working well and I used in my work!
I'm facing the problem with @ydudchak example and I'm stuck, Can one please suggest on my issue https://stackoverflow.com/questions/53227542/chartjs-clicking-on-legend-option-makes-line-chart-ugly
Most helpful comment
I updated example from @etimberg to make it working for me:
`var ctx = document.getElementById('chart').getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April'],
datasets: [{
data: [10, 0, 20, 30],
label: 'First dataset'
}]
},
options: {
customLine: {
color: 'black'
},
tooltips: {
intersect: false
}
},
plugins: [{
beforeEvent: function(chart, e) {
if ((e.type === 'mousemove')
&& (e.x >= e.chart.chartArea.left)
&& (e.x <= e.chart.chartArea.right)
) {
chart.options.customLine.x = e.x;
}
},
afterDraw: function(chart, easing) {
var ctx = chart.chart.ctx;
var chartArea = chart.chartArea;
var x = chart.options.customLine.x;
}]
})`