使用d3开发时直接在attr中写d3.line不生效,如何正确传递函数参数?
D3.js 内联线生成器不生效问题解答
不生效的核心原因
- 匿名函数无返回值:传给
attr("d", ...)的匿名函数没有写return语句,相当于给d属性赋值为undefined,自然无法渲染路径。 - 线生成器访问器参数使用错误:
d3.line()的x、y配置项接收的访问器函数,默认会被依次传入数据集中的每一项作为第一个参数,原代码写的nodes.data().x是尝试直接从整个数据集数组上取x属性,该属性不存在,返回undefined。 - 未调用线生成器生成路径字符串:
d3.line()是工厂函数,执行后返回的是线生成器函数,需要将数据集传入该生成器执行,才能得到d属性需要的SVG路径字符串,原代码只创建了生成器,没有执行传参。
正确修改方案
不需要额外包裹匿名函数,直接创建线生成器后立即传入数据调用即可:
var path = d3.select("#frame") .append("path") .attr("class", "line") .attr("d", d3.line() .x(function(d) { return d.x; }) .y(function(d) { return d.y; }) (nodes.data()) );
如果确实需要包裹在自定义函数中,记得补充return语句:
var path = d3.select("#frame") .append("path") .attr("class", "line") .attr("d", function() { // 必须返回生成的路径字符串 return d3.line() .x(function(d) { return d.x; }) .y(function(d) { return d.y; }) (nodes.data()); });
D3开发中函数作为参数传递的规范
- d3内置方法(如attr、style、事件绑定的on方法等)接收函数作为参数时,函数必须返回对应属性需要的类型值,例如attr的d属性需要字符串,传入的回调就必须返回字符串,不能省略return。
- 正确使用d3注入的回调参数:d3调用你传入的回调函数时,会自动按顺序注入「当前绑定的数据项d、索引i、当前元素集合」三个参数,直接使用d取当前项的属性即可,不需要硬编码全局数据集取值。
- 区分工厂函数和执行结果:d3中
d3.line、d3.arc这类属于生成器工厂函数,调用后返回的是可复用的生成器函数,需要再传入数据调用生成器,才能得到最终渲染需要的字符串/数值,不要漏掉第二步调用。 - 传递函数引用不要加括号:如果是把已经定义好的函数作为回调传递(比如事件处理函数),直接传函数名即可,不要加括号,加括号会立即执行函数,把返回值而非函数本身传进去。
内容的提问来源于stack exchange,提问作者Glen
相关产品推荐
相关产品推荐

