Używam SVG znajdującego się w http://upload.wikimedia.org/wikipedia/commons/ 3/32 / Blank_us_map.svg w projekcie i interakcji z nim z D3.JS. Chciałbym utworzyć kliknięcie, aby powiększyć efekt jak http://bl.ocks.org/2206590, jednak ten przykład Na danych ścieżkach przechowywanych w obiekcie JSON, aby obliczyć Centroid. Czy jest jakiś sposób ładowania danych ścieżki w D3 z istniejącego SVG, aby uzyskać środek centroid?

Moje (hackish) próba do tej pory:

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

Wydaje się, że działa na niektórych państwach, takich jak Missouri, ale inni, takich jak Waszyngton, ponieważ moje parsowanie danych SVG jest tak prymitywny. Czy D3 obsługuje coś takiego naturalnie?

22
Zikes 22 sierpień 2012, 00:29

3 odpowiedzi

Najlepsza odpowiedź

Funkcje D3 wydają się zakładać, że zaczynasz od Geajson. Jednak nie myślę jednak, że potrzebujesz centrum centroidu - czego naprawdę potrzebujesz, jest obwiedni, a na szczęście jest to dostępne bezpośrednio z interfejsu SVG DOM:

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];
}

Jest to w rzeczywistości nieco lepsze niż prawdziwe centroid w celu powiększenia, ponieważ pozwala uniknąć pewnych problemów z projekcji, w jaką można jeździć.

58
Balthazar 13 styczeń 2017, 01:34

Przyjęta odpowiedź była dla mnie świetna, dopóki nie przetestowałem w brzegu. Nie mogę komentować, ponieważ nie mam wystarczającej karmy lub cokolwiek, ale użyłem tego rozwiązania i znalazłem problem z krawędzią Microsoft, która nie używa X lub Y, tylko do góry / w lewo / dołu / w prawo itp.

Więc powyższy kod powinien być:

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];
}
2
Neil Ruud 30 listopad 2017, 10:32

Z Oto

Rozwiązaniem jest użycie metody .datum () w wyborze.

var element = d3.select("#element");
var centroid = path.centroid(element.datum());
0
Matthew 2 kwiecień 2020, 20:24