Calcular Ruta SVG Centroide con D3.js

Estoy usando el SVG situado en http://upload.wikimedia.org/wikipedia/commons/3/32/Blank_US_Map.svg en un proyecto y la interacción con el con d3.js. Me gustaría crear un clic, a efecto de zoom como http://bl.ocks.org/2206590, sin embargo de que el ejemplo se basa en los datos de la ruta almacenada en un objeto JSON para calcular el centroide. Hay alguna forma de cargar los datos de la ruta en d3 a partir de una SVG para obtener el centro de gravedad?

Mi (hackish) intento hasta ahora:

  function get_centroid(sel){
    var coords = d3.select(sel).attr('d');
    coords = coords.replace(/*[LC] */g,'],[').replace(/*M */g,'[[[').replace(/*z */g,']]]').replace(//g,'],[');
    return d3.geo.path().centroid({
      "type":"Feature",
      "geometry":{"type":"Polygon","coordinates":JSON.parse(coords)}
    });
  }

Esto parece funcionar en algunos estados como Missouri, pero otros, como Washington no porque mi SVG el análisis de datos es tan rudimentaria. ¿D3 apoyar algo como esto de forma nativa?

Aquí está el DOM interfaz para las rutas SVG. Podría ser un buen lugar de partida.

OriginalEl autor Zikes | 2012-08-21

2 Kommentare

  1. 53

    El D3 funciones todos parecen asumir que usted está comenzando con GeoJSON. Sin embargo, yo en realidad no creo que necesites el centroide para esto – lo que realmente necesita es el cuadro delimitador, y afortunadamente esto está disponible directamente desde el SVG DOM interfaz:

    function getBoundingBoxCenter (selection) {
      //get the DOM element from a D3 selection
      //you could also use "this" inside .each()
      var element = selection.node();
      //use the native SVG interface to get the bounding box
      var bbox = element.getBBox();
      //return the center of the bounding box
      return [bbox.x + bbox.width/2, bbox.y + bbox.height/2];
    }

    Este es en realidad un poco mejor que el verdadero centro de gravedad para el propósito de la función de zoom, ya que evita algunos de proyección cuestiones que de otro modo podrían ejecutar en.

    +1 para la solución detallada y de mencionar que usted no necesita GeoJSON para thisl
    +1 Informativo y el bit más acerca de la ventaja de usar el zoom con el cuadro delimitador aquí era valiosa para la solución que estaba buscando.
    Que puede funcionar para las formas cuadradas como la de U. S estados, sin embargo, plátano formas requieren un enfoque diferente.
    Mi punto aquí es que para el zoom a la característica de caso de uso, usted no necesita o desea el verdadero centro de gravedad. Este código no pretende calcular el verdadero centro de gravedad, se aborda el OP zoom caso de uso en su lugar.

    OriginalEl autor nrabinowitz

  2. 0

    La aceptada respuesta fue un gran trabajo para mí, hasta que he probado en el Borde. No puedo comentar ya que no tengo suficiente karma o lo que sea, pero fue el uso de esta solución y se encontró un problema con Microsoft Borde, que no utiliza x o y, justo arriba/izquierda/inferior/derecha, etc.

    Por lo que el código anterior debe ser:

    function getBoundingBoxCenter (selection) {
      //get the DOM element from a D3 selection
      //you could also use "this" inside .each()
      var element = selection.node();
      //use the native SVG interface to get the bounding box
      var bbox = element.getBBox();
      //return the center of the bounding box
      return [bbox.left + bbox.width/2, bbox.top + bbox.height/2];
    }

    OriginalEl autor Neil Ruud

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea