Вернуться к списку

Как подключить данные в D3 (d3.js)

  • Закажите данные на интересующую Вас территорию в формате GeoJSON.

  • Дождитесь получения результата, скачайте и распакуйте архив с данными.

  • Выберите нужный слой, например Границы муниципальных районов (boundary-polygon-lvl6.geojson)

  • Чтобы подключить слой в D3, нужно его захостить (положить туда, где он будут доступен по гиперссылке).

Код описывающий простую карту, включающую слой муниципальных районов, выглядит следующим образом:

 <!DOCTYPE html>
 <html>

   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1" />
     <title>Show Data layer on the D3</title>

   <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.3.0/d3.min.js"></script>
   <style>
     #content .map path {
       fill: #aaa;
       stroke: #fff;
     }
   </style>
 </head>

 <body>
   <div id="content">
     <svg width="620px" height="600px">
       <g class="map"></g>
     </svg>
   </div>
   <script>
     // scale - Множитель масштаба проекции
     // center - Центр проекции [долгота, широта]
     // translate - Положение центра проекции в пикселях [x, y]
     let projection = d3
       .geoMercator()
       .scale(10000)
       .translate([200, 280])
       .center([39.5, 44.3]);

     let geoGenerator = d3.geoPath().projection(projection);

     function handleMouseover(e, d) {
       let pixelArea = geoGenerator.area(d); // Площадь в пикселях
       let bounds = geoGenerator.bounds(d); // Границы объекта
       let centroid = geoGenerator.centroid(d); // Центроид объекта
       let measure = geoGenerator.measure(d); // Длина объекта

       d3.select("#content .info").text(
         d.properties.NAME +
           " (path.area = " +
           pixelArea.toFixed(1) +
           " path.measure = " +
           measure.toFixed(1) +
           ")"
       );

       d3.select("#content .bounding-box rect")
         .attr("x", bounds[0][0]) // Координата x левого верхнего угла
         .attr("y", bounds[0][1]) // Координата y левого верхнего угла
         .attr("width", bounds[1][0] - bounds[0][0]) // Ширина
         .attr("height", bounds[1][1] - bounds[0][1]); // Высота

       d3.select("#content .centroid")
         .style("display", "inline")
         .attr("transform", "translate(" + centroid + ")"); // Позиция центроида
     }

     // Вспомогательная функция для переворота координат, если площадь полигона отрицательная
     function fixCoordinates(coordinates) {
       return coordinates.map(function (ring) {
         if (d3.polygonArea(ring) < 0) {
           return ring.reverse(); // Переворот координат
         }
         return ring;
       });
     }

     function update(features) {
       features.forEach(function (feature) {
         const geometryType = feature.geometry.type; // Тип геометрии
         const coordinates = feature.geometry.coordinates; // Координаты

         if (geometryType === "Polygon") {
           feature.geometry.coordinates = fixCoordinates(coordinates); // Исправление координат полигона
         } else if (geometryType === "MultiPolygon") {
           feature.geometry.coordinates = coordinates.map(fixCoordinates); // Исправление координат мультиполигона
         }
       });

       let u = d3.select("#content g.map").selectAll("path").data(features);

       u.enter()
         .append("path")
         .attr("d", geoGenerator) // Создание пути
         .on("mouseover", handleMouseover); // Добавление события при наведении
     }

     // ЗАПРОС ДАННЫХ
     d3.json(url).then(function (json) {
       update(json.features); // Обновление данных
     });

   </script>
 </body>
</html>

Расширенный пример можно посмотреть здесь.

Результат:

../_images/d3.png