实现一个简单的geoMap。
依赖库:d3js v4 canvas渲染
1. 最简单的实现:
var width = 1300,
height = 800;
//定义一个地图映射
var projection = d3.geoMercator()
.center([100, 37])
.scale(850)
.translate([width/2, height/2]);
//在页面中插入一个canvas元素,并设置宽高
var canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height);
//获得canvas绘图上下文
var context = canvas.node().getContext("2d");
//定义一个路径生成器
var mapPath = d3.geoPath()
.projection(projection)
.context(context);
//加在数据开始渲染地图
d3.json("data/china.topojson", function(error, us) {
if (error) throw error;
//一次性绘制整个地图轮廓
mapPath(topojson.feature(us, us.objects.collection));
context.stroke();
});
这时候在浏览器中可以看到渲染的中国地图(可惜没有包含中国领海,尤其是钓鱼岛)
github
2.更实用的功能是,每个省份填充不同颜色,这样要对每个省份的多边形分别绘制:github
d3.json("data/china.topojson", function(error, us) {
if (error) throw error;
var countries = topojson.feature(us, us.objects.collection);
countries.features.forEach(drawMapPath);
});
function drawMapPath(d) {
context.beginPath();
var color = mapColor(parseInt(d.properties.id) );
context.fillStyle= color;
context.strokeStyle=color;
context.globalAlpha=0.3;
mapPath(d);
context.stroke();
context.fill();
}
得到每个省份的地理路路径,然后对每个路径独立绘制,效果如下:
3.现在绘制的是静态的地图,加入移动缩放功能:github
//给地图添加缩放范围和监听事件
canvas
.call(d3.zoom().scaleExtent([1, 36]).on("zoom", zoomed));
//当地图缩放后,获得缩放变换,重新渲染地图
function zoomed() {
transform = d3.event.transform;
render();
}
//在渲染程序中,对绘图上下文整体应用变换
function render() {
context.save();
context.clearRect(0, 0, width, height);
context.beginPath();
context.translate(transform.x, transform.y);
context.scale(transform.k, transform.k);
context.lineWidth=0.1;
context.globalAlpha=0.3;
countries.features.forEach(drawMapPath);
context.stroke();
context.fill();
context.restore();
}
4.然后添加省份标注 github
在绘制的时候,怎加绘制省份名称
//绘制地图省份
function drawMapText(d) {
context.beginPath();
context.fillStyle='black';
context.fillText(
d.properties.name,
projection(d.properties.cp)[0],projection(d.properties.cp)[1]
);
}
效果如下: