问题描述
我正在使用d3.js topo和d3.js路径从geojson数据构建楼层地图。为了澄清起见,我也使用vue.js。当用户将鼠标悬停在一个房间(即d3.js路径)上时,我想添加一个工具提示。首先,我只在用户将鼠标悬停在某个路径上时添加了控制台日志,但这没有用。我注意到,每次我加载该应用程序时,它都会生成一个控制台日志,但是当用户单击d3.js路径时,却不会。我听说有人说我必须创建一个不可见的圆形或矩形,将其绑定有tooltip属性,但是一旦楼层图变得复杂,我认为该路线将不起作用。我现在不在乎将任何实际数据添加到工具提示中,但稍后我会想要。有人可以指出我正确的方向吗?谢谢。
const data = {
"type": "FeatureCollection","features": [{
"type": "Feature","properties": {},"geometry": {
"type": "polygon","coordinates": [
[
[
0,0
],[
0,11.4
],[
7,0
]
]
]
}
},{
"type": "Feature","coordinates": [
[
[
7,[
12,"coordinates": [
[
[
12,[
19,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>
解决方法
有几种方法可以做到这一点。最简单(但最受限制)的方法是在每个path
中创建一个<title>
element。它将以悬停形式显示,因为它是浏览器的本机。
const data = {
"type": "FeatureCollection","features": [{
"type": "Feature","properties": { "name": "Kitchen" },"geometry": {
"type": "Polygon","coordinates": [
[
[
0,0
],[
0,11.4
],[
7,0
]
]
]
}
},{
"type": "Feature","properties": { "name": "Living room" },"coordinates": [
[
[
7,[
12,"properties": { "name": "Toilet" },"coordinates": [
[
[
12,[
19,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","properties": {
"name": "Kitchen"
},"properties": {
"name": "Living room"
},"properties": {
"name": "Toilet"
},0
]
]
]
}
}
]
};
var svg = d3.select("svg")
var width = +svg.attr("width")
var height = +svg.attr("height")
var tooltip = d3.select("#tooltip")
svg.attr("transform",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>