#D3 Sankey Link with Variable Width
Creates a path that resembles a sankey link, but has different heights at the source and target. I plan to use this to tie map geometries to an adjacent stacked bar chart.
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <title>Variable Width Sankey Link</title> | |
| <style> | |
| path { | |
| fill: steelblue; | |
| } | |
| </style> | |
| <body> | |
| <p id="chart"> | |
| <script src="http://d3js.org/d3.v3.min.js"></script> | |
| <script> | |
| //based on 'Sankey from csv with d3.js' http://bl.ocks.org/d3noob/c9b90689c1438f57d649 | |
| var margin = {top: 10, right: 10, bottom: 10, left: 10}, | |
| width = 700 - margin.left - margin.right, | |
| height = 300 - margin.top - margin.bottom; | |
| // append the svg canvas to the page | |
| var svg = d3.select("#chart").append("svg") | |
| .attr("width", width + margin.left + margin.right) | |
| .attr("height", height + margin.top + margin.bottom) | |
| .append("g") | |
| .attr("transform", | |
| "translate(" + margin.left + "," + margin.top + ")"); | |
| //array of d3 sankey nodes | |
| var data = [{ | |
| dy: 100, //link height, same as source.dy? | |
| source: { | |
| dx:36, //node width | |
| dy:40, //node height | |
| x:0, //node position | |
| y:125 | |
| }, | |
| sy:0, //y-offset of link from top of source node | |
| target: { | |
| dx:36, //node width | |
| dy:100, //node height | |
| x:664, //node position | |
| y:0 | |
| }, | |
| ty: 0, //y-offset of link from top of target node | |
| value: 2 | |
| }] | |
| svg.selectAll("path") | |
| .data(data) | |
| .enter() | |
| .append("path") | |
| .attr("d", function(d) { return link(d)}); | |
| //borrowed from sankey.js, draws one a line from top of source to top of target, top of target to bottom of target, bottom of target to bottom of source, bottom of source to top of source | |
| function link(d) { | |
| var curvature = .6; | |
| var x0 = d.source.x + d.source.dx, | |
| x1 = d.target.x, | |
| xi = d3.interpolateNumber(x0, x1), | |
| x2 = xi(curvature), | |
| x3 = xi(1 - curvature), | |
| y0 = d.source.y + d.sy + d.dy / 2, | |
| y1 = d.target.y + d.ty + d.dy / 2; | |
| return "M" + x0 + "," + y0 | |
| + "C" + x2 + "," + y0 | |
| + " " + x3 + "," + y1 | |
| + " " + x1 + "," + y1 | |
| + "L" + x1 + "," + (y1+d.target.dy) | |
| + "C" + x3 + "," + (y1+d.target.dy) | |
| + " " + x2 + "," + (y0+d.source.dy) | |
| + " " + x0 + "," + (y0+d.source.dy) | |
| + "L" + x0 + "," + y0; | |
| } | |
| </script> | |
| </body> | |
| </html> |