0

I am relatively new to coding and very new to d3. I am currently trying to use d3 with json to make a pack layout representing current presidential candidates and how many times they have talked about a certain issue during the feedback.

I wanted to start small so I made some dummy data in a .json file, it is below:

{
 "name": "John Doe",
 "party": "democratic",
 "issues": [
  { "issue":"issue1", "value": 25 },
  { "issue":"issue2", "value": 10 },
  { "issue":"issue3", "value": 50 },
  { "issue":"issue4", "value": 40 },
  { "issue":"issue5", "value": 5 }
 ]
}

I want to display bubbles with "issue" as the label and "value" as the circle radius, ending up with five different sized circles on my canvas. Below is my index.html file:

var width = 800, height = 600;

var canvas = d3.select("body").append("svg")
 .attr("width", width)
 .attr("height", height)
 .append("g")
  .attr("transform", "translate(50, 50)");

var pack = d3.layout.pack()
 .size([width, height - 50])
 .padding(10);

d3.json("fakedata.json", function (data) {

 var nodes = pack.nodes(data);

 var node = canvas.selectAll(".node")
  .data(nodes)
  .enter()
  .append("g")
   .attr("class", "node")
   .attr("transform", function (d) {
     return "translate(" + d.x + "," + d.y + ")";
   });

 node.append("circle")
  .attr("r", function (d) { return d.r; })
  .attr("fill", "steelblue")
  .attr("opacity", 0.25)
  .attr("stroke", "#ADADAD")
  .attr("stroke-width", "2");

 node.append("text")
  .text(function (d) {
    return d.children ? "" : d.issue;
 });
});

I keep getting the error below and I think it is because node is not being set correctly.

 Error: Invalid value for <g> attribute transform="translate(NaN,NaN)"
 Error: Invalid value for <circle> attribute r="NaN"

Any help would be much appreciated! Thank you!

dpasie2
  • 83
  • 1
  • 1
  • 10

2 Answers2

1

The JSON you are passing is

{
 "name": "John Doe",
 "party": "democratic",
 "issues": [
  { "issue":"issue1", "value": 25 },
  { "issue":"issue2", "value": 10 },
  { "issue":"issue3", "value": 50 },
  { "issue":"issue4", "value": 40 },
  { "issue":"issue5", "value": 5 }
 ]
}

It should have been like below note the key name children instead of issues

{
 "name": "John Doe",
 "party": "democratic",
 "children": [
  { "issue":"issue1", "value": 25 },
  { "issue":"issue2", "value": 10 },
  { "issue":"issue3", "value": 50 },
  { "issue":"issue4", "value": 40 },
  { "issue":"issue5", "value": 5 }
 ]
}

Working code here.

halfer
  • 19,824
  • 17
  • 99
  • 186
Cyril Cherian
  • 32,177
  • 7
  • 46
  • 55
1

The answer is a bit late, but in case you don't want to change your data structure and you want to keep the issues property, you can explicitly tell D3 to use the issues property for children data using the children() call:

var pack = d3.layout.pack()
   .size([width, height - 50])
   .children(function (d) { return d.issues; })
   .padding(10);
iulian
  • 5,494
  • 3
  • 29
  • 39