Tengo un gráfico, y quiero que la línea que representa la gráfica para mostrar un círculo en la coordenada x al pasar el ratón por encima de la svg área. Este círculo debe seguir la ruta de la línea que representa la curva. El problema es que no sé cómo hacerlo.

El código siguiente muestra de lo lejos que han sucedido, y de hecho se añade un círculo para el documento en el derecho coordenada x. Ahora, ¿qué debo hacer para cambiar el signo de interrogación con?

    svg.on("mousemove", function() {
        d3.select("path.line")
          .style("stroke-width", "2.5px");

         svg.append("svg:circle")
            .attr("cx", Math.floor(event.offsetX-m[1]))
            .attr("cy", ?)
            .attr("r", "10")
            .attr("fill", "red");
    });
InformationsquelleAutor Jimmy C | 2012-09-14

1 Comentario

  1. 27

    SVG proporciona una función nativa llamada .getPointAtLength() que devuelve los valores x e y de una ruta de acceso a cualquier longitud que usted pase esto.

    Que usted necesita para recorrer la longitud de la línea hasta encontrar el correspondiente y posición. Aquí es cómo usted lo haría en D3:

    var svg = d3.select("#line").append("svg")
    var path = 
    svg.append("path")
    .attr("d", "M0,168L28,95.99999999999997L56,192L84,71.99999999999997L112,120L140,192L168,240L196,168L224,48L252,24L280,192L308,120L336,24L364,168L392,95.99999999999997L420,168L448,95.99999999999997L476,192L504,71.99999999999997L532,120L560,192L588,216L616,168L644,48L672,24L700,192L728,120L756,24L784,192L812,71.99999999999997")
    .attr("fill", "none")
    .attr("stroke", "black");
    var circle = 
    svg.append("circle")
    .attr("cx", 100)
    .attr("cy", 350)
    .attr("r", 3)
    .attr("fill", "red");
    var pathEl = path.node();
    var pathLength = pathEl.getTotalLength();
    var BBox = pathEl.getBBox();
    var scale = pathLength/BBox.width;
    var offsetLeft = document.getElementById("line").offsetLeft;
    var randomizeButton = d3.select("button");
    svg.on("mousemove", function() {
    var x = d3.event.pageX - offsetLeft; 
    var beginning = x, end = pathLength, target;
    while (true) {
    target = Math.floor((beginning + end) / 2);
    pos = pathEl.getPointAtLength(target);
    if ((target === end || target === beginning) && pos.x !== x) {
    break;
    }
    if (pos.x > x)      end = target;
    else if (pos.x < x) beginning = target;
    else                break; //position found
    }
    circle
    .attr("opacity", 1)
    .attr("cx", x)
    .attr("cy", pos.y);
    });

    Se puede ver una demo aquí: http://bl.ocks.org/3824661

    • Estoy bastante seguro de que esto no funciona para arbitrario de la línea de tiempo de ruta de estilo de formas, por ejemplo, una línea con un muy fuerte incremento en un punto de no permitir una interpolación lineal entre la longitud de la trayectoria y la posición x.
    • que es lo suficientemente simple para la prueba de jsfiddle.net/FPfFJ y sí, no es del todo allí.
    • Sí, yo creo que la única forma de utilizar .getPointAtLength() para obtener un exacto punto en este caso es la de buscar a lo largo de la línea hasta encontrar un punto con un x valor cercano a d3.event.pageX.
    • Sí, esto funciona, he actualizado la respuesta jsfiddle.net/a9eY7
    • Bueno! Me encantaría ver a alguien implementar una búsqueda binaria para este problema, pero esto es bastante sólido.
    • No entiendo, ¿por qué no utiliza la x para calcular la longitud y, a continuación, hacer getPointAtLength(longitud)??
    • Imagina que tienes una línea con muchas curvas en el principio ∩∩∩———, cuando usted está en el medio de la pantalla que será el 50% de la anchura de la pantalla. La línea, sin embargo podría ser en el 75% de su longitud, pero no sabemos a ciencia cierta hasta que se compute a través de todas las posiciones de los candidatos (la longitud de una línea nunca será menor que el ancho de la pantalla, por ejemplo).
    • Gracias! ¿Cómo echo de menos que… jaja
    • esto no funciona si no hay Brecha en la línea, porque de valor Nulo. también puede usted explicar cuál es el significado de este bloque if ((destino === end || target === principio) && pos.x !== x) { break; }
    • d3.evento.pageX es lo que yo estaba buscando ! Gracias
    • El nodo().getPointAtLength(x) está en desuso, por favor, no lo use.

Dejar respuesta

Please enter your comment!
Please enter your name here