Svelte结合D3渲染TopoJson地图无显示且控制台无报错问题求助
问题排查结论
页面空白无报错的核心原因是投影配置错误:
- 代码中设置
geoPath().projection(null)代表直接使用要素自带坐标生成路径,不做坐标转换,但加载的法国TopoJSON数据是WGS84经纬度格式,坐标值范围在经度-510、纬度4151区间,完全落在设置的0 0 910 610的SVG可视区域外,因此没有可见内容,也不会抛出语法/请求类错误。
通用排查步骤
- 先校验数据链路:查看控制台打印的TopoJSON数据、转换后的GeoJSON features数组是否存在内容,排除fetch失败、TopoJSON解析错误的问题
- 再检查DOM输出:打开元素面板查看生成的
<path>标签的d属性,如果属性值是经纬度数值而非0910/0610区间的像素值,即可确认是投影配置问题 - 最后校验投影适配:确认投影的缩放、中心、平移参数是否能将地理范围完整映射到SVG的viewBox区间内
修复后可运行代码
<script> import { geoAlbers, geoPath } from "d3-geo"; import { onMount } from "svelte"; import * as topojson from 'topojson-client'; let deps = []; let pathGenerator; let mesh; onMount(async () => { const france = await fetch('https://gist.githubusercontent.com/Fralacticus/b6584c5865607300b2b5a0559ae47cbb/raw/8287c28f9a3eab4e3d1aa5f7e6181f064957c9de/deptopo.json' ).then(d => d.json()); const geoFeatures = topojson.feature(france, france.objects.dep); deps = geoFeatures.features; mesh = topojson.mesh(france, france.objects.dep, (a, b) => a !== b); // 初始化Albers投影,自动适配SVG视口尺寸 const projection = geoAlbers(); projection.fitSize([910, 610], geoFeatures); pathGenerator = geoPath().projection(projection); }); </script> <svg viewBox="0 0 910 610"> <g fill="white" stroke="black"> {#each deps as feature, i} <path d={pathGenerator ? pathGenerator(feature) : ''} /> {/each} </g> </svg>
修复说明
- 删除了原代码中未使用的
geoAlbersUsa、svelte/transition的draw导入,减少无效依赖 - 加载完地理数据后,使用
projection.fitSize()自动计算投影的缩放、平移参数,将法国地图完整适配到910*610的SVG画布中 - 增加了
pathGenerator的存在判断,避免初始化阶段函数未赋值时调用报错

内容的提问来源于stack exchange,提问作者Gaiusfr
相关产品推荐
相关产品推荐

