如何使用一个值函数设置多个属性?

eri*_*oco 50 javascript attributes d3.js

给定包含多个数据元素(如对象或数组)的数据,是否可以使用单个值函数在选择上设置多个属性?

例如:

var data = [{ 'x': 10, 'y': 20, 'r': 5 }];
d3.select('body').append('svg').selectAll('circle')
    .data(data)
    .enter().append('circle')
    .attr('cx cy r', function (d) {
        return [d.x, d.y, d.r];
    });
Run Code Online (Sandbox Code Playgroud)

代替:

var data = [{ 'x': 10, 'y': 20, 'r': 5 }];
d3.select('body').append('svg').selectAll('circle')
    .data(data)
    .enter().append('circle')
    .attr('cx', function (d) {
        return d.x;
    });
    .attr('cy', function (d) {
        return d.y;
    });
    .attr('r', function (d) {
        return d.r;
    });
Run Code Online (Sandbox Code Playgroud)

mee*_*mit 66

更新(2016年7月8日)此答案适用于d3 v3.x - NOT v4.x. 对于后一版本,请参阅Tim Hayes的回答,也在此页面上.或者只换attrattrs在我的回答如下,不要忘了要求/进口/脚本嵌入d3-selection-multi.并且......不要错过使用的一点.each,这可能对您有用.


是的,通过传入散列(如jQuery的css()方法)可能:

d3.select('body').append('svg').selectAll('circle')
  .data(data)
.enter().append('circle')
  .attr({
    cx: function (d) { return d.x; },
    cy: function (d) { return d.y; },
    r:  function (d) { return d.r; }
  });
Run Code Online (Sandbox Code Playgroud)

这也适用style().

如果再次出现function (d) {}感觉太多,这是另一种方法:

d3.select('body').append('svg').selectAll('circle')
  .data(data)
  .enter().append('circle')
  .each(function (d) {
    d3.select(this).attr({
      cx: d.x,
      cy: d.y,
      r:  d.r
    });
  })
Run Code Online (Sandbox Code Playgroud)

注意:此功能仅存在于d3.js v2.10.0或更高版本中

  • 我问了两个原因:一个是能够编写更简洁的代码,另一个是最小化函数调用.您提供的第一个语法很方便,但第二个语法更接近我正在寻找的 - 每个节点一个函数调用.有没有办法避免在d3选择器中包装`this`并仍然设置属性?(我想我可以使用原生的JS,但是这种转向危险地接近于牺牲性能的易读性.) (4认同)
  • @ericsoco re:减少函数调用.`.attrs`的`d3-selection-multi`docs将它描述为"在selection.attr之上设置多个属性的便捷方法."`查看[源代码](https://github.com /d3/d3-selection-multi/blob/master/src/selection/attrs.js)确认它只是在循环中调用`.attr`. (2认同)

Tim*_*yes 66

这是一个老帖子,但我在谷歌搜索时找到答案.接受的答案在D3 v4.0中不再有效.

继续前进,您可以使用该attrs()方法执行相同的操作.但attrs()只有在加载可选的d3-selection-multi脚本时才支持.

所以使用上面的例子,它在D3 v4.0中看起来像这样:

// load d3-selection-multi as separate script
<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>

d3.select('body').append('svg').selectAll('circle')
  .data(data)
  .enter().append('circle')
  .attrs({
    cx: function (d) { return d.x; },
    cy: function (d) { return d.y; },
    r:  function (d) { return d.r; }
  });
Run Code Online (Sandbox Code Playgroud)

  • 请参阅[4.0发行说明]的最后一段(https://github.com/d3/d3/blob/master/CHANGES.md#selections-d3-selection):`...多值方法 - 其中您传递一个对象以同时设置多个属性,样式或属性 - 已被提取到d3-selection-multi并且不再是默认包的一部分.多值映射方法也已重命名为复数形式以减少重载...``d3-selection-multi`注释状态:`建议大多数用户使用单值方法,例如selection.attr,因为那里对于较短的语法没什么好处......` (4认同)
  • 如果您可以通过版本接受答案,那会很好吗,对吗?谢谢你补充一下. (3认同)
  • 不错的参考@brichins-“ ...几乎没有好处...”是如此主观。一个巨大的好处是能够将属性视为一个对象并将其传递给D3版本3中的多个“ attr”调用-奇怪的是,他们对此持强烈立场。 (3认同)