我创建了一个图表,其中y轴包含每个图例项目的鼠标悬停/ tooltop。鼠标悬停创建一个工具提示,该工具提示跨越y图例项目高度处的图形宽度。我已成功定位工具提示的高度和宽度以及x轴位置,但无法找到正确的公式来定位工具提示的顶部。
var countryBox = d3.select("body").append("div")
.attr("class", "countryTip")
.style("opacity", 0);
...
/* Build mouseover infobox for each country in y axis legend in 1800 */
h.selectAll(".axis--y .tick text")
.on("mouseover", function() {
totSpec = 0;
var myElement = d3.select(this);
var countryName = myElement.text();
/* determine absolute coordinates for left edge of SVG */
var matrix = this.getScreenCTM()
.translate(+this.getAttribute("cx"), +this.getAttribute("cy"));
h.selectAll("." + countryName.replace(/\s+/g, '_')).each(function(d) {
totSpec += d.freqEnd;
totSpec -= d.freqStart;
sumSpec = sumSpec + d.freqEnd - d.freqStart;
});
var availPercent = totSpec / availSpec;
countryBox.transition()
.duration(200)
.style("opacity", .9);
var yText = getTranslation(d3.select(this.parentNode).attr("transform"));
countryBox.html(countryName + '</br>' + r(totSpec) + ' MHz assigned out of ' + r(availSpec) + ' MHz available. <br><b>Band occupancy ' + p(availPercent) + '</b>')
.style("left", (window.pageXOffset + matrix.e) + "px")
.style("top", (yText[1] - y.bandwidth()/2 - window.pageYOffset) + "px")
.style("height", y.bandwidth() + "px")
.style("width", width + "px");
console.log("yText[1]: " + yText[1] + " halfBand: " + halfBand + " margin.top: " + margin.top + " window.pageYOffset: " + window.pageYOffset );
})
.on("mouseout", function() {
countryBox.transition()
.duration(500)
.style("opacity", 0);
});
其中
getTranslation
是compensate for the absence of d3.transform in v4到
function getTranslation(transform) {
var g = document.createElementNS("http://www.w3.org/2000/svg", "g");
g.setAttributeNS(null, "transform", transform);
var matrix = g.transform.baseVal.consolidate().matrix;
return [matrix.e, matrix.f];
}
对于
.style("top", (yText[1] - y.bandwidth()/2 - window.pageYOffset) + "px")
yText[1]
会返回鼠标经过的y图例项的y坐标,实际上是相关国家/地区范围的垂直中点。 y.bandwidth()/2
表示垂直高度的一半
乐队和window.pageYOffset
补偿滚动据我所见,这应该将工具提示的顶部放在相关x波段的顶部。显然不是。引导是一个因素吗?如果涉及纯svg,我发现我可以在每个乐队上绘制一个完美的圆圈,使用yText[1]
作为圆圈的中心点。我混合了svg和html吗?
CSS
div.countryTip {
position: fixed;
z-index: 99;
text-align: left;
font-family: arial;
font-size: 1em;
line-height: 1.5;
padding: 1.5em;
background: #144667;
border: 0px;
color: white;
border-radius: 3px;
pointer-events: none;
-webkit-transform: translate3d(0, -0.5em, 0);
-moz-transform: translate3d(0, -0.5em, 0);
transform: translate3d(0, -0.5em, 0);
-webkit-transition: opacity 0.1s, -webkit-transform 0.1s;
-moz-transition: opacity 0.1s, -moz-transform 0.1s;
transition: opacity 0.1s, transform 0.1s;
}
更新:添加了Plunker
答案 0 :(得分:0)
给@ Gerald Furtado的小费提示,他指出我需要为SVG元素添加容器div的顶部偏移量。
.style("top", (document.getElementById(divID).offsetTop + yText[1] - window.pageYOffset) + "px")
完成了这项工作,虽然我仍然在工具提示的不同标签上得到一点垂直差异,我无法解释。
答案 1 :(得分:0)
终于解决了这个问题。我混淆了SVG和HTML坐标系。答案是使用getScreenCTM()
定义的矩阵坐标的y元素let matrix = this.getScreenCTM()
.translate(+this.getAttribute('cx') +this.getAttribute('cy'))
结果为
.style('top', matrix.f - y.bandwidth() / 2 + 8 + 'px')
这篇关于understanding SVG coordinates的帖子以及关于SVG工具提示的这个practical example帮助我最终实现了目标。