Je suis nouveau dans d3 - je vais essayer d'expliquer comment je le comprends mais je ne suis pas sûr d'avoir tout bien compris.
Le secret est de savoir que certaines méthodes opéreront sur l'espace cartographique (latitude, longitude) et d'autres sur l'espace cartésien (x, y sur l'écran). L'espace cartographique (notre planète) est (presque) sphérique, l'espace cartésien (écran) est plat - pour cartographier l'un sur l'autre, vous avez besoin d'un algorithme appelé projection . Cet espace est trop court pour approfondir le sujet fascinant des projections et comment elles déforment les caractéristiques géographiques afin de transformer sphérique en plan; certains sont conçus pour conserver les angles, d'autres pour conserver les distances et ainsi de suite - il y a toujours un compromis (Mike Bostock a une énorme collection d'exemples ).
En d3, l'objet de projection a une propriété / setter center, donnée en unités cartographiques:
projection.center ([emplacement])
Si center est spécifié, définit le centre de la projection sur l'emplacement spécifié, un tableau à deux éléments de longitude et de latitude en degrés et renvoie la projection. Si le centre n'est pas spécifié, renvoie le centre actuel qui est par défaut ⟨0 °, 0 °⟩.
Il y a aussi la translation, donnée en pixels - où le centre de projection se situe par rapport au canevas:
projection.translate ([point])
Si le point est spécifié, définit le décalage de translation de la projection sur le tableau à deux éléments spécifié [x, y] et renvoie la projection. Si le point n'est pas spécifié, renvoie le décalage de traduction actuel qui est par défaut [480, 250]. Le décalage de translation détermine les coordonnées en pixels du centre de la projection. Le décalage de translation par défaut place ⟨0 °, 0 °⟩ au centre d'une zone 960 × 500.
Lorsque je souhaite centrer une entité dans le canevas, j'aime définir le centre de projection au centre de la zone de délimitation de l'entité - cela fonctionne pour moi lorsque j'utilise mercator (WGS 84, utilisé dans Google Maps) pour mon pays (Brésil), jamais testé en utilisant d'autres projections et hémisphères. Vous devrez peut-être faire des ajustements pour d'autres situations, mais si vous appliquez ces principes de base, tout ira bien.
Par exemple, étant donné une projection et un chemin:
var projection = d3.geo.mercator()
.scale(1);
var path = d3.geo.path()
.projection(projection);
La bounds
méthode from path
renvoie le cadre de sélection en pixels . Utilisez-le pour trouver la bonne échelle, en comparant la taille en pixels avec la taille en unités de la carte (0,95 vous donne une marge de 5% sur le meilleur ajustement pour la largeur ou la hauteur). Géométrie de base ici, calculant la largeur / hauteur du rectangle en fonction des coins diagonalement opposés:
var b = path.bounds(feature),
s = 0.9 / Math.max(
(b[1][0] - b[0][0]) / width,
(b[1][1] - b[0][1]) / height
);
projection.scale(s);
Utilisez la d3.geo.bounds
méthode pour trouver la boîte englobante en unités de carte:
b = d3.geo.bounds(feature);
Définissez le centre de la projection sur le centre du cadre de sélection:
projection.center([(b[1][0]+b[0][0])/2, (b[1][1]+b[0][1])/2]);
Utilisez la translate
méthode pour déplacer le centre de la carte vers le centre du canevas:
projection.translate([width/2, height/2]);
Vous devriez maintenant avoir la fonction au centre de la carte agrandie avec une marge de 5%.