D3 在鼠标悬停时显示工具提示并超时
D3 show tooltip on mouse over with a timeout
我想在每次鼠标进入一个矩形并且几毫秒后鼠标在该矩形上时向 barchar 的矩形添加工具提示。我也想在鼠标离开任何矩形时删除它们。
我尝试将其与 d3 事件绑定并使用 setTimeout/clearTimeout。
它似乎工作 除了当你在工具提示行过渡时快速移动鼠标通过不同的栏时,
问题在这种情况下是工具提示从一个栏移动到另一个栏鼠标 enters/leaves
忽略超时。 工具提示的文本似乎做了一些奇怪的事情。
让我向您展示工具提示在超时前是如何出现的:
绑定绘制工具提示的函数的代码:
...
var bar = svg.select(".bars")
.selectAll(".barchart-group")
.data(data);
...
var come = bar.enter()
.append("rect")
.style("stroke", undefined)
.style("fill", "hsla(34, 82%, 48%, 0.79)");
...
//bind events to new bars
come.on("mouseover", delayTooltip)
.on("mouseout", removeBarTooltip);
...
tootlip相关函数代码:
function delayTooltip(d, i) {
// this here is every rect of the bar chart
this.hoverTimeout = window.setTimeout(addBarTooltip.bind(this), 1000, d, i);
}
function addBarTooltip(d, i) {
// **** PROBLEM ****
// this executes whithout waiting the set timeout
var firstAnims = 500;
var thisbar = d3.select(this);
var tooltip = d3.select(this.parentNode);
var gRoot = d3.select(this.parentNode.parentNode);
//Lets define some points of interest
var p0 = [+thisbar.attr("x") + (barWidth - 1) / 2, +thisbar.attr("y")];
var p1 = [p0[0], +p0[1] - 9];
var p2 = [p0[0], +p0[1] - 13];
//relevant points to draw tooltips
var line = gRoot.select(".linePointers");
var text = gRoot.select(".textHelpers");
line.append("polyline")
.style("stroke-dasharray", "2,1")
.style("stroke", "black")
.attr("points", [p0, p0])
.transition("line-Y-axis")
.duration(firstAnims)
.attrTween("points", function(d, i, a) {
return d3.interpolate([p0, p0], [p0, p1]);
});
text.append("text")
.attr("dy", ".2em")
.attr("text-anchor", "middle")
.attr("x", p2[0])
.attr("y", p1[1])
.text(d.value)
.style("font-size", ".85em")
.style("opacity", 0)
.transition("text-Y-axis")
.delay(firstAnims)
.duration(300)
.style("opacity", 1)
.attr("y", p2[1]);
}
function removeBarTooltip() {
window.clearTimeout(this.hoverTimeout);
var firstAnims = 200;
var thisbar = d3.select(this);
var tooltip = d3.select(this.parentNode);
var gRoot = d3.select(this.parentNode.parentNode);
//relevant points to draw tooltips
var p0 = [+thisbar.attr("x") + (barWidth - 1) / 2, +thisbar.attr("y")];
var p1 = [p0[0], +p0[1] - 9];
var p2 = [p0[0], +p0[1] - 13];
//Lets make a group for each part of our tooltip
var line = gRoot.select(".linePointers")
.selectAll("polyline");
var text = gRoot.select(".textHelpers")
.selectAll("text");
line.transition("line-Y-axis")
.duration(firstAnims)
.attrTween("points", function(d, i, a) {
return d3.interpolate([p0, p1], [p0, p0]);
})
.remove();
text.style("opacity", 0.7)
.transition("text-Y-axis")
.delay(firstAnims)
.duration(300)
.style("opacity", 0)
.attr("dy", p0[1] - p2[1])
.remove();
}
我希望尽可能避免添加任何其他库。
尝试foxToolTip.js
具有悬停和鼠标移开的延迟和过渡持续时间选项
https://github.com/MichaelRFox/foxToolTip.js
在 http://bl.ocks.org/MichaelRFox/59cdc1c3478fb0362448cf87fdab30d0
查看我的 bl.ock
将鼠标悬停在文本元素上时使用 0.5 秒的延迟来显示工具提示
问题出在 removeBarTooltip()
。让我们先看看这两行,我在其中定义了 tootlip 线的点:
var p0 = [+thisbar.attr("x") + (barWidth - 1) / 2, +thisbar.attr("y")];
var p1 = [p0[0], +p0[1] - 9];
稍后在这个函数中我正在做:
[...]
line.transition("line-Y-axis")
.duration(firstAnims)
.attrTween("points", function(d, i, a) {
return d3.interpolate([p0, p1], [p0, p0]);
})
.remove();
所以发生的事情是,由于 var p0
值取决于鼠标悬停在哪个栏上,所以图唇线从一个栏移动到另一个栏。
为了解决这个问题,我将带有 attrTween 的行转换更改为:
line.transition("line-Y-axis")
.duration(firstAnims)
.attrTween("points", function(d, i, a) {
var p0current = a.split(",");
var p1current = p0current.splice(2);
return d3.interpolate([p0current, p1current], [p0current, p0current]);
})
.remove();
它使用参数 a
的点 属性 的实际值,并仅基于它插入实际的移动事件。
我想在每次鼠标进入一个矩形并且几毫秒后鼠标在该矩形上时向 barchar 的矩形添加工具提示。我也想在鼠标离开任何矩形时删除它们。
我尝试将其与 d3 事件绑定并使用 setTimeout/clearTimeout。
它似乎工作 除了当你在工具提示行过渡时快速移动鼠标通过不同的栏时,
问题在这种情况下是工具提示从一个栏移动到另一个栏鼠标 enters/leaves 忽略超时。 工具提示的文本似乎做了一些奇怪的事情。
让我向您展示工具提示在超时前是如何出现的:
绑定绘制工具提示的函数的代码:
...
var bar = svg.select(".bars")
.selectAll(".barchart-group")
.data(data);
...
var come = bar.enter()
.append("rect")
.style("stroke", undefined)
.style("fill", "hsla(34, 82%, 48%, 0.79)");
...
//bind events to new bars
come.on("mouseover", delayTooltip)
.on("mouseout", removeBarTooltip);
...
tootlip相关函数代码:
function delayTooltip(d, i) {
// this here is every rect of the bar chart
this.hoverTimeout = window.setTimeout(addBarTooltip.bind(this), 1000, d, i);
}
function addBarTooltip(d, i) {
// **** PROBLEM ****
// this executes whithout waiting the set timeout
var firstAnims = 500;
var thisbar = d3.select(this);
var tooltip = d3.select(this.parentNode);
var gRoot = d3.select(this.parentNode.parentNode);
//Lets define some points of interest
var p0 = [+thisbar.attr("x") + (barWidth - 1) / 2, +thisbar.attr("y")];
var p1 = [p0[0], +p0[1] - 9];
var p2 = [p0[0], +p0[1] - 13];
//relevant points to draw tooltips
var line = gRoot.select(".linePointers");
var text = gRoot.select(".textHelpers");
line.append("polyline")
.style("stroke-dasharray", "2,1")
.style("stroke", "black")
.attr("points", [p0, p0])
.transition("line-Y-axis")
.duration(firstAnims)
.attrTween("points", function(d, i, a) {
return d3.interpolate([p0, p0], [p0, p1]);
});
text.append("text")
.attr("dy", ".2em")
.attr("text-anchor", "middle")
.attr("x", p2[0])
.attr("y", p1[1])
.text(d.value)
.style("font-size", ".85em")
.style("opacity", 0)
.transition("text-Y-axis")
.delay(firstAnims)
.duration(300)
.style("opacity", 1)
.attr("y", p2[1]);
}
function removeBarTooltip() {
window.clearTimeout(this.hoverTimeout);
var firstAnims = 200;
var thisbar = d3.select(this);
var tooltip = d3.select(this.parentNode);
var gRoot = d3.select(this.parentNode.parentNode);
//relevant points to draw tooltips
var p0 = [+thisbar.attr("x") + (barWidth - 1) / 2, +thisbar.attr("y")];
var p1 = [p0[0], +p0[1] - 9];
var p2 = [p0[0], +p0[1] - 13];
//Lets make a group for each part of our tooltip
var line = gRoot.select(".linePointers")
.selectAll("polyline");
var text = gRoot.select(".textHelpers")
.selectAll("text");
line.transition("line-Y-axis")
.duration(firstAnims)
.attrTween("points", function(d, i, a) {
return d3.interpolate([p0, p1], [p0, p0]);
})
.remove();
text.style("opacity", 0.7)
.transition("text-Y-axis")
.delay(firstAnims)
.duration(300)
.style("opacity", 0)
.attr("dy", p0[1] - p2[1])
.remove();
}
我希望尽可能避免添加任何其他库。
尝试foxToolTip.js
具有悬停和鼠标移开的延迟和过渡持续时间选项
https://github.com/MichaelRFox/foxToolTip.js
在 http://bl.ocks.org/MichaelRFox/59cdc1c3478fb0362448cf87fdab30d0
查看我的 bl.ock将鼠标悬停在文本元素上时使用 0.5 秒的延迟来显示工具提示
问题出在 removeBarTooltip()
。让我们先看看这两行,我在其中定义了 tootlip 线的点:
var p0 = [+thisbar.attr("x") + (barWidth - 1) / 2, +thisbar.attr("y")];
var p1 = [p0[0], +p0[1] - 9];
稍后在这个函数中我正在做:
[...]
line.transition("line-Y-axis")
.duration(firstAnims)
.attrTween("points", function(d, i, a) {
return d3.interpolate([p0, p1], [p0, p0]);
})
.remove();
所以发生的事情是,由于 var p0
值取决于鼠标悬停在哪个栏上,所以图唇线从一个栏移动到另一个栏。
为了解决这个问题,我将带有 attrTween 的行转换更改为:
line.transition("line-Y-axis")
.duration(firstAnims)
.attrTween("points", function(d, i, a) {
var p0current = a.split(",");
var p1current = p0current.splice(2);
return d3.interpolate([p0current, p1current], [p0current, p0current]);
})
.remove();
它使用参数 a
的点 属性 的实际值,并仅基于它插入实际的移动事件。