最近公司在香港有新项目,于是便要求大屏上显示香港地图;
最终实现如图:
一开始使用的echarts来渲染香港地图,效果如下:
但是这份JSON数据实现的香港地图和实际地图有出入,且使用echarts实现地图宽度会被压缩,所以经理就在群里说了这个问题,要求换一个更详细的地图;于是我找了百度了很久,最终使用D3.js来绘制该香港地图;代码如下:
<template>
<div id="chart-container_hk">
<svg id="chart_hkhk"></svg>
</div>
</template>
<script>
import * as d3 from "d3";
import hongKongData from "../config/hongKong.json";
import coastlineData from "../config/coastlineData.json";
import api from "../api/fast/index";
export default {
data() {
return {
params: {
areaCode: "810000",
areaLevel: "province",
areaName: "香港",
name: "香港",
},
list: [],
};
},
async mounted() {
const aid = sessionStorage.getItem("aid");
api
.getProjectAndDeviceNumByCity({
agentId: aid,
province: this.params.name,
})
.then(({ result: res }) => {
this.list = res;
console.log(34, this.list);
this.$nextTick(() => {
let that = this;
const width = 813; // 设置地图的宽度
const height = 549; // 设置地图的高度
const svg = d3
.select("#chart_hkhk")
.attr("width", width)
.attr("height", height)
.attr("viewBox", `-100 -0 ${width} ${height}`)
.style("display", "block")
.style("margin", `auto`);
const projection = d3
.geoIdentity()
.fitSize([600, height], hongKongData);
const path = d3.geoPath().projection(projection);
// 区模块背景颜色和高亮效果
svg
.selectAll("path")
.data(hongKongData.features)
.enter()
.append("path")
.attr("d", path)
.style("fill", (d, i) =>
d.properties.adcode == 810017 ? "#8f6e09" : "#dea913"
) // 修改背景颜色
.style("stroke", "#fff")
.style("stroke-width", "1px")
.on("mouseover", function () {
d3.select(this).classed("highlight", true); // 添加高亮效果
})
.on("mouseout", function () {
d3.select(this).classed("highlight", false); // 移除高亮效果
})
.on("click", function (d) {
console.log(43);
that.$router.push({
name: "amap",
query: {
type: "all",
sType: "all",
point: "114.1393194,22.36387667",
cityName: "葵青区",
areaCode: "810000",
},
});
// window.location.href = `https://data.dafangai.cn/#/amap?type=all&sType=all&point=114.1393194,22.36387667&cityName=葵青区&areaCode=810000`;
});
// 领海边界线
svg
.append("path")
.datum(coastlineData) // 使用海岸线数据
.attr("d", path)
.style("fill", "none")
.style("stroke", "#dea913") // 颜色为#dea913
.style("stroke-dasharray", "3") // 虚线样式
.style("stroke-width", "3px");
// 区名显示和提示框
svg
.selectAll("text")
.data(hongKongData.features)
.enter()
.append("text")
.text((d) => d.properties.name) // 区名
.attr("x", (d) => path.centroid(d)[0]) // 设置文本位置为区块的质心
.attr("y", (d) => -path.centroid(d)[1] + 549) // 将y坐标取负值
.attr("text-anchor", "middle")
.style("font-size", "12px")
.style("fill", "#fff")
.attr("transform", "scale(1, -1) translate(0, -" + height + ")");
// 提示框
const tooltip = d3
.select("#chart-container_hk")
.append("div")
.attr("class", "tooltip")
.style("opacity", 0);
svg
.selectAll("path")
.on("mouseover", function (d, i) {
tooltip.transition().duration(200).style("opacity", 0.9);
const cityData = that.list.find(
(item) => item.city === d.target.__data__.properties.name
);
const deviceSum = cityData ? cityData.deviceSum : 0;
const projectSum = cityData ? cityData.projectSum : 0;
tooltip
.html(
"<div>" +
d.target.__data__.properties.name +
"</div>" +
"<div>设备数:" +
deviceSum +
"台" +
"</div>" +
"<div>项目数:" +
projectSum +
"个" +
"</div>"
)
.style("left", d.pageX / 2 + "px")
.style("top", 549 - d.pageY + "px")
.style("transform", "scaleY(-1)");
})
.on("mouseout", function () {
tooltip.transition().duration(500).style("opacity", 0);
});
setInterval(() => {
// 触发mouseover事件
svg
.selectAll("path")
.filter((d) => d.properties && d.properties.adcode === 810017) // 添加判断条件,过滤空对象
.dispatch("mouseover");
}, 2000);
});
});
},
};
</script>
<style lang="scss">
#chart-container_hk {
height: 549px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
transform: scaleY(-1);
}
#chart-hkhk svg {
transform: scaleY(-1);
}
#chart-container_hk .tooltip {
background-color: rgba(0, 0, 0, 0.8);
color: #fff;
font-size: 12px;
padding: 5px;
position: absolute;
pointer-events: none;
}
#chart-container_hk .highlight {
fill: #ffd700; // 设置高亮的背景颜色
stroke-width: 2px;
stroke: #fff;
}
</style>
D3.js官网:https://www.d3js.org.cn/
JSON数据来源:DataV.GeoAtlas地理小工具系列
JSON数据地址:hongKongJSON: 香港地图详细JSON数据
D3.js还有很多我没弄明白的地方,这次也是第一次使用,比如他渲染出来地图是上下翻转的,但文字又是正常的....希望能一起讨论学习