D3.js交互3D地球旋转时标注点消失报cx属性NaN错误求助
问题原因排查及修复方案
核心错误点
- 字段名不匹配
你加载城市csv数据时,使用d.lon、d.lat读取经纬度坐标,但是在zoomed旋转更新点位的逻辑里,错误调用了不存在的d.x、d.y字段,导致经纬度读取失败,投影计算返回无效值。 - 未处理背面投影返回null的情况
d3正射投影geoOrthographic对于旋转到地球背面的点,会直接返回null而非坐标数组,你直接取projectedPoint[0]就会得到NaN,触发控制台报错,也会导致点位属性设置失败直接消失。
你原本手写的可见性判断逻辑冗余且依赖错误字段,完全可以直接用投影返回值判断点位是否可见,不需要额外做角度计算。
修复代码
替换zoomed函数里城市点位更新的逻辑即可:
d3.selectAll("circle.cities").each(function (d, i) { // 修正为读取正确的经纬度字段 var projectedPoint = projection([d.lon, d.lat]) // 投影返回null代表点位在地球背面,直接隐藏 if (!projectedPoint) { d3.select(this).style("display", "none") return } // 点位在可见面时更新坐标并显示 d3.select(this) .attr("cx", projectedPoint[0]) .attr("cy", projectedPoint[1]) .style("display", "block") })
可选优化
如果要避免后续重复处理数据类型,可以在加载csv时提前把经纬度转成数值:
d3.csv("cities.csv").then(function(data) { // 提前转换经纬度为数值格式,避免后续重复转换 const processedData = data.map(d => ({ ...d, lon: +d.lon, lat: +d.lat })) svg.selectAll("circle").data(processedData) .enter() .append("circle") .attr("class", "cities") .attr("r", 3) .attr("cx", d => projection([d.lon,d.lat])[0]) .attr("cy", d => projection([d.lon,d.lat])[1]) })
内容的提问来源于stack exchange,提问作者Kylee
相关产品推荐
相关产品推荐

