用 d3.js 做一个地图迁徙图
这次使用的是 Vue + d3v5。
html
<div ref="test-svg"></div>
js
import * as d3 from "d3";
import geoJson from "~/assets/map.json";
export default {
name: "d3map",
mounted() {
const width = 1000,
height = 800;
/*
* 创建一个地理投影
* .center 设置投影中心位置
* .scale 设置缩放系数
*
*/
const projection = d3.geoMercator().center([116.3, 35.07]).scale(40000);
// 创建GEO路径生成器path
const path = d3.geoPath().projection(projection);
// 经纬度转投影坐标
const coo = (coordinates) => {
// 转为映射在地图上的坐标
return projection(coordinates);
};
// 设置颜色值
const ss2 = d3.schemeSet2;
const sp2 = d3.schemePastel2;
// 获取GeoJSON数据
const features = geoJson.features;
// 创建d3画布
const svg = d3
.select(this.$refs["test-svg"])
.append("svg")
.attr("width", width + "px")
.attr("height", height + "px");
/*
* 渲染地图
* mouseover 鼠标移入变色
*/
const map = svg
.append("g") // 创建容器
.attr("class", "map"); // 给容器class="map"
map
.selectAll("path") // 获取容器下的path
.data(features) // 载入geo数据
.join("path")
.attr("fill", function (d, i) {
return ss2[i % 3];
})
.attr("d", path)
.on("mouseover", function (d, i) {
d3.select(this).attr("fill", sp2[i % 3]);
})
.on("mouseout", function (d, i) {
d3.select(this).attr("fill", ss2[i % 3]);
});
/**
rotate:auto自动旋转方向
dur:路径运行完成时间
repeatCount:重复次数
*/
map
.append("circle")
.attr("r", 5)
.attr("fill", "red")
.attr("cx", function (d) {
return coo([116.3, 35.07])[0];
})
.attr("cy", function (d) {
return coo([116.3, 35.07])[1];
});
map
.append("circle")
.attr("r", 5)
.attr("fill", "red")
.attr("cx", function (d) {
return coo([116.65, 35.0])[0];
})
.attr("cy", function (d) {
return coo([116.65, 35.0])[1];
});
const lineGenerator = d3
.line()
.x(function (d) {
return d[0];
})
.y(function (d) {
return d[1];
});
const lineData = [
coo([116.3, 35.07]),
coo([116.3 + (116.65 - 116.3) / 2, 35.07 + (35.07 - 35.0) / 2]),
coo([116.65, 35.0]),
];
map
.append("path")
.attr("d", lineGenerator.curve(d3.curveBasis)(lineData))
.attr("stroke", "red")
.attr("fill", "none")
.attr("stroke-width", "2");
svg
.append("circle") //插入图片
.attr("id", "img")
.attr("r", 5)
.attr("fill", "blue")
.append("animateMotion")
.attr("dur", "3s")
.attr("repeatCount", "indefinite")
.attr("rotate", "auto")
.attr("path", lineGenerator.curve(d3.curveBasis)(lineData));
},
};