利用geojson文件或者类似包含对象属性和坐标(只要坐标是在统一参考系下)的文件利用SVG绘图无非是以下思路:
1、准备源数据和DOM
2、根据源数据和节点尺寸计算比例尺
3、根据比例尺重新将源坐标数据格式化到DOM对应位置
4、利用SVG绘制点(Point)、线(Poluline)、面(Polygon)等元素
工具的使用熟悉即可。这里谈一下比例尺的计算,简单思路,获取原始坐标的范围(Extent),Extent包含Xmin,Ymin,Xmax,Ymax四个坐标,再将之于DOM的范围即[[0,0],[0,height],[width,height],[width,0]]做等比换算。
而上述内容,当我们认识到D3后便知道不再需要考虑这么多细节,甚至比例尺只需要d3.scale.linear()
就基本足以解决了。
话不多说,开撸。
先确保你已经正确安装配置了nodejs,然后随便找到你准备新建项目的文件夹,开打命令行执行以下命令:
npm init -y
npm install d3@3.5.17 --save
npm install d3-geo --save
npm install lite-server -g
安装完毕后在该文件夹下新建index.html和app.js,并添加相应的引用:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>d3 with geoJsontitle>
head>
<body>
<script src="node_modules/d3//d3.min.js"> script>
<script src="node_modules/d3-geo/dist/d3-geo.min.js">script>
<script src="node_modules/d3-array/dist/d3-array.min.js">script>
<script src="app.js">script>
<style>
.main {
height: 800px;
width: 100%;
}
style>
<div id="tips" style="bottom:100px;left: 0;position:absolute;height: 100px;width:100px">
div>
<svg id='map' class="main">
svg>
<hr>
<div id='log'>
div>
body>
html>
app.js就先空着,一会再说。
新建文件夹assets,在assets下再新建文件夹geoJson,然后去下载需要的geojson文件放在这里。你的项目结构现在看来至少是这样的:
项目准备就先这样,继续往下。
这里直接用原生Http方式请求数据:
const Http = new XMLHttpRequest();
var url = './assets/geoJson/china.json';
//获取Geojson文件,避免回调嵌套换行太多,这里直接返回一个promise
function getGeoData() {
return new Promise(function (resolve, reject) {
Http.open("get", url);
Http.send();
Http.onreadystatechange = function () {
if (Http.readyState == 4 && Http.status == 200) {
resolve(JSON.parse(Http.responseText))
}
}
})
}
关于Http和Promise的知识可以直接点击它们跳转,此处不再赘述。
定义一个绘图方法,接收传入的参数并将所有元素在目标DOM节点上绘制。
var containerWidth = 0;
var containerHeight = 0;
function draw(nodes) {
//墨卡托坐标系
let projection = d3.geoMercator()
//坐标映射
projection.fitExtent([
[0, 0],
[containerWidth, containerHeight]
], nodes);
let path = d3.geoPath(projection);
//绘图
let polygonNode = svg.selectAll("path")
.data(nodes.features)
.enter()
.append("path")
.attr("d", path)
}
回到packge.json所在文件夹,输入
lite-serve
浏览器自动打开后,这个时候你应该看到下图所示的东西:
这个看起来确实是难看了点,我们再直接用链式语法给元素定义各类属性和样式:
//链式语法定义属性和样式
var polygonNode = svg.selectAll("path")
.data(nodes.features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "grey")
.attr('opacity', 0.5)
.attr('stroke', 'yellow')
.attr('stroke-width', function (d) {
return 1
})
当然,除了上面这些,你还可以给各元素添加事件。
完整代码和其他内容请移步我的GITHUB。
简单说一下上述内容用到的东西。
1、npm新建项目
2、http请求数据(JSON)
3、d3选择器
4、d3.geo
5、其他
以上内容不过前端冰山一角,甚至对于d3.js而言也不过万中其一,且行且学。
千里之行,始于足下。