5

我的 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();
});
4

4 回答 4

3

您在每次鼠标移动时都选择该行,而是将该行保留在一个变量中:

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);
});
于 2012-10-10T23:26:25.883 回答
3

我有同样的问题,但我注意到两件事:

  1. 如果你看一下 High Charts,他们已经(在他们的 JS 库中)实现了一个类似的垂直指南,它并没有落后太多。所以有可能做到这一点。参见例如:这里

  2. 我使用了一个容器元素,向其中添加了一个 SVG 元素,并在其中添加了一个带有坐标平移/变换的组 (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 也没有针对鼠标事件进行优化。

于 2012-12-18T18:52:14.167 回答
3

mousemove您可以添加几毫秒的延迟,而不是更新 every 上的属性:

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可能太长了。

于 2012-12-18T19:02:37.463 回答
1

有一个名为的 CSS 属性shape-rendering,它设置了 SVG 应该如何呈现的优先级。您可以指定autooptimizeSpeedcrispEdgesgeometricPrecision, 其中 auto 尝试在不牺牲精度的情况下适应速度和清晰度。

我发现这些设置shape-rendering可以auto提高我的十字准线的性能。KrisEdges 和 optimizeSpeed 似乎使光标间歇性地消失。我无法在小提琴中重现平滑的十字准线,但在我的解决方案中,它现在实际上非常平滑。

于 2014-02-28T23:49:38.980 回答