我正在D3中创建一个包含两个主要功能的面积图:
1)使用时间滑块可更改x轴上的日期范围并更新图表(类似于笔刷缩放)
2)悬停出现的工具提示,以显示给定日期的确切值
这两个功能在加载图表时起作用,但是当我通过拖动幻灯片来更改x轴范围时,我遇到了一个问题:面积图可以通过放大新的轴和面积来按需转换,但是当我将鼠标悬停以显示工具提示,该工具提示的位置和值与该行/区域的新路径不匹配。
我尝试将所有创建工具提示对象的代码(附加到focus
var)包装到一个函数中,然后在移动滑块时调用该函数。我还尝试过将x比例尺存储在一个变量中,该变量在移动时间滑块时会更新,并将其传递给drawFocus()
函数。工具提示仍会出现在原始位置。
Screenshot of where tooltip appears after zooming using time slider
粘贴到bl.ock的链接以获取下面的完整代码,但我认为问题出在tipMove()
函数中,该函数在用户将鼠标悬停在图表上时被调用。 (current_x存储时间滑块定义的x比例):
// function that adds tooltip on hover
function tipMove() {
// below code finds the date by bisecting and
// stores the x and y coordinate as variables
let x0 = current_x.invert(d3.mouse(this)[0]);
let i = bisectDate(data, x0, 1);
let d0 = data[i - 1];
let d1 = data[i];
let d = x0 - d0.date > d1.date - x0 ? d1 : d0;
// place the focus objects on the same path as the line
focus.attr('transform', `translate(${current_x(d.date)}, ${y(d.value)})`);
// position the x line
focus.select('line.x')
.attr('x1', 0)
.attr('x2', x(d.date))
.attr('y1', 0)
.attr('y2', 0);
// console.log(x0)
// position the y line
focus.select('line.y')
.attr('x1', 0)
.attr('x2', 0)
.attr('y1', 0)
.attr('y2', height - y(d.value));
// position the text
focus.select('text').text(d.value).transition() // slowly fade in the tooltip
.duration(100)
.style("opacity", 1);
// show the circle on the path
focus.selectAll('.focus circle')
.style("opacity", 1)
};
此处的完整代码:https://blockbuilder.org/bendoesdata/99c2ca152f760b6d93c923ee9462f4fa
我希望放大图表后,工具提示会跟随该行,但是相反,工具提示会遵循该行的原始路径(在剪辑路径中不再可见)。