2012-10-10 58 views
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(); 
}); 

回答

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); 
}); 
+0

這有助於減少一些滯後的,謝謝你,但我希望能有降低甚至更多,因爲還有移動鼠標指針時,一個非常明顯的延遲的方法。 –

+0

'd3.event.pageX'和'.pageY'可能會更快,我已經更新了答案。除此之外,我恐怕你已經優化了所有你能做到的事情,總會有一點落後於鼠標。 – Duopixel

+0

我不認爲這是導致性能問題的選擇,我認爲這是對瀏覽器無法跟上的DOM的快速修改。 – Wex

3

我有同樣的問題,但我注意到兩件事:

  1. 如果你看高圖表,他們已經實現了(在他們的JS庫)一個類似的垂直指南,這並不落後於此。所以有可能做到這一點。參見例如:here

  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"); 

的INTERES ting的事情是,當我將鼠標事件(在第一個答案中使用上面的代碼)綁定到各種元素時,我獲得了非常不同的性能:當我將它綁定到「d3-canvas」組時,我的引導線非常​​緩慢且滯後後面,當我將它綁定到它的父級svg元素(「d3-svg」)時,它已經更快了,如果我將它綁定到div(「d3-container」),我可以獲得最快的性能(儘管它仍然不是儘管高庫存儘管)。所以我認爲座標轉換爲鼠標事件增加了很多開銷,但不管怎樣D3或SVG也沒有針對鼠標事件進行優化。

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

+1

是的,這有效。我認爲這是正確的做法。 – jm1234567890

1

有一個叫shape-rendering CSS屬性它設置爲您SVGs應該如何呈現的優先級。您可以指定autooptimizeSpeedcrispEdges,或geometricPrecision,其中汽車試圖適應速度和脆度不犧牲精度。

我發現設置shape-renderingauto增加了我的十字準線的性能。 crispEdges和optimizeSpeed似乎會使光標間歇性地消失。我無法在小提琴中重現光滑的十字準線,但在我的解決方案中,現在它實際上非常流暢。

相關問題