У Майка Бостока есть замечательный туториал о том, как сделать карту с помощью d3 и topojson. Недавно проделав некоторую картографическую работу для клиента, я очень хотел узнать больше и попробовать сделать картограмму на основе d3. Я нашел несколько хороших примеров несмежных картограмм, но я хотел сделать южноафриканскую версию непрерывной картограммы, используя реализацию Шона Аллена d3.
Вот конечный продукт, и я расскажу вам о некоторых сложных моментах, с которыми мне пришлось столкнуться.
https://fletchjeff.github.io/zacartogram/
Первое изображение представляет собой карту ZA с разграничением местных муниципалитетов. Используя данные о голосовании за 2011 год с www.iec.org.za, я нанес на карту победившую партию каждого местного муниципалитета разными цветами.
Что я хотел увидеть, так это то, как изменились размеры территории, когда вы сопоставили это с зарегистрированными избирателями в муниципалитете. Опять же, используя данные IEC, я передал количество зарегистрированных избирателей в функцию картограммы, чтобы изменить относительный размер каждого муниципалитета в зависимости от количества избирателей. На приведенной выше карте вы можете увидеть, как сильно разросся город Йоханнесбург.
Код Шона имеет множество вариантов данных и использует информацию о штатах США и географию. Поскольку штат и муниципалитет достаточно похожи, я попытался сопоставить файл TopoJSON для муниципалитетов Южной Африки с его кодом. Это заняло некоторое время, и я начал понимать, как это работает, только после значительного упрощения.
Вы можете взять код здесь. Я прокомментировал более сложные части и значительно сократил объем проекта по сравнению с исходной реализацией Шона, чтобы сделать его модификацию более понятной.
Первая проблема заключалась в наличии правильных версий библиотек. В cartogram.js используется d3.v2.min.js и определенная версия topojson.js. Использование версий на d3js.org, казалось, сломалось. Вы можете просто взять те, на которые есть ссылки с моей карты, для zip-пакета.
<script src="lib/d3.v2.min.js"></script> <script src="lib/topojson.js"></script> <script src="lib/cartogram.js"></script>
В примере Шона использовались данные из CSV-файла для создания свойств, используемых на карте. Однако мой файл топойсона уже включает свойства каждого муниципалитета. Метод .properties добавляет свойства, которые вы можете использовать для имен, цветов и т. д.
var carto = d3.cartogram() .projection(proj) .properties(function (d) { // this adds the "properties" properties // to the geometries return d.properties; });
d3.cartogram использует d3.topojson для создания данных объектов и добавляет возможность пересчета форм отдельных областей на основе некоторого числового ввода. Чтобы создать исходные функции, вызовите картограмму следующим образом:
var features = carto.features(topology, geometries)
Чтобы изменить/исказить фигуры, вызовите картограмму следующим образом:
carto.value(function (d) { return +vote_data.get(d.properties["CAT_B"])[1]; }); var features = carto(topology, geometries).features;
Я буду честен и скажу, что действительно не понимаю разницы между этими двумя способами создания данных объектов, но, похоже, это работает. Число, которое вы возвращаете в carto.value(), устанавливает площадь относительно максимального и минимального числа, которое вы возвращаете. Например, если вы вернете 1, то фигуры будут иметь одинаковую площадь.
Первоначально опубликовано на https://limn.co.za 23 октября 2013 г.