D3.js中为.attr('d')传递函数报错及区域生成器使用咨询
嘿,我来帮你搞定这个D3的路径属性问题!你遇到的错误其实是因为D3处理d属性的方式和其他属性有点不一样,咱们一步步来解决:
错误原因解析
你说给除了d之外的.attr()传箭头函数都没问题,唯独d报错——这是因为当你给d属性直接传一个箭头函数时,D3并没有像处理fill、stroke这些属性那样自动执行它并返回结果,反而把这个函数本身转成了字符串(就是报错里看到的"function area(da…"),而<path>的d属性需要的是合法的路径指令(比如M、L这些),自然就触发错误了。
解决方案
要解决这个问题,你需要在attr('d')的回调函数里主动调用对应的区域生成器,把当前数据传给它,生成正确的路径字符串。结合你提到的需要通过选择索引(或者布尔数组)来区分两组区域,具体可以这么做:
- 先定义好两个不同的区域生成器,分别对应两种渲染方向:
// 从上到下的区域生成器(沿Y轴方向扩展) const areaVertical = d3.area() .x(d => xScale(d.x)) .y0(height) // 底部基准线 .y1(d => yScale(d.y)); // 顶部数据点 // 从左到右的区域生成器(沿X轴方向扩展) const areaHorizontal = d3.area() .y(d => yScale(d.y)) .x0(0) // 左侧基准线 .x1(d => xScale(d.x)); // 右侧数据点
- 绑定数据后,利用
attr('d')的回调函数参数(当前数据d、索引i),结合你的布尔数组选择对应的生成器:
// 假设你有一个布尔数组,对应每个数据组是否使用垂直区域 const useVerticalArea = [true, false, true, false]; // 示例数组,长度和数据组数一致 svg.selectAll('path') .data(yourDataGroups) .join('path') .attr('d', (d, i) => { // 根据索引取布尔值,调用对应生成器并传入当前数据 return useVerticalArea[i] ? areaVertical(d) : areaHorizontal(d); }) // 其他属性正常用箭头函数即可 .attr('fill', (d, i) => `hsl(${i * 60}, 70%, 60%)`) .attr('opacity', 0.7);
这样一来,每个路径元素都会根据索引对应的布尔值,调用正确的区域生成器,返回合法的路径字符串给d属性,就不会报错啦。
如果你不想用索引,而是想基于数据本身的属性来判断(比如每个数据组里有个direction字段),直接把判断条件换成d.direction === 'vertical'这类逻辑就可以,原理完全一致。
内容的提问来源于stack exchange,提问作者dukeluke
相关产品推荐
相关产品推荐

