使用d3.js和HTML5 Canvas(不是SVG)的鼠标事件

时间:2014-08-21 13:25:49

标签: javascript html5 canvas d3.js

我是Canvas的新手,对d3.js来说还是全新的......

我正在尝试使用d3.js和Canvas来创建交互式数据可视化。我有一个非常基本的版本,但是我对如何准确地与每个节点(一个圆圈)进行交互感到有点困惑。

网上关于如何做到这一点似乎有限,或者我错过了什么?

我目前只是尝试使用以下代码在mouseover / mouseout上更改鼠标光标:

canvas.on("mousemove", function() {
   var m = d3.mouse(this);
   selectNode( m[0], m[1] );
});

var nodeI, thisNX, thisNY, nHover;

for ( i; i < nodes.length; i++ ) {

nX = nodes[i].x,
nY = nodes[i].y,
nR = nodes[i].radius - 3,
nHover = nodes[i].hover || "";

if ( mX >= nX - nR && mX <= nX + nR && mY >= nY - nR && mY <= nY + nR && nHover === "" ) {

    console.log( "mouse on!" );

    nodeI = nodes[i].index;
    thisNX = nX;
    thisNY = nY;

    $('html,body').css('cursor','pointer');

    nodes[i].hover = true;

} else {
    if ( nHover === true ) {
        console.log( "mouse off!" );
        nodes[nodeI].hover = "";
        $('html,body').css('cursor','default');
    }       
}

这是一个工作小提琴:http://jsfiddle.net/u90cmm36/

我非常接近让这个工作,虽然我无法让mouseout正常工作。

我是否以正确的方式进行此操作?对我来说似乎有点啰嗦。什么是Canvas的d3.js的内置鼠标悬停/鼠标悬停?

感谢您的帮助!!

1 个答案:

答案 0 :(得分:2)

不幸的是,没有用于画布的内置鼠标悬停。有一些图书馆可以做到这一点,比如KineticJS,但我还没有用过它。据我所知,D3已经使用了很多,并没有内置鼠标悬停画布。

通常,如果我在画布上使用d3,我会使用透明的SVG图层来控制鼠标的交互。这种方法既提供了SVG的交互性,又提供了画布的更精细的图形控制,但如果你有很多交互位,可以降低性能,因为每个不同的交互需要一个DOM元素。你也可以通过跟踪鼠标位置来做事,这就是你正在做的事情。但是,您的方法存在一些问题。

现在,您循环遍历所有节点,一次检查一个鼠标位置。即使您的鼠标位于节点中,循环也会继续,并在检查时将光标更改回来,并且发现您不在循环中的下一个节点中。您应该更改此项以检查并查看您是否在任何节点中,然后一旦确定您是否在节点中,请停止检查其余节点并更改你的光标(如果需要更改的话。)

您当前检查鼠标悬停的方法还会检查边界方块而不是圆圈。这将检查鼠标是否在一个圆圈中:

var distance = Math.sqrt(Math.pow(nX - mX, 2) + Math.pow(nX - mX, 2));
if(distance <= nR){ //mouseover };