Reputation: 121
I have a D3 Js Sankey diagram, with lots of data. At the end of the data are always companies. The company node is a simple circle. But around that circle i want a donut chart, with 2 values. The values are inside the company node as numsms and nummid. you can also see that in the picture below.
Example of the diagram:
So I want around the company circles a donut chart. But I can't seem to get this to work, I've only found examples for donut charts as own svg.
My code for circles:
svg.selectAll(".node.circle")
.append("circle")
.attr("r", function(d) {
if(d.node.indexOf("company-") > -1) {
return company_circle_size(d);
} else {
return page_circle_size(d);
}
})
.attr("cy", function(d) { return d.dy/2;})
.attr("cx", function(d) {
var cx = sankey.nodeWidth() - 30;
if(d.node.indexOf("company-") > -1) {
cx = cx + 15;
}
return cx;
})
.style("fill", function (d) {
if(d.node.indexOf("company-") > -1) {
if(d.name.indexOf("No data") > -1) {
return "grey";
}
var color = '';
switch(d.status) {
case 'Approved':
color = 'green';
break;
case 'inactive ':
color = 'red';
break;
case 'initial':
color = 'yellow';
break;
case 'review':
color = 'blue';
break;
default:
color = 'grey';
break;
}
return color;
}
return "grey";
//return d.color = color(d.name.replace(/ .*/, ""));
})
.style("fill-opacity", ".9")
.style("shape-rendering", "auto")
.style("stroke", function (d) {
return d3.rgb(d.color).darker(2);
})
.append("title")
.text(function (d) {
if(d.node.indexOf("company-") > -1) {
if(d.cpId != null) {
return d.name + "\n cpId: " + d.cpId;
}
return d.name;
}
return d.name + "\n" + format(d.value);
});
In a for loop I replace the class name "node circle" to "node company".
$(selector).attr("class", "node company")
I've tried some things and I think the code needs to be placed here.
svg.selectAll('.company').each(function(companyNode) {
var values = [[companyNode.numsms, companyNode.nummid]];
var total = companyNode.numsms + companyNode.nummid;
if(total > 0) {
// create donut chart
}
});
Upvotes: 3
Views: 2530
Reputation: 1209
Sankey + Piechart implementation here: http://food.csaladen.es (though pie-chart resides in a static div, so move that above your node every time you evoke it)
Upvotes: -1
Reputation: 108527
Finally got back to this question.
Here's a quick example combining a sankey diagram containing a donut chart. I didn't fit it to your data, this is a generic example.
// if no pie data, just use rects as normal
node.filter(function(d){
return !d.pieData;
})
.append("rect")
.attr("height", function(d) {
return d.dy;
})
.attr("width", sankey.nodeWidth())
.style("fill", function(d) {
return d.color = color(d.name.replace(/ .*/, ""));
})
.style("stroke", function(d) {
return d3.rgb(d.color).darker(2);
})
.append("title")
.text(function(d) {
return d.name + "\n" + format(d.value);
});
// set up donut chart stuff
var pColor = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var arc = d3.svg.arc()
.outerRadius(50)
.innerRadius(20);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// if we have pie data, draw the donut chart
var g = node.filter(function(d){
return d.pieData;
})
.append("g")
.attr('transform', function(d,i){
return 'translate('+d.dx/2+','+d.dy/2+')'; // proper position
})
.attr("class","donut")
.selectAll(".arc")
.data(function(d){
return pie(d.pieData); // nested selection to assign data
})
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d,i) { return color(i); });
Upvotes: 1
Reputation: 1216
You can append a div to the node using foriegnObject. In that div pass your values to an inline jquery sparkline chart (line, pie, etc). Set the transparency of the div so that it doesn't block the diagram. Add your values to the original sankey data array(ie source,target,value,numsms,numid) and then call them in the append with d.numsms).
//sparkline plugin and setup... http://omnipotent.net/jquery.sparkline/#s-docs
//something like the following, look at the fiddle for more info
node.append("foreignObject")
.attr("width", sankey.nodeWidth()*2)
.attr("height", function(d) { return d.dy/2 })
.attr("transform", function(d) { return "translate(" + (d.x+20) + "," + (d.y+10) + ")"; })
.append("xhtml:body")
.style("font", "14px 'Helvetica Neue'")
.html("<div>Inline Sparkline: <span class='inlinesparkline'>1,4,4,7,5,9,10</span></div>");
After adding the div to each node call the plugin to activate the inline charts.
$('.inlinesparkline').sparkline();
Have a look at my fiddle. It's not a sankey but it does show you how to implement foriegnObject.
d3.js diagram with inline charts!
Hope this helps.
Upvotes: 1