我的svg上有一个垂直指针跟在鼠标指针之后,但是现在它更新它的位置很慢,这对于快速鼠标移动尤其明显。有没有办法减少这种滞后?
当前代码:
svg.on("mousemove", function(d) {
svg.select(".guideline")
.attr("x1", d3.mouse(this)[0]-1)
.attr("x2", d3.mouse(this)[0]-1);
});
svg.on("mouseover", function(d) {
svg.append("line")
.attr("class", "guideline")
.attr("y1", margin[0])
.attr("y2", height+margin[0])
.attr("opacity", originOpacity)
.attr("stroke", "#333")
.attr("pointer-events", "none");
});
svg.on("mouseout", function(d) {
svg.select(".guideline").remove();
});
答案 0 :(得分:3)
我遇到了同样的问题,但我发现了两件事:
如果你看一下High Charts,他们已经(在他们的JS库中)实现了一个类似的垂直指南,它并没有落后太多。所以有可能做到这一点。例如,请参阅:here
我使用了一个容器元素,我在其中添加了一个SVG元素,我在其中添加了一个带有坐标转换/转换的group(g)元素,如下所示:
HTML:
<div id="d3-container"></div>
JS:
var svg = d3.select("#d3-container")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("id","d3-svg")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("id","d3-canvas");
有趣的是,当我将鼠标事件(使用第一个答案中的上述代码)绑定到各种元素时,我会得到非常不同的性能:当我将它绑定到“d3-canvas”组时,我的引导线是非常慢并且滞后,当我将它绑定到它的父svg元素(“d3-svg”)时它已经更快了,如果我将它绑定到div(“d3-container”),我获得最快的性能(尽管它仍然没有高股票那么快。所以我认为坐标转换会给鼠标事件增加很多开销,但不管怎样,D3或SVG也没有针对鼠标事件进行优化。
答案 1 :(得分:2)
您正在选择每个鼠标移动的线条,而是将该线条保留在变量中:
var line = svg.append("line")
.attr("class", "guideline")
.attr("y1", margin[0])
.attr("y2", height+margin[0])
.attr("opacity", 0)
.attr("stroke", "#333")
.attr("pointer-events", "none");
svg.on("mousemove", function(d) {
line
.attr("x1", d3.event.pageX-1)
.attr("x2", d3.event.pageY-1);
});
svg.on("mouseover", function(d) {
line.attr("opacity", originOpacity);
});
svg.on("mouseout", function(d) {
line.attr("opacity", 0);
});
答案 2 :(得分:2)
您可以添加几毫秒的延迟,而不是更新每个mousemove
上的属性:
var lastMove, elapsed;
svg.on("mousemove", function(d) {
elapsed = Date.now() - lastMove;
if ( elapsed < 40 ) return;
svg.select(".guideline")
.attr("x1", d3.mouse(this)[0]-1)
.attr("x2", d3.mouse(this)[0]-1);
lastMove = Date.now();
});
这肯定会提高性能,但代价是让动作更加不稳定。玩你检查的毫秒数。 40
可能太长了。
答案 3 :(得分:1)
有一个名为shape-rendering
的CSS属性,用于设置应如何呈现SVG的优先级。您可以指定auto
,optimizeSpeed
,crispEdges
或geometricPrecision
,其中auto会尝试在不牺牲精度的情况下适应速度和清晰度。
我发现设置shape-rendering
到auto
会提高我的十字准线的性能。 crispEdges和optimizeSpeed似乎让光标间歇性地消失。我无法在小提琴中重现光滑的十字准线,但在我的解决方案中,它现在实际上非常平滑。