Sono nuovo di d3 - proverò a spiegare come lo capisco ma non sono sicuro di aver fatto tutto bene.
Il segreto sta nel sapere che alcuni metodi opereranno sullo spazio cartografico (latitudine, longitudine) e altri sullo spazio cartesiano (x, y sullo schermo). Lo spazio cartografico (il nostro pianeta) è (quasi) sferico, lo spazio cartesiano (schermo) è piatto - per mappare l'uno sull'altro è necessario un algoritmo, chiamato proiezione . Questo spazio è troppo breve per approfondire l'affascinante soggetto delle proiezioni e il modo in cui distorcono le caratteristiche geografiche per trasformare il piano sferico in piano; alcuni sono progettati per conservare gli angoli, altri conservano le distanze e così via - c'è sempre un compromesso (Mike Bostock ha una vasta collezione di esempi ).
In d3, l'oggetto di proiezione ha una proprietà / setter centrale, espressa in unità cartografiche:
projection.center ([percorso])
Se viene specificato center, imposta il centro della proiezione nella posizione specificata, una matrice a due elementi di longitudine e latitudine in gradi e restituisce la proiezione. Se il centro non è specificato, restituisce il centro corrente che per impostazione predefinita è ⟨0 °, 0 °⟩.
C'è anche la traduzione, data in pixel - dove si trova il centro di proiezione rispetto alla tela:
projection.translate ([punto])
Se viene specificato point, imposta l'offset di traslazione della proiezione sull'array a due elementi specificato [x, y] e restituisce la proiezione. Se il punto non è specificato, restituisce l'offset di traduzione corrente, il cui valore predefinito è [480, 250]. L'offset di traduzione determina le coordinate dei pixel del centro della proiezione. L'offset di traduzione predefinito posiziona ⟨0 °, 0 °⟩ al centro di un'area 960 × 500.
Quando voglio centrare una funzione nell'area di disegno, mi piace impostare il centro di proiezione al centro del riquadro di delimitazione della funzione: questo funziona per me quando utilizzo mercator (WGS 84, utilizzato in google maps) per il mio paese (Brasile), mai testato utilizzando altre proiezioni ed emisferi. Potrebbe essere necessario apportare modifiche per altre situazioni, ma se inchiodi questi principi di base andrà bene.
Ad esempio, dati una proiezione e un percorso:
var projection = d3.geo.mercator()
.scale(1);
var path = d3.geo.path()
.projection(projection);
Il bounds
metodo da path
restituisce il rettangolo di selezione in pixel . Usalo per trovare la scala corretta, confrontando la dimensione in pixel con la dimensione in unità della mappa (0,95 ti dà un margine del 5% sulla misura migliore per larghezza o altezza). Geometria di base qui, calcolando la larghezza / altezza del rettangolo dati gli angoli diagonalmente opposti:
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);
Utilizzare il d3.geo.bounds
metodo per trovare il rettangolo di selezione nelle unità della mappa:
b = d3.geo.bounds(feature);
Imposta il centro della proiezione al centro del riquadro di selezione:
projection.center([(b[1][0]+b[0][0])/2, (b[1][1]+b[0][1])/2]);
Usa il translate
metodo per spostare il centro della mappa al centro dell'area di disegno:
projection.translate([width/2, height/2]);
Ormai dovresti avere la funzione al centro della mappa ingrandita con un margine del 5%.