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
相关产品推荐
相关产品推荐

