У Майка Бостока есть замечательный туториал о том, как сделать карту с помощью 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 г.