2012-10-10 45 views
5

Tengo una guía vertical en mi svg que sigue al puntero del mouse, pero ahora es un poco lenta para actualizar su posición, algo que es especialmente notable con los movimientos rápidos del mouse. ¿Hay alguna manera de reducir este retraso?¿Hay alguna manera de reducir el retraso de una guía que sigue al puntero del mouse?

código actual:

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

Respuesta

2

Usted está seleccionando la línea en cada mousemove, mantener la línea en una variable en su lugar:

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

Esto ayudó a reducir algunos retrasos, gracias por eso, pero esperaba que hubiera una manera de reducirlo aún más, ya que todavía hay un retraso muy obvio al mover el puntero del mouse. –

+0

'd3.event.pageX' y' .pageY' pueden ser más rápidos, he actualizado la respuesta.Más allá de eso, me temo que ya has optimizado todo lo que pudiste, siempre habrá un ligero retraso detrás del mouse. – Duopixel

+0

No creo que sea el 'select' el que está causando el problema con el rendimiento, creo que son las rápidas modificaciones al DOM que el navegador no puede seguir. – Wex

3

estoy teniendo el mismo problema, pero me di cuenta de dos cosas :

  1. Si mira los gráficos altos, han implementado (en su biblioteca JS) una guía vertical similar, que no se queda atrás tanto Entonces es posible hacerlo. Véase, por ejemplo: here

  2. uso un elemento de contenedor, a la que añadí un elemento SVG, a la que añadí un elemento del grupo (g) con una coordenada traducción/transformación, así:

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

Los interes Esto es cuando, al vincular eventos de mouse (usando el código anterior en la primera respuesta) a los diversos elementos, obtengo un rendimiento muy diferente: cuando lo vinculo al grupo "d3-canvas", mi línea guiada es muy lenta y retrasa Detrás, cuando lo enlace a su elemento principal svg ("d3-svg") ya es más rápido, y si lo enlace al div ("d3-container") obtengo el rendimiento más rápido (aunque todavía no es tan rápido como High Stock). Así que estoy pensando que la transformación de coordenadas agrega una gran cantidad de sobrecarga a los eventos del mouse, pero de alguna manera D3 o SVG tampoco están optimizados para los eventos del mouse.

2

En lugar de actualizar los atributos de cada mousemove, se podría añadir un retraso par de milisegundos:

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

Esto sin duda va a mejorar el rendimiento, pero a costa de hacer los movimientos más entrecortado. Juega con la cantidad de milisegundos que compruebes. 40 puede ser demasiado largo.

+1

Sí, esto funciona. Creo que es la forma correcta de hacerlo. – jm1234567890

1

Hay una propiedad CSS llamada shape-rendering que establece la prioridad de cómo se deben representar los archivos SVG. Puede especificar auto, optimizeSpeed, crispEdges o geometricPrecision, donde la función automática intenta dar cabida a la velocidad y la nitidez sin sacrificar la precisión.

He encontrado que la configuración shape-rendering a auto aumentó el rendimiento de mi punto de mira. crispEdges y optimizeSpeed ​​parecen hacer que el cursor desaparezca intermitentemente. No pude reproducir una cruz en forma de cruz en un violín, pero en mi solución en realidad es perfectamente suave ahora.

Cuestiones relacionadas