Percorso non mostrato in D3.js topojson grafico
-
22-12-2019 - |
Domanda
Sto cercando di disegnare una mappa usando Topojson, quindi ho seguito questo esempio
Ma non sto ottenendo nulla di disegnato.
Ecco cosa ho scritto
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<style>
path {
fill: #ccc;
stroke: #fff;
stroke-width: .5px;
}
path:hover {
fill: red;
}
</style>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>
var width = 960,
height = 500;
var path = d3.geo.path();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("tunisia.json", function(error, topology) {
console.log(topology);
svg.selectAll("path")
.data(topojson.feature(topology, topology.objects.governorates).features)
.enter().append("path")
.attr("d", path);
});
</script>
</body>
</html>
.
Dopo alcuni debug si scopre che il percorso nel mio caso viene aggiunto come segue:
<svg width="960" height="500">
<path></path>
<path></path>
</svg>
.
considerando che dovrebbe normalmente essere come questo:
<svg width="960" height="500">
<path d="M183.85631949544694,17.16574961388676L184.64695256075555,18.261986556132797L184.24437929962187,21.436416964644536L184.9109502450185,22.72190753660925L183.42733139583214,23.600229178621248L181.43637647772152,23.38526266060535L162.4858998398068,18.04698631290296L162.95134674943927,16.322885588815097L161.24381018256219,15.20848145955324L160.04585728433227,11.701769628478132L161.0879861841512,10.793553936506555L172.9773901748378,14.256236175137701Z"></path>
</svg>
.
Ecco i dati che sto usando: https://raw.githubuserContent.com/mtimet/tnacmaps/master/topojson/Tunisia.json
Potresti controllare cosa sto facendo male
Soluzione
Non ci sono problemi con il tuo file JSON.
Il problema che stai avendo è che non stai definendo una proiezione per il tuo d3.geo.path()
che significa che torna al momento predefinito. Secondo la documentazione legata sopra:
.
#d3.geo.path()
crea un nuovo generatore di percorso geografico con le impostazioni predefinite: albersusa proiezione e Un raggio di punti di 4,5 pixel.
I tuoi dati Geo sono per una mappa della Tunisia, quindi una proiezione di AlberSa non conterrà alcuna coordinata nel tuo set di dati. Questo è il motivo per cui i dati del percorso sono vuoti nell'output.
Per risolvere questo problema, è necessario definire una proiezione. Puoi farlo quando si carica i dati e puoi utilizzare d3.geo.bounds()
, passando nel featureCollection
per trovare i confini geografici dei tuoi dati.
var featureCollection = topojson.feature(topology, topology.objects.governorates);
var bounds = d3.geo.bounds(featureCollection);
.
Poi da questi limiti, è possibile calcolare il centro della tua FeatureCollection:
var centerX = d3.sum(bounds, function(d) {return d[0];}) / 2,
centerY = d3.sum(bounds, function(d) {return d[1];}) / 2;
.
Allora puoi usarlo per centrare la tua proiezione. Ad esempio, se stai usando una proiezione Mercatore, potresti fare quanto segue:
var projection = d3.geo.mercator()
.scale(3000)
.center([centerX, centerY]);
.
La scelta di una scala di 3000 è arbitraria, sembrava funzionare bene in questo caso, modificarlo a qualsiasi cosa funzioni per te.
Infine, è necessario impostare il .projection()
del path
alla proiezione che hai effettuato, prima di creare effettivamente i percorsi SVG.
path.projection(projection);
svg.selectAll("path")
.data(featureCollection.features)
.enter().append("path")
.attr("d", path);
.
qui è un esempio di funzionamento utilizzando i tuoi dati.