Acceso estudiantes


¿Has olvidado tu contraseña?

Crear un mapa web interactivo con D3

Al desarrollar un mapa web interactivo nos planteamos habitualmente el uso de librerías como OpenLayers o Leaflet, tal y como vimos en posts anteriores: ¿Leaflet o OpenLayers? o Mejorando nuestros mapas de Leaflet/OpenLayers con la librería Materialize. Pero también podemos desarrollar un mapa web interactivo con D3, tal y como expondremos en el siguiente post.

¿Qué es D3.js?

D3 es una librería JavaScript diseñada para la visualización de datos de forma dinámica e interactiva utilizando estándares web. Para ello, hace uso de tecnologías bien consolidadas como HTML5, SVG y CSS. Presenta además una gran popularidad, con 168M de descargas desde Febrero de 2015, y valorado con 98k estrellas –en el momento de escribir este artículo– en su cuenta de gitHub.

Tal y como puede constatarse en la página de ejemplos de D3.js, son muchas las representaciones de datos que se pueden llevar a cabo con esta librería. Mayoritariamente gráficos y diagramas, aunque también mapas web dinámicos e interactivos.

Mapa dinámico con d3
Mapa dinámico realizado con D3.js. Fuente: D3 in depth

Añadir la librería D3

Para añadir a nuestro proyecto un mapa web interactivo realizado con D3, lo primero que hay que hacer es cargar la librería. Podemos añadir directamente el CDN:

<script src="https://d3js.org/d3.v7.min.js"></script>

o bien, si desarrollamos el proyecto con Node, instalar el paquete correspondiente:

npm install d3

Cartografía y proyecciones

Los datos geográficos a partir de los cuáles crearemos el mapa web interactivo con D3, pueden estar en formato GeoJSON. Se trata de un estándar abierto, basado en el formato JSON, y que permite representar puntos, líneas y polígonos, así como sus atributos no espaciales.

Tal y como veremos, la librería D3 ofrece las herramientas necesarias para convertir el GeoJSON a SVG (Scalable Vector Graphics), el formato con el que trabaja D3 de forma nativa.

Desde la página web de Natural Earth Data, podemos descargar la cartografía vectorial (en formato Shapefile) relativa a los límites administrativos de todos los países del mundo. Será esta cartografía con la que vamos a realizar nuestro mapa web interactivo.

Desde cualquier software SIG se puede convertir el archivo Shapefile a GeoJSON. O también se puede ejecutar directamente esta comanda con GDAL:

ogr2ogr -f GeoJSON countries.json ne_10m_admin_0_countries/ne_10m_admin_0_countries.shp 

El sistema de referencia de los datos descargados de Natural Earth es el WGS84. Al generar el GeoJSON a partir de esta cartografía, hemos mantenido este sistema de referencia en el nuevo archivo. Aunque una vez en D3, ya veremos cómo resultará muy fácil modificar la proyección de los mapas generados.

Asimismo, d3-geo y d3-geo-projection ofrecen multitud de proyecciones para poder utilizar.

Código para generar un mapa web con D3

En el código html de la aplicación web, deberemos crear el espacio en el que ubicar el mapa. En este ejemplo, será en la etiqueta <svg> con el id map.

<!DOCTYPE html>
<html>
<head>
  <title>Webmapping con d3</title>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

  <link rel="stylesheet" href="style.css">
</head>
<body>

  <h1>Mapas web interactivos con D3</h1>
  <p>Países del mundo</p>

  <svg id="map" width="50vw" height="50vh"></svg>

  <script src="main.js"></script>
</body>
</html>

Añadimos algunas propiedades para centrar el contenido en el fichero de estilos:

p,
h1{
  text-align: center;
}

#map{
  align-content: center;
}

svg {
  display: block;
  margin: auto;
  border: 1px solid gray;
}

Y las instrucciones para generar el mapa web con D3, en el fichero javascript:

// importamos la librería
import * as d3 from "d3";

// cargamos el archivo json que hemos generado previamente
// en este caso, el archvio lo hemos ubicado en un servidor apache
d3.json("http://localhost/countries.json").then(geodata => {

  // almacenamos en una variable la proyección a utilizar
  // en este caso, utilizamos la proyección Natural Earth (http://www.shadedrelief.com/NE_proj/)
  let projection = d3.geoNaturalEarth1()

  // creamos el elemento SVG asignándole la proyección definida anteriormente
  let generator = d3.geoPath().projection(projection);

  // añadimos el SVG en el fichero html, justo en la etiqueta que hemos creado con el nombre svg.
  d3.select("svg")

    .selectAll("path")

    // añadimos los datos
    .data(geodata.features)

    .join("path")

    .attr("d", generator)

    // añadimos algunos estilos básicos en el mapa
    .attr('stroke', '#000')

    .attr('fill', '#fff')

});

De este modo, y en pocas líneas de código, conseguimos realizar un simple mapa con D3.

Mapa elaborado con D3 para representar la cartografía de países del mundo. Fuente: elaboración propia.

Aplicar estilo a la cartografía

La librería D3 ofrece también la posibilidad de aplicar estilo a los datos, a partir de los valores de alguno de los campos. En este caso, vamos a crear un mapa de coropletas, en base al total de población de cada uno de los países. En la cartografía de Natural Earth, los datos de población se encuentran en un campo con el nombre POP_EST.

Utilizaremos la función d3.scaleThereshold para definir los rangos de valor y el color asociado a cada uno de ellos.

  var escalaColor = d3.scaleThreshold()
  .domain([100000, 1000000, 10000000, 30000000, 100000000, 500000000])
  .range(d3.schemeBlues[7]);

En domain se definen mediante un array, los límites del rango de valores apropiado a los datos a tematizar, mientras que en range, el color asociado a cada uno de ellos.

Para generar de forma automática la rampa de color, utilizamos otra función de D3: d3.schemaBlues. En este caso, usamos una rampa de color azul, aunque hay muchas otras disponibles.

Por último, deberemos cambiar el atributo que utilizamos inicialmente para asignar el color de relleno de cada una de las entidades del mapa.

//.attr('fill', '#fff')
.attr("fill", function (d) {
    return escalaColor(d.properties.POP_EST);
})

De este modo, en pocas líneas de código podemos dar estilo a los datos, pudiendo además modificar muy rápidamente tanto la escala de color como los rangos de valor .

Tematización del mapa web interactivo con d3
Tematización de los datos en función de un atributo. Fuente: elaboración propia.

Dotar de interactividad al mapa

También es posible dotar de interactividad al mapa, de tal forma que, por ejemplo, podamos consultar información de las entidades representadas.

En este caso, vamos a mostrar la información relativa al país sobre el que nos situemos, así como el total de población.

En primer lugar, en el archivo html creamos el div en el que se añadirá esta información.

<div class="info">El país seleccionado es: <span id="name"></span> con una población de <span id="population"></span> habitantes</div>

Por otro lado, en el archivo javascript, creamos una función que permita obtener el nombre del país y su población, así como añadir estos datos en el documento html:

var selectCountry = function(d){
    var country_name = d.target.__data__.properties.FORMAL_EN;
    var population =  d.target.__data__.properties.POP_EST;
    document.getElementById("name").innerHTML = country_name;
    document.getElementById("population").innerHTML = population;
  }

Y hacemos la llamada a esta función al detectar el movimiento del puntero sobre el mapa:

.on('mousemove', selectCountry )

El resultado es el que se muestra a continuación:

Consulta de datos del mapa web interactivo con d3
Consultar datos del mapa de forma interactiva. Fuente: elaboración propia

Conclusiones

La librería D3 nos permite elaborar mapas web interactivos utilizando lenguaje html, css y javascript.

En este post hemos visto cómo crear un mapa interactivo bastante simple. Pero las posibilidades que nos ofrece la librería son muy amplias, permitiendo elaborar visualizaciones complejas y dotándoles de interactividad.

La librería D3 puede ser, en este sentido, una alternativa a tener en cuenta en el desarrollo de proyectos de webmapping.

Josep Sitjar
Geógrafo y máster en medio ambiente, análisis y gestión del territorio. Actualmente estoy cursando un grado superior en desarrollo de aplicaciones web. Trabajo en el Servicio de SIG y Teledetección (SIGTE) de la Universitat de Girona participando en numerosos proyectos técnicos vinculados al mundo de los SIG y al desarrollo de aplicaciones web map.


Suscríbete a nuestra newsletter