d3.chart.sankey: Reusable D3 Sankey diagram using d3.Chart.
This diagram shows how the ingredients may contribute to the total sustainability of a chocolate bar through different issues.
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>d3.chart.sankey (product demo)</title> | |
| <script src="//d3js.org/d3.v3.min.js"></script> | |
| <script src="//cdn.rawgit.com/newrelic-forks/d3-plugins-sankey/master/sankey.js"></script> | |
| <script src="//cdn.rawgit.com/misoproject/d3.chart/master/d3.chart.min.js"></script> | |
| <script src="//cdn.rawgit.com/q-m/d3.chart.sankey/master/d3.chart.sankey.min.js"></script> | |
| <style> | |
| body { | |
| padding: 10px; | |
| min-width: 600px; | |
| max-width: 1200px; | |
| margin: auto; | |
| } | |
| #chart { | |
| height: 500px; | |
| font: 13px sans-serif; | |
| } | |
| .node rect { | |
| fill-opacity: .9; | |
| shape-rendering: crispEdges; | |
| stroke-width: 0; | |
| } | |
| .node text { | |
| text-shadow: 0 1px 0 #fff; | |
| } | |
| .link { | |
| fill: none; | |
| stroke: #000; | |
| stroke-opacity: .2; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="chart"></div> | |
| <script> | |
| var colors = { | |
| 'environment': '#edbd00', | |
| 'social': '#367d85', | |
| 'animals': '#97ba4c', | |
| 'health': '#f5662b', | |
| 'research_ingredient': '#3f3e47', | |
| 'fallback': '#9f9fa3' | |
| }; | |
| d3.json("//cdn.rawgit.com/q-m/d3.chart.sankey/master/example/data/product.json", function(error, json) { | |
| var chart = d3.select("#chart").append("svg").chart("Sankey.Path"); | |
| chart | |
| .name(label) | |
| .colorNodes(function(name, node) { | |
| return color(node, 1) || colors.fallback; | |
| }) | |
| .colorLinks(function(link) { | |
| return color(link.source, 4) || color(link.target, 1) || colors.fallback; | |
| }) | |
| .nodeWidth(15) | |
| .nodePadding(10) | |
| .spread(true) | |
| .iterations(0) | |
| .draw(json); | |
| function label(node) { | |
| return node.name.replace(/\s*\(.*?\)$/, ''); | |
| } | |
| function color(node, depth) { | |
| var id = node.id.replace(/(_score)?(_\d+)?$/, ''); | |
| if (colors[id]) { | |
| return colors[id]; | |
| } else if (depth > 0 && node.targetLinks && node.targetLinks.length == 1) { | |
| return color(node.targetLinks[0].source, depth-1); | |
| } else { | |
| return null; | |
| } | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> |
This is great. I'm looking to replicate this using different data - do you have any advice on preparing/structuring the data for the json input? Must the sources and targets under the links be numerical? Is there a straightforward way of mapping these to the node labels?
Many thanks