score:3

Accepted answer

this is, indeed, a little bit complicated, mainly because your y property contains just one object, instead of an array of objects.

my solution here uses d3.entries, which, according to the api:

returns an array containing the property keys and values of the specified object (an associative array). each entry is an object with a key and value attribute, such as {key: "foo", value: 42}. the order of the returned array is undefined. (emphasis mine)

it's important having an array, so we can bind the data (since the data() method accepts only three things: an array, a function or nothing).

so, in this solution, i'm using the outer objects to append groups...

var groups = svg.selectall(null)
  .data(data)
  .enter()
  .append("g");

... and the y object of each outer object to append the rectangles...

var rects = groups.selectall(null)
  .data(function(d) {
    return d3.entries(d.y)
  })
  .enter()
  .append("rect");

... and using d3.entries() to convert the object into an array of objects, which can be used with data().

here is a demo (i changed your actual values, so we can better see the rectangles):

var data = [{
  "x": 100,
  "y": {
    "10": 100,
    "20": 200,
    "26": 300,
    "35": 400
  }
}, {
  "x": 20,
  "y": {
    "50": 60,
    "59.6": 400,
    "70.1": 20,
    "80.8": 320,
    "88": 20,
    "98.8": 722
  }
}, {
  "x": 30,
  "y": {
    "109.8": 80,
    "119.9": 600,
    "139.2": 40
  }
}, {
  "x": 10,
  "y": {
    "150.1": 60,
    "170.3": 400,
    "190.8": 360,
    "209.6": 88
  }
}, {
  "x": 50,
  "y": {
    "259.8": 20,
    "280.4": 450
  }
}];

var colours = d3.scaleordinal(d3.schemecategory10);

var constant = 5;

var svg = d3.select("svg");

var groups = svg.selectall(null)
  .data(data)
  .enter()
  .append("g")
  .style("fill", function(d, i) {
    return colours(i)
  })

var rects = groups.selectall(null)
  .data(function(d) {
    return d3.entries(d.y)
  })
  .enter()
  .append("rect");

rects.attr("y", function(d) {
    return +d.key
  })
  .attr("width", function(d) {
    return d.value
  })
  .attr("height", constant)
  .attr("x", function(d) {
    return d3.select(this.parentnode).datum().x;
  })
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="600" height="300"></svg>

pay attention to how i get the y and width values and, specially, the x value (accessing the parent's datum).


More Query from same tag