tutorial library examples ejemplos d3js javascript d3.js svg geojson topojson

javascript - library - Escala d3 v4 mapa para adaptarse a SVG(o en absoluto)



d3js charts examples (1)

Por qué los datos no se proyectan correctamente

La cuestión clave es que tus datos ya están proyectados. Las geo-proyecciones D3 usan datos no proyectados, o en pares de latitud larga. Datos en el datum WGS84. Esencialmente, una geo-proyección d3 toma coordenadas esféricas y las traduce en coordenadas cartesianas xey.

Sus datos no se ajustan a esto: ya es plano. Puedes ver más evidentemente porque Alaska no está donde debería estar (a menos que alguien cambie los pares de latitud larga de Alaska, lo cual es poco probable). Otros signos y síntomas de datos ya proyectados pueden ser una característica que cubre todo el planeta y errores de NaN.

Que esta es una proyección compuesta hace que sea difícil de desprogramar, pero puede visualizar los datos ya proyectados en d3.js.

"Proyectar" datos ya proyectados

Simplemente, puedes definir tu proyección como nula:

var path = d3.geoPath(null);

Esto tomará los datos x, y de las geometrías geojson y lo mostrará como x, y datos. Sin embargo, si sus coordenadas x, y exceden el ancho y alto de su svg, el mapa no estará contenido en su svg (como lo encontró en su ejemplo con .attr("d", d3.geoPath()); ).

Si desea un poco de control sobre cómo se muestran esos datos, puede usar una geoTransform .

De Mike Bostock :

Pero, ¿y si tu geometría ya es plana? Es decir, ¿qué sucede si solo desea tomar la geometría proyectada, pero aún así traducirla o escalarla para que se ajuste a la ventana gráfica?

Puede implementar una transformación de geometría personalizada para obtener control completo sobre el proceso de proyección.

Usar una geoTransform es relativamente sencillo, suponiendo que no desea cambiar el tipo de proyección . Por ejemplo, si desea escalar los datos, puede implementar una función corta para escalar con geoTransform :

function scale (scaleFactor) { return d3.geoTransform({ point: function(x, y) { this.stream.point(x * scaleFactor, y * scaleFactor); } }); } var path = d3.geoPath().projection(scale(0.2));

Sin embargo, esto escalará todo en la esquina superior izquierda al alejarse. Para mantener las cosas centradas, puede agregar un código para centrar la proyección:

function scale (scaleFactor,width,height) { return d3.geoTransform({ point: function(x, y) { this.stream.point( (x - width/2) * scaleFactor + width/2 , (y - height/2) * scaleFactor + height/2); } }); } var path = d3.geoPath().projection(scale(0.2,width,height))

Manifestación:

En caso de que el fragmento no cargue el json, he publicado un bl.ock aquí .

Aquí hay un ejemplo usando su archivo:

var width = 600; var height = 300; var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); function scale (scaleFactor,width,height) { return d3.geoTransform({ point: function(x, y) { this.stream.point( (x - width/2) * scaleFactor + width/2 , (y - height/2) * scaleFactor + height/2); } }); } d3.json("https://d3js.org/us-10m.v1.json", function (error, us){ var path = d3.geoPath().projection(scale(0.2,width,height)) svg.append("g") .attr("class", "states") .selectAll("path") .data(topojson.feature(us, us.objects.states).features) .enter().append("path") .attr("fill", "gray") .attr("d", path); });

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/2.2.0/topojson.js"></script>

¿Cómo puede saber si sus datos ya están proyectados?

Puede verificar que la geometría de sus características respete los límites de latitud y longitud. Por ejemplo, si tuviera que iniciar sesión:

d3.json("https://d3js.org/us-10m.v1.json", function (error, us){ console.log(topojson.feature(us, us.objects.states).features); });

Verá rápidamente que los valores son superiores a +/- 90 grados N / S y +/- 180 grados E / W. Es poco probable que sean pares de latitud larga.

Alternativamente, podría importar sus datos a un servicio en línea como mapshaper.org y compararlos contra otro topojson / geojson que sepa que no está proyectado (o ''proyectado'' usando WGS84).

Si se trata de geojson, puede tener la suerte de ver una propiedad que define la proyección, como: "name": "urn:ogc:def:crs:OGC:1.3:CRS84" (CRS significa sistema de referencia de coordenadas) o un número EPSG: EPSG:4326 (EPSG significa European Petroleum Survey Group).

Además, si sus proyectos de datos con una proyección nula, pero no una proyección estándar (escalada / alejamiento para asegurarse de que no está buscando en el área incorrecta), podría estar lidiando con los datos proyectados. Del mismo modo, si su ventana gráfica está completamente cubierta por una función (y no está ampliada). Las coordenadas NaN también son un indicador potencial. Sin embargo, estos últimos indicadores de datos proyectados también pueden significar otros problemas.

Por último, la fuente de datos también puede indicar que los datos ya están proyectados en los metadatos o en cómo se usan: al observar este bloque , podemos ver que no se utilizó ninguna proyección cuando se definió geoPath .

Estoy tratando de hacer que este mapa de la escala estadounidense sea más pequeño. Ya sea a mi SVG, o incluso manualmente.

Este es mi código en su forma más simple de:

function initializeMapDifferent(){ var svg = d3.select("#map").append("svg") .attr("width", 1000) .attr("height", 500); d3.json("https://d3js.org/us-10m.v1.json", function (error, us){ svg.append("g") .attr("class", "states") .selectAll("path") .data(topojson.feature(us, us.objects.states).features) .enter().append("path") .attr("fill", "gray") .attr("d", d3.geoPath()); }); }

He intentado algo como:

var path = d3.geoPath() .projection(d3.geoConicConformal() .parallels([33, 45]) .rotate([96, -39]) .fitSize([width, height], conus));

pero cada vez que agrego algo a mi variable de ruta obtengo errores NAN de las partes internas de D3. ¡Gracias por cualquier ayuda!