svg圈没有很好地注册鼠标

时间:2015-01-06 17:46:38

标签: javascript html css svg d3.js

我有一个带缩放功能的d3地图,其中的圆圈代表不同的城市。出于某种原因,当我将鼠标悬停在圆圈上时(鼠标悬停显示工具提示,并且单击显示某些行),很难让它进行注册。它似乎只是在圆圈的边界附近注册而不是整个形状,但我还没有找到一个可辨别的模式。这是我的相关代码:

CSS:

circle {
  stroke-width: 1.5px;
  stroke: "green";
  cursor: pointer;
}

使用Javascript:

var node = g.selectAll(".node")
    .data(data.nodes)
    .enter()
    .append("circle")
    .attr("cx", function(d) {
        return projection([-1 * d.lon, -1 * d.lat])[0];
    })
    .attr("cy", function(d) {
        return projection([-1 * d.lon, -1 * d.lat])[1];
    })
    .attr("r", 3)
    .style("fill", function(d) {
        return line_color([Math.floor(d.diversity * num_lines)])
    })
    .style("stroke", "#000000")
    .style("stroke-width", "0.05px")
    .on('mouseover', tip.show)
    .on("click", fade(0))
    .on('mouseout', tip.hide);

Here it is in action, to demonstrate the problem

3 个答案:

答案 0 :(得分:2)

您的链接正在您的节点之后绘制,这意味着它们位于节点的“顶部”。你的指针事件没有进入圆圈,因为链接正在屏蔽它。

在你的代码中你有

    var data = d3.json("data/city_data.json", function(error, data) {
    var num_lines = data.links.length;
    var line_color = d3.scale.sqrt().domain([0, num_lines]).range(["#99CCFF", "#000066"]); //scale color by sqrt to seperate it out
    var node = g.selectAll(".node")
        .data(data.nodes)
        .enter()
        .append("circle")
        .attr("cx", function(d) {
            return projection([-1 * d.lon, -1 * d.lat])[0];
        })
        .attr("cy", function(d) {
            return projection([-1 * d.lon, -1 * d.lat])[1];
        })
        .attr("r", 3)
        .style("fill", function(d) {
            return line_color([Math.floor(d.diversity * num_lines)])
        })
        .style("stroke", "#000000")
        .style("stroke-width", "0.05px")
        .on('mouseover', tip.show)
        .on("click", fade(0))
        .on('mouseout', tip.hide);

    var link = g.selectAll(".link")
        .data(data.links)
        .enter()
        .append("line")
        .attr("class", "link")
        .style("stroke-opacity", 0)
        .style("stroke", function(d) {
            return line_color([Math.floor(d.nlp_1 * num_lines)]);
        })
        .style("stroke-width", 1);

    link.attr("x1", function(d) {
            source_node = data.nodes[d.source];
            return projection([-1 * source_node.lon, -1 * source_node.lat])[0];
        })
        .attr("y1", function(d) {
            source_node = data.nodes[d.source];
            return projection([-1 * source_node.lon, -1 * source_node.lat])[1];
        })
        .attr("x2", function(d) {
            target_node = data.nodes[d.target];
            return projection([-1 * target_node.lon, -1 * target_node.lat])[0];
        })
        .attr("y2", function(d) {
            target_node = data.nodes[d.target];
            return projection([-1 * target_node.lon, -1 * target_node.lat])[1];
        });

尝试做:

var data = d3.json("data/city_data.json", function(error, data) {
    var num_lines = data.links.length;
    var line_color = d3.scale.sqrt().domain([0, num_lines]).range(["#99CCFF", "#000066"]); //scale color by sqrt to seperate it out

    var link = g.selectAll(".link")
        .data(data.links)
        .enter()
        .append("line")
        .attr("class", "link")
        .style("stroke-opacity", 0)
        .style("stroke", function(d) {
            return line_color([Math.floor(d.nlp_1 * num_lines)]);
        })
        .style("stroke-width", 1);

    link.attr("x1", function(d) {
            source_node = data.nodes[d.source];
            return projection([-1 * source_node.lon, -1 * source_node.lat])[0];
        })
        .attr("y1", function(d) {
            source_node = data.nodes[d.source];
            return projection([-1 * source_node.lon, -1 * source_node.lat])[1];
        })
        .attr("x2", function(d) {
            target_node = data.nodes[d.target];
            return projection([-1 * target_node.lon, -1 * target_node.lat])[0];
        })
        .attr("y2", function(d) {
            target_node = data.nodes[d.target];
            return projection([-1 * target_node.lon, -1 * target_node.lat])[1];
        });

    var node = g.selectAll(".node")
        .data(data.nodes)
        .enter()
        .append("circle")
        .attr("cx", function(d) {
            return projection([-1 * d.lon, -1 * d.lat])[0];
        })
        .attr("cy", function(d) {
            return projection([-1 * d.lon, -1 * d.lat])[1];
        })
        .attr("r", 3)
        .style("fill", function(d) {
            return line_color([Math.floor(d.diversity * num_lines)])
        })
        .style("stroke", "#000000")
        .style("stroke-width", "0.05px")
        .on('mouseover', tip.show)
        .on("click", fade(0))
        .on('mouseout', tip.hide);

您在SVG中最后绘制的项目将位于顶部。这样做的好处是可以整理可视化,因此链接的端点位于节点下方,使其看起来更整洁。

答案 1 :(得分:2)

我同意@BenLyall的说法,即在圈子之后绘制链接是造成问题的原因。在SVG中,深度由绘制元素的顺序控制。但是,更简单的解决方案是使链接忽略指针事件。尝试将.style("pointer-events", "none")添加到链接。我在您提供的链接中使用开发人员工具执行此操作,并且只要您移动一个圆圈就会显示工具提示。

答案 2 :(得分:1)

.style("pointer-events", "all")添加到圈子中。 default只是鼠标悬停在可见的内容上,但你想要内部的任何内容,无论是否渲染。

这是显示正常工作的a fiddle