【D3.js - v5.x】(7)繪製地圖 | Geo佈局 | 完整代碼

地圖

在數據可視化中,地圖是很重要的一部分。很多情況會與地圖有關聯,如中國各省的人口多少,GDP多少等,都可以和地圖聯繫在一起。

地圖數據的獲取

製作地圖需要 JSON 文件,將 JSON 的格式應用於地理上的文件,叫做 GeoJSON 文件。本文就是用這種文件繪製地圖。

那麼如何獲取中國地圖的 GeoJSON 文件呢? 如下鏈接,打開並下載至本地,並命名爲ChinaGeoFull.json,後面實現會用到。

https://geo.datav.aliyun.com/areas_v2/bound/100000_full.json

投影函數

由於 GeoJSON 文件中的地圖數據,都是經度和緯度的信息。它們都是三維的,而要在網頁上顯示的是二維的,所以要設定一個投影函數來轉換經度緯度。如:

var projection = d3.geoMercator()
      .center([107, 31])
      .scale(850)
      .translate([width/2, height/2]);

文檔: https://www.d3js.org.cn/document/d3-geo/#projections

其中,

  • center() 設定地圖的中心位置,[107,31] 指的是經度和緯度。
  • scale() 設定放大的比例。
  • translate() 設定平移。

地理路徑生成器

爲了根據地圖的地理數據生成 SVG 中 path 元素的路徑值,需要用到d3.geoPath([projection[, context]),稱它爲地理路徑生成器。

文檔:https://www.d3js.org.cn/document/d3-geo/#paths

使用默認的設置創建一個新的地理路徑生成器. 如果指定了 projection, 則設置 當前投影. 如果指定了 context 則設置當前 當前上下文.

var path = d3.geoPath(projection)

向服務器請求文件並繪製地圖

 d3.json("./ChinaGeoFull.json").then(function(data){
        console.log(data)
        svg.selectAll("g")
            .data(data.features)
            .enter()
            .append("g")
            .append("path")
            .attr('d',path)//使用地理路徑生成器
            .attr("stroke","#000")
            .attr("stroke-width",1)
            .attr("fill", function(d,i){
                return color[i%10];
            })
            .on("mouseover",function(d,i){
                d3.select(this).attr("fill","yellow");
            })
            .on("mouseout",function(d,i){
                d3.select(this).attr("fill",color(i));
            });
      //添加座標
      svg.selectAll("g")
         .append('text')
         .attr('font-size', 12)
         .attr('text-anchor', 'middle')
         .attr('x', d => {
          var position = projection(d.properties.centroid || [0, 0]);
          return position[0];
         })
         .attr('y', d => {
          var position = projection(d.properties.centroid || [0, 0]);
          return position[1];
        })
        .attr('dy', d => {
        //澳門和香港重合了,擠到一起了
          if (d.properties.name === '澳門') {
            return 15;
          }
        })
        .text(d => d.properties.name);
          
      })

完整代碼

<body>
    <svg width="1000" height="1000"></svg>
    <script>
      var marge = {top:60,bottom:60,left:60,right:60}
      var svg = d3.select("svg")
      var width = svg.attr("width")
      var height = svg.attr("height")
      var g = svg.append("g").attr("transform","translate("+marge.top+","+marge.left+")");
      //投影函數
      var projection = d3.geoMercator()
      .center([107, 31])
      .scale(800)
      .translate([width/2, height/2]);
      //路徑
      var path = d3.geoPath(projection);
      var color = d3.schemeCategory10;

      d3.json("./ChinaGeoFull.json").then(function(data){
        console.log(data)
        svg.selectAll("g")
            .data(data.features)
            .enter()
            .append("g")
            .append("path")
            .attr('d',path)//使用地理路徑生成器
            .attr("stroke","#000")
            .attr("stroke-width",1)
            .attr("fill", function(d,i){
                return color[i%10];
            })
            .on("mouseover",function(d,i){
                d3.select(this).attr('opacity', 0.5);
            })
            .on("mouseout",function(d,i){
                d3.select(this).attr('opacity', 1);
            });
      //添加座標
      svg.selectAll("g")
         .append('text')
         .attr('font-size', 12)
         .attr('text-anchor', 'middle')
         .attr('x', d => {
          var position = projection(d.properties.centroid || [0, 0]);
          return position[0];
         })
         .attr('y', d => {
          var position = projection(d.properties.centroid || [0, 0]);
          return position[1];
        })
        .attr('dy', d => {
        //這裏爲什麼這麼寫呢,因爲澳門和香港重合了,擠到一起了。
          if (d.properties.name === '澳門') {
            return 15;
          }
        })
        .text(d => d.properties.name);
          
      })
    </script>
</body>

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章