Карта к совершенству: использование D3.js для создания красивых веб-карт
Опубликовано: 2022-03-11Документы, управляемые данными, или D3.js, — это «библиотека JavaScript для управления документами на основе данных». Или, проще говоря, D3.js — это библиотека визуализации данных. Он был разработан Майком Бостоком с целью устранить разрыв между статическим отображением данных и интерактивной и анимированной визуализацией данных.
D3 — мощная библиотека с массой применений. В этом уроке я расскажу об одном особенно интересном применении D3: создании карт. Мы рассмотрим общие проблемы создания полезной и информативной веб-карты и покажем, как в каждом случае D3.js дает способным разработчикам JavaScript все, что им нужно, чтобы карты выглядели и чувствовались красиво.
Для чего используется D3.js?
D3.js может привязывать любые произвольные данные к объектной модели документа (DOM), а затем с помощью JavaScript, CSS, HTML и SVG применять к документу преобразования, управляемые этими данными. Результатом может быть простой вывод HTML или интерактивные диаграммы SVG с динамическим поведением, таким как анимация, переходы и взаимодействие. Все преобразования данных и рендеринг выполняются на стороне клиента в браузере.
В самом простом случае D3.js можно использовать для управления DOM. Вот простой пример, где D3.js используется для добавления элемента абзаца в пустой текст документа с текстом «Hello World»:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>D3 Hello World</title> <script src="http://d3js.org/d3.v3.min.js"></script> </head> <body> <script type="text/javascript"> d3.select("body").append("p").text("Hello World"); </script> </body> </html>
Однако сила D3.js заключается в его способности визуализации данных. Например, его можно использовать для создания диаграмм. Его можно использовать для создания анимированных диаграмм. Его можно даже использовать для интеграции и анимации различных подключенных диаграмм.
D3 для веб-карт и визуализации географических данных
Но D3.js можно использовать не только для манипулирования DOM или для рисования диаграмм. D3.js чрезвычайно эффективен, когда дело доходит до обработки географической информации. Манипуляции и представление географических данных могут быть очень сложными, но создание карты с помощью D3.js довольно просто.
Вот пример D3.js, который будет рисовать карту мира на основе данных, хранящихся в формате данных, совместимом с JSON. Вам просто нужно определить размер карты и используемую географическую проекцию (подробнее об этом позже), определить элемент SVG, добавить его в DOM и загрузить данные карты с помощью JSON. Стилизация карты выполняется с помощью CSS.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>D3 World Map</title> <style> path { stroke: white; stroke-width: 0.5px; fill: black; } </style> <script src="http://d3js.org/d3.v3.min.js"></script> <script src="http://d3js.org/topojson.v0.min.js"></script> </head> <body> <script type="text/javascript"> var width = 900; var height = 600; var projection = d3.geo.mercator(); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var path = d3.geo.path() .projection(projection); var g = svg.append("g"); d3.json("world-110m2.json", function(error, topology) { g.selectAll("path") .data(topojson.object(topology, topology.objects.countries) .geometries) .enter() .append("path") .attr("d", path) }); </script> </body> </html>
Географические данные для D3
При работе с этим руководством по D3.js помните, что построение карт лучше всего работает с данными, отформатированными в форматах JSON, особенно со спецификациями GeoJSON и TopoJSON.
GeoJSON — это «формат для кодирования различных структур географических данных». Он предназначен для представления объектов дискретной геометрии, сгруппированных в наборы функций пар имя/значение.
TopoJSON — это расширение GeoJSON, которое может кодировать топологию, в которой геометрия «сшивается вместе из общих сегментов линий, называемых дугами». TopoJSON устраняет избыточность, сохраняя реляционную информацию между географическими объектами, а не просто пространственную информацию. В результате геометрия становится намного более компактной и комбинированной, когда геометрии имеют общие черты. Это приводит к тому, что типичный файл TopoJSON на 80% меньше, чем его эквивалент GeoJSON.
Так, например, для карты с несколькими граничащими друг с другом странами общие части границ будут храниться в GeoJSON дважды, по одному разу для каждой страны по обе стороны от границы. В TopoJSON это будет всего одна строка.
Библиотеки карт: Google Maps и Leaflet.js
На сегодняшний день самыми популярными картографическими библиотеками являются Google Maps и Leaflet. Они предназначены для быстрого и легкого получения «скользких карт» в Интернете. «Скользящие карты» — это термин, относящийся к современным веб-картам на основе JavaScript, которые позволяют масштабировать и перемещаться по карте.
Листовка — отличная альтернатива Google Maps. Это библиотека JavaScript с открытым исходным кодом, предназначенная для создания интерактивных карт, удобных для мобильных устройств, с учетом простоты, производительности и удобства использования. Leaflet лучше всего подходит для использования большого выбора растровых карт, доступных в Интернете, и обеспечивает простоту работы с мозаичными картами и их возможности представления.

Leaflet можно с большим успехом использовать в сочетании с функциями обработки данных D3.js и для использования D3.js для векторной графики. Объединение их вместе выявляет лучшее в обеих библиотеках.
Карты Google сложнее комбинировать с D3.js, поскольку исходный код Google Maps закрыт. Можно использовать Карты Google и D3 вместе, но в основном это ограничивается наложением данных с помощью D3.js на фоновые карты Карт Google. Более глубокая интеграция невозможна без взлома.
Проекции - Beyond Spherical Mercator
Вопрос о том, как проецировать карты трехмерной сферической Земли на двумерные поверхности, является старой и сложной проблемой. Выбор наилучшей проекции для карты — важное решение для каждой веб-карты.
В нашем руководстве по простой карте мира D3.js выше мы использовали систему координат сферической проекции Меркатора, вызвав d3.geo.mercator()
. Эта проекция также известна как Web Mercator. Эта проекция была популяризирована Google, когда они представили Google Maps. Позже эту проекцию переняли и другие веб-сервисы, а именно OpenStreetMap, Bing Maps, Here Maps и MapQuest. Это сделало Spherical Mercator очень популярной проекцией для скользких онлайн-карт.
Все картографические библиотеки поддерживают сферическую проекцию Меркатора по умолчанию. Если вы хотите использовать другие проекции, вам нужно будет использовать, например, библиотеку Proj4js, которая может делать любые преобразования из одной системы координат в другую. В случае с Leaflet есть плагин Proj4Leaflet. В случае с Google Maps, ну, ничего.
D3.js выводит картографические проекции на совершенно новый уровень благодаря встроенной поддержке множества различных географических проекций. D3.js моделирует географические проекции как полные геометрические преобразования, а это означает, что когда прямые линии проецируются на кривые, D3.js применяет настраиваемую адаптивную передискретизацию для разделения линий и устранения артефактов проекции. Плагин Extended Geographic Projections D3 доводит количество поддерживаемых проекций до более чем 40. Можно даже создать совершенно новую пользовательскую проекцию, используя d3.geo.projection
и d3.geo.projectionMutator
.
Растровые карты
Как упоминалось ранее, одна из сильных сторон D3.js заключается в работе с векторными данными. Для использования растровых данных есть возможность объединить D3.js с Leaflet. Но есть также возможность делать все только с помощью D3.js, используя d3.geo.tile для создания скользких карт. Даже имея только D3.js, люди делают удивительные вещи с растровыми картами.
Векторные манипуляции на лету
Одной из самых больших проблем в классической картографии является обобщение карты. Вы хотите иметь как можно больше подробной геометрии, но эти данные должны адаптироваться к масштабу отображаемой карты. Слишком высокое разрешение данных увеличивает время загрузки и замедляет рендеринг, а слишком низкое разрешение портит детали и топологические отношения. Скользкие карты, использующие векторные данные, могут столкнуться с большой проблемой при обобщении карты.
Одним из вариантов является предварительное обобщение карты: иметь разные наборы данных с разным разрешением, а затем отображать соответствующий набор данных для текущего выбранного масштаба. Но это умножает наборы данных, усложняет обслуживание данных и чревато ошибками. Тем не менее, большинство картографических библиотек ограничены этой опцией.
Лучшее решение — делать обобщение карты на лету. И вот снова D3.js с его мощными функциями обработки данных. D3.js позволяет упростить строку в браузере.
Я хочу больше!
D3.js непросто освоить, и у него крутая кривая обучения. Необходимо быть знакомым со многими технологиями, а именно с объектами JavaScript, синтаксисом цепочек jQuery, SVG и CSS и, конечно же, API D3. Вдобавок ко всему, нужно иметь немного дизайнерских навыков, чтобы в итоге создать красивую графику. К счастью, у D3.js большое сообщество и множество ресурсов, в которых люди могут покопаться. Эти учебники — отличная отправная точка для изучения D3.
Если вам нравится учиться на примерах, Майк Босток поделился более чем 600 примерами D3.js на своей веб-странице. Все примеры D3.js имеют репозиторий git для контроля версий, их можно разветвлять, клонировать и комментировать.
Если вы используете CartoDB, вам будет приятно узнать, что CartoDB упрощает работу с картами D3.
И в качестве небольшого бонуса в конце, вот один из моих любимых примеров, демонстрирующий удивительные возможности D3:
- земля, глобальная анимированная 3D-карта ветра всего мира, созданная с помощью D3.js. Земля — это визуализация глобальных погодных условий, основанная на прогнозах погоды, сделанных суперкомпьютерами в Национальных центрах прогнозирования окружающей среды, NOAA/Национальной метеорологической службе и преобразованных в JSON. Вы можете настроить отображаемые данные, такие как высота для показаний скорости ветра, изменить наложенные данные и даже изменить проекцию Земли.