目录

D3.js绘制中国地图

目录

d3.js 是一个 JavaScript 库,用于根据数据操作文档。d3 可以使用 HTML、SVG 和 CSS 将数据变为现实。d3 对网络标准的强调让你拥有了现代浏览器的全部功能,而不会将自己束缚在专有框架中,将强大的可视化组件和数据驱动的 DOM 操作方法结合在一起。

最近使用 d3 做了一个中国地图,也实现了一些交互,所以记录下来:

1.首先得准备一份中国地图的 json 文件,这里就不提供了,网上可以找到下载链接,也可以参考这个项目

https://github.com/clemsos/d3-china-map

2.这里就不对 d3 的具体 api 进行介绍了,直接上源码

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<style type="text/css">
  body {
    background: #fdfdfd;
  }
  path {
    stroke-width: 1px;
  }
  .subProvince {
    fill: #fff;
    transform: translate(0, 5px);
  }
  .choose-city {
    fill: #ee9b8a !important;
    stroke: #df9269 !important;
  }
  .thirdProvince {
    fill: #e6f3f3;
    transform: translate(0, 10px);
  }
  .cityExist {
    fill: #daf6f6;
    stroke: #bceaea;
  }
  .cityNoExist {
    fill: #afd8f6;
    stroke: #8ec7e2;
  }
  text {
    font-size: 14px;
    font-weight: 700;
    fill: #56abab;
  }
  .cityExist + text,
  .cityNoExist + text {
    fill: #56abab;
  }
  .choose-city + text {
    fill: #fff;
  }
  .whiteFont {
    fill: #fff !important;
  }
  circle {
    fill: steelblue;
    fill-opacity: 0.8;
    stroke: #fff;
  }
</style>

// svg元素
<svg width="960" height="960"></svg>

<script>
  "use strict";
  const d3 = window.d3;

  const mapData = window.map; // 地图数据

  // 选择SVG对象
  const $svg = d3.select("svg");

  // 地图阴影效果
  const $thirdProvince = $svg.append("svg:g").attr("id", "thirdProvince");
  // 地图阴影效果
  const $subProvince = $svg.append("svg:g").attr("id", "subProvince");

  const $province = $svg.append("svg:g").attr("id", "province");

  const width = $svg.attr("width");
  const height = $svg.attr("height");
  // 生成投影函数
  const projection = d3
    .geoMercator() // 设定经纬度3D转2D算法
    .center([103, 30]) // 设置经纬度中心点
    .scale(850) // 设定标尺
    .translate([width / 2, height / 2]); // 设定转换宽高
  const path = d3.geoPath(projection); // 设置路径转换函数
  // 选中省路径并插入路径数据

  $subProvince
    .append("path")
    .datum(mapData)
    .attr("d", path)
    .attr("class", "subProvince");

  $thirdProvince
    .append("path")
    .datum(mapData)
    .attr("d", path)
    .attr("class", "thirdProvince");

  const $provinceGraph = $province
    .selectAll("path")
    .data(mapData.features) // 绑定数据
    .enter() // 获取所有数据
    .append("g");
  $provinceGraph
    .append("path") // 插入路径
    .attr("d", path) // 使用地理位置生成器
    .attr("data-exist", function (d) {
      // 插入属性
      return d.properties.exist ? "true" : "";
    })
    .attr("class", function (d) {
      // 插入属性
      return d.properties.exist
        ? "cityExist common-city-class city" + d.properties.id
        : "cityNoExist common-city-class city" + d.properties.id;
    });

  $provinceGraph
    .append("text")
    .attr("transform", function (d) {
      return "translate(" + projection(d.properties.cp) + ")";
    })
    .attr("dy", ".35em")
    .attr("dx", "-1em")
    .text(function (d) {
      // 插入名称
      return d.properties.name;
    });

  $(".common-city-class").mouseenter(function () {
    $(".common-city-class").removeClass("choose-city");
    $(this).addClass("choose-city");
  });
</script>

4.以上代码可以直接使用,只需要引入 d3 .js 以及中国地图的 json 文件,需要特别注意的是,svg 对象中设置某个元素的样式与 css 不太相同,比如设置区块填充颜色使用的是fill,其他的可以根据具体的数据设置不同的地图属性,如

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$provinceGraph
  .append("path") // 插入路径
  .attr("d", path) // 使用地理位置生成器
  .attr("data-exist", function (d) {
    // 插入属性
    return d.properties.exist ? "true" : "";
  })
  .attr("class", function (d) {
    // 插入属性
    return d.properties.exist
      ? "cityExist common-city-class city" + d.properties.id
      : "cityNoExist common-city-class city" + d.properties.id;
  });

这里

1
return d.properties.exist ? 'cityExist common-city-class city' + d.properties.id : 'cityNoExist common-city-class city' + d.properties.id

指的是如果属性中有exist属性这返回前者,反之返回后者,这样就方便我们一些实际的项目开发需求,另外最好使用原生 js 操作 svg 对象。

关于 d3 的文档可以参考官网