使用D3.js渲染越南地图时地图显示过小的问题求助
解决D3.js绘制越南地图显示过小的问题
核心问题分析
你的代码存在两个关键问题导致地图显示过小:
- 投影未适配地理数据范围:默认的
d3.geoMercator()没有根据越南的地理边界进行缩放和平移,地图以默认全球视角渲染,自然显得极小。 - 路径生成错误:绘制省份路径时,你传入了整个
provinces集合给path(),而非让D3为每个feature单独生成路径。
修正后的代码
const urlGEOJSON = 'https://data.opendevelopmentmekong.net/geoserver/ODMekong/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ODMekong%3Aa4eb41a4-d806-4d20-b8aa-4835055a94c8&outputFormat=application%2Fjson'; const width = 800; const height = 800; d3.select('.container') .append('h1') .text('Viet Nam Map'); const svg = d3.select('.container') .append('svg') .attr('width', width) .attr('height', height) .attr('id', 'map') .attr('viewBox', [0, 0, width, height]); // 修正viewBox避免拉伸 fetch(urlGEOJSON) .then(res => res.json()) .then(data => { // Convert GeoJSON data into TopoJSON const topo = topojson.topology({vietnam : data}, 1000); // Convert TopoJSON back to GeoJSON for using D3.geoPath() const provinces = topojson.feature(topo, topo.objects.vietnam); const country = topojson.mesh(topo, topo.objects.vietnam, (a,b)=> a === b); // 关键:根据地理数据范围调整投影 const projection = d3.geoMercator() .fitSize([width - 40, height - 40], provinces) // 留40px边距,避免地图贴边 .precision(0.1); const path = d3.geoPath().projection(projection); svg.append('g') .selectAll('path') .data(provinces.features) .enter() .append('path') .attr('d', path) // 让D3自动为每个feature生成路径 .attr('fill', 'white') .attr('stroke', '#ccc'); // 增加省份边界线提升可读性 svg.append('path') .datum(country) .attr('fill', 'none') .attr('stroke', 'black') .attr('stroke-width', 1.5) .attr('d', path) }) .catch(err => console.log(err))
关键修改点说明
- 投影适配:使用
fitSize()方法,传入SVG可用尺寸(减去边距)和地理数据集合,让D3自动计算合适的缩放比例和平移量,确保地图填满SVG容器。 - 路径生成修正:将
attr('d', path(provinces))改为attr('d', path),D3会为每个绑定的feature调用path函数生成对应路径。 - 细节优化:修正viewBox参数避免地图拉伸,增加省份边界线、加粗国家边界,提升地图视觉清晰度。
内容的提问来源于stack exchange,提问作者C4n Ng0
相关产品推荐
相关产品推荐

