title: Combining Parent and Nested Data with d3.js
body: <p>I have a data structure like this (<strong>assume that the data structure is non-negotiable</strong>):</p>
  
  <pre><code>data = {
      segments : [
          {x : 20, size : 10, colors : ['#ff0000','#00ff00']},
          {x : 40, size : 20, colors : ['#0000ff','#000000']}
      ]};
  </code></pre>
  
  <p>Using the <a href="https://github.com/mbostock/d3/wiki" rel="nofollow noreferrer">d3.js</a> javascript library, I'd like to draw four rectangles, one for each color in both <code>colors</code> arrays.  Information from each entry in the <code>segments</code> array is used to draw the rectangles corresponding to each color in its <code>color</code> array.  E.g., The red and green rectangles will have a width and height of 10.  The resulting html should look like this: </p>
  
  <pre><code>&lt;div id="container"&gt;
      &lt;svg width="200" height="200"&gt;
          &lt;g&gt;
              &lt;rect x="20" y="20" width="10" height="10" fill="#ff0000"&gt;&lt;/rect&gt;
              &lt;rect x="30" y="30" width="10" height="10" fill="#00ff00"&gt;&lt;/rect&gt;
          &lt;/g&gt;
          &lt;g&gt;
              &lt;rect x="40" y="40" width="20" height="20" fill="#0000ff"&gt;&lt;/rect&gt;
              &lt;rect x="60" y="60" width="20" height="20" fill="#000000"&gt;&lt;/rect&gt;
          &lt;/g&gt;
      &lt;/svg&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>I've come up with some code that accomplishes this, but I found the part about using data from two different levels of nesting in <code>data</code> to be confusing, and I feel that there might be a more idiomatic way to accomplish the same with d3.js.  Here's the code (full example at <a href="http://jsbin.com/welcome/39650/edit" rel="nofollow noreferrer">http://jsbin.com/welcome/39650/edit</a>):</p>
  
  <pre><code>function pos(d,i) { return d.x + (i * d.size); } // rect position
  function size(d,i) { return d.size; }            // rect size
  function f(d,i) { return d.color; }              // rect color
  
  // add the top-level svg element and size it
  vis = d3
      .select('#container')
      .append('svg')
      .attr('width',200)
      .attr('height',200);
  
  // add the nested svg elements
  var nested = vis
      .selectAll('g')
      .data(data.segments)
      .enter()
      .append('g');
  
  // Add a rectangle for each color
  nested
      .selectAll('rect')
      .data(function(d) {
          // **** ATTENTION ****
          // Is there a more idiomatic, d3-ish way to approach this?
          var expanded = [];
          for(var i = 0; i &lt; d.colors.length; i++) {
              expanded.push({
                  color : d.colors[i],
                  x     : d.x
                  size  : d.size });
          }
          return expanded;
      })
      .enter()
      .append('rect')
      .attr('x',pos)
      .attr('y',pos)
      .attr('width',size)
      .attr('height',size)
      .attr('fill',f);
  </code></pre>
  
  <p><strong>Is there a better and/or more idiomatic way to access data from two different levels of nesting in a data structure using d3.js?</strong></p>
  
  <h1>Edit</h1>
  
  <p>Here's the solution I came up with, thanks to <a href="https://stackoverflow.com/a/13116665/1015178">meetamit's answer</a> for the closure idea, and using more idiomatic d3.js indentation thanks to <a href="https://stackoverflow.com/a/13145734/1015178">nautat's answer</a>:</p>
  
  <pre><code>$(function() {
    var
      vis = null,
      width = 200,
      height = 200,
      data = {
          segments : [
             {x : 20, y : 0, size : 10, colors : ['#ff0000','#00ff00']},
             {x : 40, y : 0, size : 20, colors : ['#0000ff','#000000']}
          ]
      };
  
      // set the color
      function f(d,i) {return d;}
  
      // set the position
      function pos(segment) {
        return function(d,i) {
          return segment.x + (i * segment.size);
        };
      }
  
      // set the size
      function size(segment) {
        return function() {
          return segment.size;
        };
      }
  
      // add the top-level svg element and size it
      vis = d3.select('#container').append('svg')
          .attr('width',width)
          .attr('height',height);
  
      // add the nested svg elements
      var nested = vis
          .selectAll('g')
            .data(data.segments)
          .enter().append('g');
  
      // Add a rectangle for each color.  Size of rectangles is determined
      // by the "parent" data object.
      nested
      .each(function(segment, i) {
        var 
            ps = pos(segment),
            sz = size(segment);
  
        var colors = d3.select(this)
          .selectAll('rect')
            .data(segment.colors)
          .enter().append('rect')
            .attr('x', ps)
            .attr('y',ps)
            .attr('width', sz)
            .attr('height',sz)
            .attr('fill', f);
    });
  
  });
  </code></pre>
  
  <p>Here's the full working example: <a href="http://jsbin.com/welcome/42885/edit" rel="nofollow noreferrer">http://jsbin.com/welcome/42885/edit</a></p>