JamesE
JamesE

Reputation: 3923

D3 access nested data

I have some nested data in this format:

[{"key":"PFOA",
  "values":[
     {"sampleDate":"2016-0126T05:00:00.000Z",
      "shortName":"PFOA",
      "pfcLevel":0,
      "chemID":1},
     {"sampleDate":"2016-01-19T05:00:00.000Z",
      "shortName":"PFOA",
      "pfcLevel":0,
      "chemID":1},
     {"sampleDate":"2016-01-12T05:00:00.000Z",
      "shortName":"PFOA",
      "pfcLevel":0,
      "chemID":1}
   ],
   "visible":0}
]

I'm trying to use this data to add circles to a multi-line graph. I can do this if I use the raw, non-nested data directly from the database, but that is causing other issues. I'd rather use the same nested data for the lines and the circles if possible. The nest function and the circle code is below:

var nested_data = d3.nest()
        .key(function(d) { return d.shortName; })
        .entries(data);

var circles = svg.selectAll(".circle")
        .data(nested_data) 
      .enter().append("g")
        .attr("class", "circle");

circles.append("circle")
        .attr("stroke", function(d) { return color(d.key); })
        .attr("fill", "white")
        .attr("cx", function(d, i) { return x(d.values['sampleDate']) })
        .attr("cy", function(d, i) { return y(d.values['pfcLevel']) })
        .attr("r", 2);

I've tried different things like d.values[sampleDate] or .data(nested_data.values) but I am getting undefined errors on all of them.

Thanks in advance.

Upvotes: 0

Views: 3527

Answers (1)

MrHen
MrHen

Reputation: 2480

You are looking for a Nested Selection:

var nested_data = d3.nest()
  .key(function(d) {
    return d.shortName;
  })
  .entries(data);

var groups = svg.selectAll(".circle")
  .data(nested_data)
  .enter().append("g")
  .attr("class", "circle");

var circles = groups.selectAll("circle") // start a nested selection
  .data(function(d) {
    return d.values; // tell d3 where the children are
  })
  .enter().append("circle")
  .attr("stroke", function(d) {
    return color(d.shortName);
  })
  .attr("fill", "white")
  .attr("cx", function(d, i) {
    return x(d.sampleDate) // use the fields directly; no reference to "values"
  })
  .attr("cy", function(d, i) {
    return y(d.pfcLevel)
  })
  .attr("r", 2);

Upvotes: 1

Related Questions