Как да създадете чисти реагиращи SVG карти с topojson и d3-geo

Тъй като d3 беше разделен на по-малки компоненти в v4, сдвояването му с реакция стана по-рационално. Правенето на декларативни SVG карти с реакция, топойсон и d3-geo никога не е било по-лесно.

Тази статия ще ви покаже как да създавате чисти реагиращи SVG карти с topojson-client и d3-geo. Описаните тук техники ще ви помогнат да направите свои собствени компоненти за SVG картографиране за многократна употреба.

Какво обхваща тази статия

  1. Анатомията на SVG карта, независима от реакцията
  2. Структура на примерните зависимости на приложението и npm
  3. Зареждане на topojson и рендериране на основна SVG карта с react и d3-geo
  4. Добавяне на събития
  5. Примерна карта, управлявана от данни с маркери

код

Кодът за този урок е достъпен в repo на react-svg-maps-tutorial на github.

Забележка: Този урок обхваща създаването на проста SVG карта. Ако имате нужда от повече функционалности, като мащабиране, панорамиране и пояснения, съставих библиотека с компоненти за многократна употреба, които можете да инсталирате чрез npm, наречени reakct-simple-maps.

1. Анатомията на SVG карта

За да създадете карта с реагиране и d3-geo, нека първо разгледаме как може да изглежда изходът на такава карта:


  
    
      <път d = "..." class = "страна" />
      <път d = "..." class = "страна" />
    
    
      <кръг клас = "маркер" r = 10 />
      <кръг клас = "маркер" r = 10 />
    
  

Тази структура е напълно независима от това дали използвате reak или друга рамка / инструмент за изобразяване на карта.

Вместо да използваме d3 за манипулиране на DOM и управление на горните елементи, можем да използваме react. В JSX горната структура на практика остава същата (с изключение на клас, който става className).


  
    
      <път d = "..." className = "държава" />
      <път d = "..." className = "държава" />
    
    
      <кръг className = "маркер" r = 10 />
      <кръг className = "маркер" r = 10 />
    
  

Единствената трудна част е генерирането на d-пътя за всяка страна. За да направите това, първо ще ви е необходим геофайл (topojson), съдържащ някои json, описващи пътищата на страната. Тогава ще ви трябва библиотека, която може да превежда такива географски данни в координати. Topojson-client и d3-geo са идеално подходящи за тези задачи. Първият ви позволява да използвате topojson файлове, които са значително по-малки от geojson, а последният ви позволява лесно да управлявате геопрогнози и да превеждате геоданни в координатна система. Използването на d3-geo също ви позволява да се възползвате от богатата колекция от проекции, създадени от Майк Босток.

2. Зависимости и структура

За да създадете карта с реакция, ще ви е необходим основен проект за реакция. За моя собствен пример използвах възможно най-простия котел, за да не се разсейвам от специфичния за картата код. Вижте ръководството за github repo за повече информация.

За картата ще използвам d3-geo и topojson-client (при условие че вече сте инсталирали react и react-dom), така че нека започнем с инсталирането на тези библиотеки:

npm инсталирайте d3-geo topojson-client --save

Структурата на кода за този пример ще изглежда така:

┬ ап
├─┬ ср
┬ ├─┬ компоненти
│ │ └── WorldMap.js
│ └── index.js
├─┬ обществен
│ ├── app.js => код, компилиран от webpack
│ └── свят-110m.json
├── index.js
├── package.json
├── webpack.config.js
└── възел-модули

3. Компонентът WorldMap

Компонентът WorldMap ще направи карта, базирана на картата на света-110m от топойсън-worldatlas. Тъй като искам да персонализирам проекцията и да я използвам повторно за маркери, създадох отделен метод, който връща проекция на Меркатор с някои персонализиране на мащаба и компенсирането. Възползвам се и от свойството SVG viewBox, за да подготвя картата за променливи размери на екрана.

Започнете с дефинирането на worldData като част от състоянието на компонента WorldMap (ред 12). Това ще бъде празен масив в началото и данните ще бъдат заредени асинхронно, след като компонентът се монтира (вижте компонентDidMount на ред 20). Празният масив избягва хвърлянето на грешка при итерация над worldData преди зареждането на картата (вижте ред 39).

За получаване на world-110m.json използвам вградената функция за извличане на Chrome, но можете да използвате всяка библиотека AJAX по ваш избор (например axios, superagent).

Проекцията се използва за изобразяване на d-пътя на пътеките на страната, както и свойството cx и cy на маркерните кръгове. Тъй като проекцията е персонализирана, има смисъл да се напише метод за нея (вижте ред 15).

За да не направя всички страни един и същи цвят, използвам индекса на страната в масива worldData, за да определя непрозрачността на запълване на пътя към страната. Ако имате данни, можете да използвате същата стратегия, за да създадете хороплетна карта.

4. Събития

Добавянето на събития към вашите SVG пътища работи по същия начин като добавянето на събития към всеки друг елемент в JSX. Кодът по-долу показва как да добавите манипулатор на onClick към пътеките за страната.

Същият подход може да се използва и за други събития (например mouseEnter, mouseLeave, mouseMove) за страни, но също така и за маркери.

5. Пример за данни: Повечето населени градове в света

Нека се опитаме да добавим някои данни в сместа и да изведем най-населените градове в света на картата на света. Размерът на маркера ще се определя от размера на населението на града.

Забележка: Към маркерите съм добавил и събитие onClick, извеждайки към момента на конзолата град с клик (виж редове 57 и 103).

Картата ви трябва да изглежда така.

Резултатът от WorldMap.js трябва да изглежда така. Страните са оцветени въз основа на индекса на страната в масива worldData. Размерите на кръга се определят от размера на населението на всеки показан град.

Вече можете да актуализирате набора от данни на маркера с помощта на setState и маркерите ще бъдат актуализирани съответно.

Ако искате да добавите съвети към вашата карта, можете да използвате описаната по-горе техника за обработка на събития. За да изобразите действителната подсказка, можете да използвате библиотека като redux-tooltip.

Следващи стъпки

За прости карти техники, описани в тази статия, трябва да са достатъчни, за да започнете, но след като искате да добавите по-сложна функционалност, като панорама, мащабиране и т.н., става малко по-сложно. Изпълнението е особено труден проблем при реагирането на SVG карти.

Както бе споменато по-горе, аз събрах набор от компоненти за многократна употреба в библиотеката на react-simple-maps, които помагат да се правят по-ефективни SVG карти с react и d3-geo. Библиотеката се справя с по-сложната логика, свързана с оразмеряването, панорама и оптимизация на производителността, така че да можете да се съсредоточите върху красивите и ангажиращи визуализации.

вдъхновение

Ако се интересувате да прочетете повече за използването на react и d3 заедно, проверете „Интерактивни приложения с React и D3“ от Илия Меекс или „Как и защо да използвате d3 с реакция“ от Дан Сканлон.

Ако имате въпроси или мисли за кода в тази статия, моля, оставете съобщение по-долу. Ако сте намерили тази статия за полезна, не се колебайте да споделите и препоръчате. Честито картографиране!