Reputation: 2817
I am implementing d3.js zoom behaviour on a svg, on the same svg I also need to capture mouse coordinate so I can set position of a tool tips that follow mouse cursor's position.
The problem is that my 'mousemove' event has override d3.js zoom behaviour. With 'mousemove' event added, zoom behaviour stop working.
It is either I have 'mousemove' event or 'zoom' event, but not both. Any suggestion how to get around this? Thanks.
// bind zoom behavior
selection_svg.call(
d3.behavior.zoom()
.translate([0, 0])
.scale(1)
.scaleExtent([1, 14])
.on('zoom', ()=>{ selection_plotArea.attr('transform', 'translate('+d3.event.translate+')scale('+d3.event.scale+')'); })
);
// tool tip coordinate
const toolTipNode = selection_toolTip.node();
toolTipNode.style.position = 'absolute';
selection_svg.node().addEventListener('mousemove',function(evt){
const coord_client = {
x:evt.clientX,
y:evt.clientY,
}
toolTipNode.style.left = `${coord_client.x}px`;
toolTipNode.style.top = `${coord_client.y}px`;
}, false);
I have added the code for this problem to fiddle: https://jsfiddle.net/apollotang/rt9t1vdj/
Upvotes: 0
Views: 1054
Reputation: 193
If you have a mousemove event attached to your svg, be sure you aren't calling d3.event.stopPropagation() within the mousemove event, or else you will prevent the zoom behavior.
Upvotes: 0
Reputation: 3324
The problem seems to be related to tooltipNode
catching mouse events. By adding some offset to coord_client
your problem would be gone.
selection_svg.on('mousemove', function () {
const coord_client = {
x: d3.event.layerX + 10,
y: d3.event.layerY + 10
};
toolTipNode.style.left = `${coord_client.x}px`;
toolTipNode.style.top = `${coord_client.y}px`;
}, false);
Note: I also changed clientX
and clientY
to layerX
and layerY
since there was a bug when scrolling changed mouse position and tooltipNode
would have been separated from mouse. Besides the event handling code changed to be handled by d3.
Upvotes: 1