svg 圆圈没有很好地注册鼠标悬停
svg circle not registering mouseover very well
我有一张具有缩放功能的 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);
将 .style("pointer-events", "all")
添加到圈子中。 default 只是将鼠标悬停在可见的内容上,但无论是否渲染,您都想要内部的任何内容。
这里 a fiddle 显示它正在工作
您的链接是在您的节点之后绘制的,这意味着它们是 "on top" 个节点。您的指针事件没有进入圆圈,因为链接掩盖了它。
在你的代码中你有
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 中最后绘制的项目将位于顶部。这具有整理可视化效果的优点,因此链接的端点位于节点下方,使其看起来更整洁。
我同意@BenLyall 的观点,在圆圈后绘制 link 是导致问题的原因。在 SVG 中,深度由绘制元素的顺序控制。不过,一个更简单的解决方案是让 link 忽略指针事件。尝试将 .style("pointer-events", "none")
添加到 link 中。我使用您提供的 link 中的开发人员工具来做到这一点,一旦您移过一个圆圈,就会显示工具提示。
我有一张具有缩放功能的 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);
将 .style("pointer-events", "all")
添加到圈子中。 default 只是将鼠标悬停在可见的内容上,但无论是否渲染,您都想要内部的任何内容。
这里 a fiddle 显示它正在工作
您的链接是在您的节点之后绘制的,这意味着它们是 "on top" 个节点。您的指针事件没有进入圆圈,因为链接掩盖了它。
在你的代码中你有
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 中最后绘制的项目将位于顶部。这具有整理可视化效果的优点,因此链接的端点位于节点下方,使其看起来更整洁。
我同意@BenLyall 的观点,在圆圈后绘制 link 是导致问题的原因。在 SVG 中,深度由绘制元素的顺序控制。不过,一个更简单的解决方案是让 link 忽略指针事件。尝试将 .style("pointer-events", "none")
添加到 link 中。我使用您提供的 link 中的开发人员工具来做到这一点,一旦您移过一个圆圈,就会显示工具提示。