vue.js - 如何将工具提示添加到 d3.js 路径?
问题描述
我正在使用 d3.js 拓扑和 d3.js 路径从 geojson 数据构建平面图。为了澄清,我也在使用 vue.js。当用户将鼠标悬停在房间上时(又名 d3.js 路径),我想添加一个工具提示。首先,当用户将鼠标悬停在路径上但不起作用时,我只添加了一个控制台日志。我注意到每次加载应用程序时都会生成控制台日志,但当用户单击/悬停在 d3.js 路径上时不会。我听说有人说我必须创建一个不可见的圆形或矩形,它会将工具提示属性绑定到它,但我认为一旦楼层地图变得复杂,这条路线就不会起作用。我现在不关心将任何实际数据添加到工具提示中,但稍后我会想要。有人可以指出我正确的方向吗?谢谢你。
const data = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
0, 0
],
[
0, 11.4
],
[
7, 11.4
],
[
7, 0
],
[
0, 0
]
]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
7, 0
],
[
7, 11.4
],
[
12, 11.4
],
[
12, 0
],
[
7, 0
]
]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
12, 0
],
[
12, 11.4
],
[
19, 11.4
],
[
19, 0
],
[
12, 0
]
]
]
}
}
]
};
var svg = d3.select("svg")
var width = +svg.attr("width")
var height = +svg.attr("height")
svg.attr("transform", "translate(" + width / 2 + ",0)")
var projection = d3.geoIdentity().fitSize([width, height], data)
var path = d3.geoPath(projection)
svg.selectAll("path")
.data(data.features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "grey")
.attr("fill-opacity", .2)
.attr("stroke", "black")
.attr("stroke-width", 1.5)
.on("mouseover", console.log("hello"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="400" height="200"></svg>
解决方案
有几种方法可以做到这一点。最简单但最有限的一种方法是<title>
在每个path
. 它会在悬停时显示,因为它是浏览器原生的。
const data = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": { "name": "Kitchen" },
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
0, 0
],
[
0, 11.4
],
[
7, 11.4
],
[
7, 0
],
[
0, 0
]
]
]
}
},
{
"type": "Feature",
"properties": { "name": "Living room" },
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
7, 0
],
[
7, 11.4
],
[
12, 11.4
],
[
12, 0
],
[
7, 0
]
]
]
}
},
{
"type": "Feature",
"properties": { "name": "Toilet" },
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
12, 0
],
[
12, 11.4
],
[
19, 11.4
],
[
19, 0
],
[
12, 0
]
]
]
}
}
]
};
var svg = d3.select("svg")
var width = +svg.attr("width")
var height = +svg.attr("height")
svg.attr("transform", "translate(" + width / 2 + ",0)")
var projection = d3.geoIdentity().fitSize([width, height], data)
var path = d3.geoPath(projection)
svg.selectAll("path")
.data(data.features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "grey")
.attr("fill-opacity", .2)
.attr("stroke", "black")
.attr("stroke-width", 1.5)
.append("title")
// Do this to maintain access to the features you drew
.datum(function(d) { return d; })
.text(function(d) {
return d.properties.name;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="400" height="200"></svg>
更复杂的可以使用绝对定位div
,例如:
const data = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"name": "Kitchen"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
0, 0
],
[
0, 11.4
],
[
7, 11.4
],
[
7, 0
],
[
0, 0
]
]
]
}
},
{
"type": "Feature",
"properties": {
"name": "Living room"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
7, 0
],
[
7, 11.4
],
[
12, 11.4
],
[
12, 0
],
[
7, 0
]
]
]
}
},
{
"type": "Feature",
"properties": {
"name": "Toilet"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
12, 0
],
[
12, 11.4
],
[
19, 11.4
],
[
19, 0
],
[
12, 0
]
]
]
}
}
]
};
var svg = d3.select("svg")
var width = +svg.attr("width")
var height = +svg.attr("height")
var tooltip = d3.select("#tooltip")
svg.attr("transform", "translate(" + width / 2 + ",0)")
var projection = d3.geoIdentity().fitSize([width, height], data)
var path = d3.geoPath(projection)
svg.selectAll("path")
.data(data.features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "grey")
.attr("fill-opacity", .2)
.attr("stroke", "black")
.attr("stroke-width", 1.5)
.on("mousemove", function(d) {
// +3 as some offset to make sure spawning the tooltip doesn't
// accidentally also cause unhover and thus removing itself
tooltip
.html(d.properties.name)
.style("display", "block")
.style("left", d3.event.x + 3 + 'px')
.style("top", d3.event.y + 3 + 'px');
})
.on("mouseleave", function() {
tooltip
.style("display", null)
.style("left", null)
.style("top", null);
});
#tooltip {
position: absolute;
top: 0;
left: 0;
display: none;
border: solid 1px red;
padding: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="400" height="200"></svg>
<div id="tooltip"></div>
推荐阅读
- php - PHP Stripe \Stripe\AccountLink 类未找到
- deep-learning - 如何修复:RuntimeError: Function AddmmBackward 返回了一个无效的梯度索引 1got [100, 4096] 但预期的形状与 [100, 200704] 兼容
- amazon-web-services - 亚马逊 api 网关可以配置为验证 api 路由但通过 web 应用程序路由吗?
- pyspark - 在使用 PySpark 读取它们的列表时如何跳过空的镶木地板文件?
- kubernetes - 使用 Prometheus 在 K8s 服务端点上测量 40 倍和 50 倍的错误?
- json - 如何在 json 模式模式中指定匹配文字星号
- python - 不正确的 ndarray 被写入 csv
- python - 来自csv文件的矩阵的Python线性插值
- c - 如何用空格 printf() 填充值?
- angular - Angular - 'ngx-caption' 不是 Angular-12 ngx-datatable 中的已知元素