在d3.js中操纵鼠标悬停“命中区域”

时间:2014-12-01 22:51:54

标签: svg d3.js

鼠标悬停 / mouseout 时,我希望显示隐藏 SVG中的节点,问题是我在节点内的形状是一条只有1.5px宽度的路径,因此在鼠标悬停事件中不容易击中该区域,这对用户体验肯定不方便。

我想知道是否有办法使用任意宽度使命中区域更宽,但对用户不可见?

我的代码片段:

link.enter()
    .append('g').attr('class', 'link')
    .append('line')
    .attr('class', 'path')
    .attr('marker-end', function(d, i) {
        if (i === 2) {
            return 'url(#arrow)';
        } else {
            return null;
        }
    }).on('mouseover', function(d) {
        //alert(JSON.stringify(d));
        alert('mouseover');
    }).on('mouseout', function(d) {
        alert('mouseout');
    });

css:

.node .path {
  stroke: #878f8f;
  stroke-width: 1.5px;
  fill:none;
}

2 个答案:

答案 0 :(得分:7)

您可以使用透明笔划和大笔画宽度向line添加另一个g,这会增加命中区域。

// Subscribe to mouse events on the entire g
gEnter = link.enter()
    .append('g')
    .attr('class', 'link')
    .on('mouseover', function(d) {
        //alert(JSON.stringify(d));
        alert('mouseover');
    }).on('mouseout', function(d) {
        alert('mouseout');
    });

// Instead of 1 line, append 2 lines inside the g, and make
// one of them transparent and "fat", which will enlarge the
// hit area
lines = gEnter
    .selectAll('.path').data(['visible', 'invisible'])
lines.enter()
    .append('line')
    .attr('class', 'path')
    .attr('marker-end', function(d, i, j) {
        // j is the parent's i
        if (j === 2) {
            return 'url(#arrow)';
        } else {
            return null;
        }
    })
    .attr({
        // returning null from these functions simply defaults to whatever the
        // .path class's CSS props are doing
        'stroke-width': function(d, i) { return d == 'invisible' ? 10 : null },
        'stroke': function(d, i) { return d == 'invisible' ? 'transparent' : null }
    })

答案 1 :(得分:1)

您如何定义"rowNum":2, "rowList":[2,5,10,20], "loadComplete": function() { var i, myPageRefresh = function(e) { var newPage = $(e.target).text(); $("#tree").trigger("reloadGrid",[{page:newPage}]); e.preventDefault(); }; $($("#tree")[0].p.pager + '_center td.myPager').remove(); var pagerPrevTD = $('<td>', { class: "myPager"}), prevPagesIncluded = 0, pagerNextTD = $('<td>', { class: "myPager"}), nextPagesIncluded = 0, totalStyle = $("#tree")[0].p.pginput === false, startIndex = totalStyle? this.p.page-2*2: this.p.page-2; for (i=startIndex; i<=this.p.lastpage && (totalStyle? (prevPagesIncluded+nextPagesIncluded<2*2):(nextPagesIncluded<2)); i++) { if (i<=0 || i === this.p.page) { continue; } var link = $('<a>', { href:'#', click:myPageRefresh }); link.text(String(i)); if (i<this.p.page || totalStyle) { if (prevPagesIncluded>0) { pagerPrevTD.append('<span>,&nbsp;</span>'); } pagerPrevTD.append(link); prevPagesIncluded++; } else { if (nextPagesIncluded>0 || (totalStyle && prevPagesIncluded>0)) { pagerNextTD.append('<span>,&nbsp;</span>'); } pagerNextTD.append(link); nextPagesIncluded++; } } if (prevPagesIncluded > 0) { $($("#tree")[0].p.pager + '_center td[id^="prev"]').after(pagerPrevTD); } if (nextPagesIncluded > 0) { $($("#tree")[0].p.pager + '_center td[id^="next"]').before(pagerNextTD); } } ` ?我无法弄清楚你的解决方案,但我遵循了将两行(一个是可见的,另一个是invisivle)附加到父link元素的相同想法。我认为它效率不高,因为我最终不得不两次调用线坐标(一次用于可见线,一次用于不可见线)。这就是我所做的:

g

它有效,但如果有人可以提出改进建议,那就太棒了,谢谢!