I am creating an interactive bubble chart of fortune 500 data. I am trying to reduce a selection but can't figure out why it's not working as I expect.
var bubble = d3.layout.pack()
...
d3.json("js/data/fortune2009.json", function(json) {
var node = svg.data([json]).selectAll("g.node")
.data(bubble.nodes); // filter here?
node.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("class", function(d) { return "q" + color(d.Profit) + "-9"; });
node.filter(function(d) { return !d.children; })
.append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.Company.substring(0, d.r / 3); });
});
The JSON data looks like this:
{
"children":[
{
"Year" : "2009",
"Rank" : "1",
"Revenue" : "442",
"Profit" : "851.00",
"Company" : "Exxon Mobil"
},
....
}
I want to remove the parent node. I am trying to use a filter function like described here.
.filter(function(d) { return !d.children; })
But if i add my filter function where I initialize the node
selection, either nothing happens or I get an error.
(The filter works when I apply it before appending text)
How do I solve this?
UPDATE: Here is a JSFIDDLE / showing my problem.
I am creating an interactive bubble chart of fortune 500 data. I am trying to reduce a selection but can't figure out why it's not working as I expect.
var bubble = d3.layout.pack()
...
d3.json("js/data/fortune2009.json", function(json) {
var node = svg.data([json]).selectAll("g.node")
.data(bubble.nodes); // filter here?
node.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("class", function(d) { return "q" + color(d.Profit) + "-9"; });
node.filter(function(d) { return !d.children; })
.append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.Company.substring(0, d.r / 3); });
});
The JSON data looks like this:
{
"children":[
{
"Year" : "2009",
"Rank" : "1",
"Revenue" : "442",
"Profit" : "851.00",
"Company" : "Exxon Mobil"
},
....
}
I want to remove the parent node. I am trying to use a filter function like described here.
.filter(function(d) { return !d.children; })
But if i add my filter function where I initialize the node
selection, either nothing happens or I get an error.
(The filter works when I apply it before appending text)
How do I solve this?
UPDATE: Here is a JSFIDDLE http://jsfiddle/B9w4N/8/ showing my problem.
Share Improve this question edited Jun 26, 2014 at 19:35 VividD 10.5k8 gold badges66 silver badges112 bronze badges asked Jan 28, 2013 at 12:43 swenedoswenedo 3,1149 gold badges32 silver badges50 bronze badges 1-
1
At a glance I'd guess that you'd need to put your filter between
node.enter()
and.append("g")
, but it'd take more time than I have to spare to get an example running so it'd help if you could put something working on JSFiddle... – Richard Marr Commented Jan 28, 2013 at 13:01
2 Answers
Reset to default 8You had the right idea. You just needed to apply the filter where the circles are created (in addition to where the text is created):
node
.filter(function(d) { return !d.children; })
.append("circle")
.attr("r", function(d) { return d.r; });
Forked version on JSFiddle
You can filter the array that the layout outputs:
var node = svg.data([fortune2009]).selectAll("g.node")
.data(function(d) {
return bubble.nodes(d).filter(function(v) {
return v.depth > 0;
});
});
See updated fiddle: http://jsfiddle/B9w4N/10/