【发布时间】:2022-02-25 07:26:08
【问题描述】:
我正在尝试在美国的 TopoJSON 地图中为县实现鼠标悬停时的 div 工具提示,在 Angular 构建的页面上使用 D3。
我已经尝试了 D3 鼠标悬停事件中可用的 x/y 坐标的每种组合,以及在线建议的一些组合(D3.pointer、Element.getBoundingClientRect 等),但无论我做什么,工具提示似乎落在不正确的坐标上,从我的鼠标偏移并且不一定在svg 上的每个位置都具有相同的度数。
有没有合适的方法来做到这一点?代码示例如下。相关部分在this.counties.on("mouseover", ...)内。
HTML
<div class="row g-0">
<div class="container" id="mapContainer">
<svg id="map"></svg>
<div id="tooltip">TESTING</div>
</div>
</div>
CSS
#mapContainer {
position: relative;
}
#tooltip {
position: absolute;
}
TypeScript
this.svg = d3.select("#map")
.attr("preserveAspectRatio", "xMidYMid meet")
.attr("viewBox", "0 0 960 600")
.attr("height", "100%")
.attr("width", "100%")
this.g = this.svg.append("g")
.attr("id", "g")
this.zoom = d3.zoom()
.scaleExtent([1, 8])
.translateExtent([[0, 0], [960, 600]])
.on("zoom", (event, d) => {
let {transform} = event
this.g.attr("transform", transform)
this.g.attr("stroke-width", 1 / transform.k)
})
this.counties = this.g.append("g")
.attr("class", "county")
.attr("fill", "#DFDFDF")
.attr("stroke", "#FFFFFF")
.attr("stroke-linejoin", "round")
.attr("stroke-width", "0.25")
.selectAll('path')
.data(topojson.feature(this.topography, this.topography["objects"]["counties"])["features"])
.join("path")
.attr("id", function(d) {return d["id"]})
.attr('d', this.path)
.attr("fill", "#DFDFDF")
.on("mousemove", (event, d) => {
d3.select("#tooltip")
.style("left", `${d3.pointer(event)[0]}px`)
.style("top", `${d3.pointer(event)[1]}px`)
})
// PER DERISTNOCHDA'S SUGGESTION
.on("mousemove", (event, d) => {
d3.select("#tooltip")
.style("left", `${event.pageY}px`)
.style("top", `${event.pageX}px`)
})
一些结果的屏幕截图,例如,当光标在右上角的缅因州时:
当光标位于左下角的亚利桑那州时:
【问题讨论】:
-
由于您的
#tooltip是绝对放置的,您应该尝试使用d3.event.pageX和d3.event.pageY而不是d3.pointer相对于事件目标转换的坐标。 -
@deristnochda 我试图实现这个(代码编辑到上面的 TypeScript 部分),但这也给了我一个实际上不在我的光标附近的工具提示。
标签: html typescript d3.js coordinates topojson