You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

D3.js如何在遍历GeoJSON时为每个要素单独设置投影?

为GeoJSON每个要素单独设置投影实现等尺寸显示

完全可以实现,核心思路是为每个GeoJSON Feature单独创建投影,并将每个要素放在独立的容器中布局,确保每个要素都被缩放到统一尺寸。

你原来的代码用了全局投影适配所有要素,现在需要调整为针对单个要素生成投影,以下是修改后的实现:

// 单个要素的尺寸和布局间距
const featureWidth = 200,
      featureHeight = 200,
      padding = 20,
      columns = 2; // 每行显示2个要素,可按需调整

const svg = d3.select('#content g.map')
              .append("svg")
              // 计算整个SVG的宽高,根据列数和要素数量调整
              .attr("width", columns * (featureWidth + padding) + padding)
              .attr("height", Math.ceil(geojson.features.length / columns) * (featureHeight + padding) + padding);

// 遍历每个要素,单独处理投影和路径
svg.selectAll('g.feature-group')
   .data(geojson.features)
   .enter()
   .append('g')
   .attr('class', 'feature-group')
   // 定位每个要素容器的位置,按行列排列
   .attr('transform', (d, i) => {
     const x = padding + (i % columns) * (featureWidth + padding);
     const y = padding + Math.floor(i / columns) * (featureHeight + padding);
     return `translate(${x}, ${y})`;
   })
   .each(function(d) {
     // 为当前要素创建专属投影
     const projection = d3.geoAlbers()
                          .fitExtent(
                            [[0, 0], [featureWidth, featureHeight]],
                            d // 传入单个要素,而非所有features
                          );
     // 使用该投影生成路径
     const geoGenerator = d3.geoPath().projection(projection);
     
     // 在当前要素容器中添加路径
     d3.select(this)
       .append('path')
       .attr('d', geoGenerator(d))
       .attr('stroke-width', '3')
       .attr('stroke', 'black')
       .attr('fill', 'none');
   });

关键说明:

  • 每个要素都有独立的projection实例,通过fitExtent将单个要素适配到[featureWidth, featureHeight]的固定尺寸,确保所有要素显示大小一致。
  • 用<g>元素作为每个要素的容器,通过transform: translate()控制位置,避免要素重叠,实现规整布局。
  • 使用.each()方法遍历每个要素容器,在内部创建投影和路径,保证每个要素的投影相互独立。

内容的提问来源于stack exchange,提问作者Luk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 11:45:37