How to set multiple attributes with one value function?

Javascriptd3.jsAttributes

Javascript Problem Overview


Given a datum containing multiple data elements, such as an object or array, is it possible to set multiple attributes on a selection with a single value function?

E.g. something like:

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];
    });

instead of:

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;
    });

Javascript Solutions


Solution 1 - Javascript

UPDATE (July 8th 2016) This answer applies to d3 v3.x — NOT v4.x. For the latter version, see Tim Hayes's answer, also on this page. Or... just swap attr with attrs in my answer below, and don't forget to require/import/script-embed d3-selection-multi. And... don't miss the bit about using .each, which may be useful to you.


Yeah, it's possible by passing in a hash (like jQuery's css() method):

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; }
  });

This works for style() as well.

If the reoccurring function (d) {} start to feel like too much, this is another approach:

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
    });
  })

NOTE: this feature only exists in d3.js v2.10.0 or higher

Solution 2 - Javascript

This is an old post, but I found it while Googling around for an answer. The accepted answer no longer works in D3 v4.0.

Moving forward, you can do the same by using the attrs() method. But attrs() is only supported if you load the optional d3-selection-multi script.

So using the example above, it would look like this in 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; }
  });

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionericsocoView Question on Stackoverflow
Solution 1 - JavascriptmeetamitView Answer on Stackoverflow
Solution 2 - JavascriptTimHayesView Answer on Stackoverflow