Skip to content

Instantly share code, notes, and snippets.

@jasonkolb
Created April 25, 2014 03:10
Show Gist options
  • Save jasonkolb/11276685 to your computer and use it in GitHub Desktop.
Save jasonkolb/11276685 to your computer and use it in GitHub Desktop.
Vertical Sankey
{"description":"Vertical Sankey","endpoint":"","display":"svg","public":true,"require":[{"name":"Sankey Plugin","url":"https://raw.githubusercontent.com/jasonkolb/d3-plugins/master/sankey/sankey.js"}],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"energy.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"inlet.css":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"pingpong","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"ajax-caching":true,"thumbnail":"http://i.imgur.com/ZDaBYMA.png"}
{"nodes":[
{"id": "0", "name" : "Facebook", "type" : "Channel", "lost" : 0.00, "stateType" : "FUNNEL"},
{"id": "1", "name" : "Google", "type" : "Channel", "lost" : 0.00, "stateType" : "FUNNEL"},
{"id": "2", "name" : "Twitter", "type" : "Channel", "lost" : 0.00, "stateType" : "FUNNEL"},
{"id": "3", "name" : "Unknown", "type" : "Channel", "lost" : 0.00, "stateType" : "FUNNEL"},
{"id": "4", "name" : "Marketing Automation", "type" : "Lander", "lost" : 50.00, "stateType" : "FUNNEL"},
{"id": "5", "name" : "Facebook Rules", "type" : "Lander", "lost" : 100.00, "stateType" : "FUNNEL"},
{"id": "6", "name" : "Social Marketing Blueprint", "type" : "Incentive", "lost" : 20.00, "stateType" : "FUNNEL"},
{"id": "7", "name" : "Email Marketing Cheatsheet", "type" : "Incentive", "lost" : 75.0, "stateType" : "FUNNEL"},
{"id": "8", "name" : "14 Day Trial", "type" : "Trial", "lost" : 85, "stateType" : "FUNNEL"},
{"id": "9", "name" : "Bronze Plan", "type" : "Plan", "lost" : 15, "stateType" : "LIFECYCLE"},
{"id": "10", "name" : "Silver Plan", "type" : "Plan", "lost" : 20.0, "stateType" : "LIFECYCLE"},
{"id": "11", "name" : "Gold Plan", "type" : "Plan", "lost" : 25.0, "stateType" : "LIFECYCLE"},
{"id": "12", "name" : "Loyal", "type" : "Segment", "lost" : 2, "stateType" : "LIFECYCLE"},
{"id": "13", "name" : "At Risk", "type" : "Segment", "lost" : 25, "stateType" : "LIFECYCLE"},
{"id": "15", "name" : "25% Discount", "type" : "Incentive", "lost" : 50, "stateType" : "LIFECYCLE"}
],
"links":[
{"source":0,"target":1,"value":124.729},
{"source":1,"target":2,"value":0.597},
{"source":1,"target":3,"value":26.862},
{"source":1,"target":4,"value":280.322},
{"source":1,"target":5,"value":81.144},
{"source":6,"target":2,"value":35},
{"source":7,"target":4,"value":35},
{"source":8,"target":9,"value":11.606},
{"source":10,"target":9,"value":63.965},
{"source":9,"target":4,"value":75.571},
{"source":11,"target":12,"value":10.639},
{"source":11,"target":13,"value":22.505},
{"source":11,"target":14,"value":46.184},
{"source":15,"target":14,"value":113.726},
{"source":15,"target":12,"value":342.165},
{"source":15,"target":13,"value":40.858},
{"source":15,"target":3,"value":56.691},
{"source":5,"target":13,"value":0.129},
{"source":5,"target":3,"value":1.401},
{"source":5,"target":12,"value":48.58},
{"source":2,"target":12,"value":121.066},
{"source":4,"target":12,"value":46.477}
]}
.node rect {
cursor: move;
fill-opacity: .9;
shape-rendering: crispEdges;
}
.node text {
pointer-events: none;
text-shadow: 0 1px 0 #fff;
}
.lostLink{
fill: none;
stroke: red;
stroke-opacity: .5;
}
.link {
fill: none;
stroke: #000;
stroke-opacity: .2;
}
.link:hover {
stroke-opacity: .5;
}
console.log("1")
var margin = {top: 1, right: 1, bottom: 6, left: 1},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var formatNumber = d3.format(",.0f"),
format = function(d) { return formatNumber(d) + " TWh"; },
color = d3.scale.category20();
var svg = d3.select("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
console.log("2")
var sankey = d3.sankey()
.nodeWidth(15)
.nodePadding(10)
.size([width, height]);
var path = sankey.link();
energy = tributary.energy;
sankey
.nodes(energy.nodes)
.links(energy.links)
.layout(32);
console.log("3")
var link = svg.append("g").selectAll(".link")
.data(energy.links)
.enter().append("path")
.attr("class", "link")
.attr("d", path)
.style("stroke-width", function(d) {
console.log(d);
return Math.max(0.8, d.dy); })
.sort(function(a, b) { return b.dy - a.dy; });
link.append("title")
.text(function(d) { return d.source.name + " → " + d.target.name + "\n" + format(d.value); });
console.log("3")
//////// LOST LINK THIS IS CUSTOM SHIZNIT
/*
sankey.lostLink = function() {
var curvature = .5;
function link(d) {
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;
}
}
//ok so the data really needs to be re-arranged here
var link = svg.append("g").selectAll(".lostLink")
.data(energy.nodes)
.enter().append("path")
.attr("class", "link")
.attr("d", sankey.lostLink)
.style("stroke-width", function(d) { return Math.max(0.8, d.dy); })
.sort(function(a, b) { return b.dy - a.dy; });
*/
//////// END CUSTOM SHIZNIT
var node = svg.append("g").selectAll(".node")
.data(energy.nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.call(d3.behavior.drag()
.origin(function(d) { return d; })
.on("dragstart", function() { this.parentNode.appendChild(this); })
.on("drag", dragmove));
node.append("rect")
.attr("height", function(d) { return d.dy; })
.attr("width", sankey.nodeWidth())
.style("fill", function(d) {
return color(d.name);
/* 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); });
node.append("text")
.attr("x", -6)
.attr("y", function(d) { return d.dy / 2; })
.attr("dy", ".35em")
.attr("text-anchor", "end")
.attr("transform", null)
.text(function(d) { return d.name; })
.filter(function(d) { return d.x < width / 2; })
.attr("x", 6 + sankey.nodeWidth())
.attr("text-anchor", "start");
function dragmove(d) {
d3.select(this).attr("transform", "translate(" + d.x + "," + (d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))) + ")");
sankey.relayout();
link.attr("d", path);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment