javascript - 获取所有重叠特征的工具提示 D3
问题描述
例如,在图片中有一些圆圈相互重叠,如果鼠标悬停在重叠区域上,我想获取有关这两个特征/圆圈的信息。
代码和工具提示示例附在下面。
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
radius = 32;
var circles = d3.range(20).map(function() {
return {
x: Math.round(Math.random() * (width - radius * 2) + radius),
y: Math.round(Math.random() * (height - radius * 2) + radius)
};
});
var color = d3.scaleOrdinal()
.range(d3.schemeCategory20);
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.text("a simple tooltip");
svg.selectAll("circle")
.data(circles)
.enter().append("circle")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", radius)
.on("mouseover", function(d){
return tooltip.style("visibility", "visible");
})
.on("mousemove", function(d){
return tooltip
.html("Radius: " + d.x)
.style("top", (event.pageY-10)+"px").style("left", (event.pageX+10)+"px");
})
.on("mouseout", function(d){return tooltip.style("visibility", "hidden");})
.style("fill", function(d, i) { return color(i); })
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d) {
d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this).classed("active", false);
}
svg {
border: 1px solid black;
}
.active {
stroke: #000;
stroke-width: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>
<svg width="960" height="500"></svg>
解决方案
这将计算鼠标位置与所有其他圆圈的距离,以测试鼠标是否超过一个圆圈:
<!DOCTYPE html>
<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>
<svg width="500" height="500"></svg>
<script>
var svg = d3.select('svg'),
width = +svg.attr('width'),
height = +svg.attr('height'),
radius = 32;
var circles = d3.range(20).map(function () {
return {
x: Math.round(Math.random() * (width - radius * 2) + radius),
y: Math.round(Math.random() * (height - radius * 2) + radius),
};
});
var color = d3.scaleOrdinal().range(d3.schemeCategory20);
var tooltip = d3
.select('body')
.append('div')
.style('position', 'absolute')
.style('z-index', '10')
.style('visibility', 'hidden')
.text('a simple tooltip');
var circles = svg
.selectAll('circle')
.data(circles)
.enter()
.append('circle')
.attr('cx', function (d) {
return d.x;
})
.attr('cy', function (d) {
return d.y;
})
.attr('r', radius)
.on('mouseover', function (d) {
return tooltip.style('visibility', 'visible');
})
.on('mousemove', function (d) {
var txt = 'X: ' + d.x,
m = d3.mouse(this);
circles.each(function(d1){
// if not circle with "mouseover"
if (d.x !== d1.x || d.y !== d1.y)
{
// check distance
if (Math.sqrt((d1.x - m[0])**2 + (d1.y - m[1])**2) <= 32)
{
// add to tooltip
txt += '<br/> X: ' + d1.x;
}
}
});
return tooltip
.html(txt)
.style('top', event.pageY - 10 + 'px')
.style('left', event.pageX + 10 + 'px');
})
.on('mouseout', function (d) {
return tooltip.style('visibility', 'hidden');
})
.style('fill', function (d, i) {
return color(i);
})
.call(
d3
.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended)
);
function dragstarted(d) {
d3.select(this).raise().classed('active', true);
}
function dragged(d) {
d3.select(this)
.attr('cx', (d.x = d3.event.x))
.attr('cy', (d.y = d3.event.y));
}
function dragended(d) {
d3.select(this).classed('active', false);
}
</script>
</body>
</html>
推荐阅读
- c# - 粒子系统不会出现在构建的项目中
- go - 与直接查询单个 Web 服务器的速度相同
- authentication - .Net Core 身份验证和用户会话
- django - 何时使用 API 与 Django 内置函数
- php - curl_getinfo($ch, CURLINFO_CERTINFO) 为空
- python - 如何在 Python 中下载文件但忽略错误?
- java - 为什么我的 while 循环不读取这两个语句?
- flutter - 从链接启动时如何将数据传递给我的应用程序?
- angular - 同时运行 ng build --watch 和 ng serve 时,Angular 7 库 html-template 更改不会影响到应用程序
- c# - C# 在网络流上设置 WriteTimeout / ReadTimeout 没有区别?