Last active
August 29, 2015 14:02
-
-
Save katemonkeys/8fe7ec1a3a0f7bd62098 to your computer and use it in GitHub Desktop.
Lunch Money Debts This Quarter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gistup |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
node_modules/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This plot shows the total money owed between colleagues for lunch over time. Colors and chords indicate direction and amount of lending. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<body> | |
<div id="ticker">March 1</div> | |
<div id="evolution"> | |
</div> | |
<script src="http://code.jquery.com/jquery-1.11.0.min.js"> </script> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script>var color = d3.scale.category10();</script> | |
<script> | |
var names = ["Alex","Lauren","Ryan","Liz","Philip","Chris"] | |
var lunchData = [ | |
[0,1,1,1,1,1], | |
[1,0,1,1,1,1], | |
[1,1,0,1,1,1], | |
[1,1,1,0,1,1], | |
[1,1,1,1,0,1], | |
[1,1,1,1,1,0] | |
]; | |
var datafile = 'sequence.json'; | |
d3.chart = d3.chart || {}; | |
d3.chart.chord = function(options) { | |
var self = {}; | |
var svg; | |
var chord = d3.layout.chord() | |
.padding(.05) | |
.sortSubgroups(d3.descending); | |
var w = Math.min(screen.width,960)-20, | |
h = Math.min(screen.height,500), | |
innerRadius, outerRadius, | |
coloring = 'bigger'; | |
if (screen.width<screen.height) { | |
innerRadius = w * .30; | |
} else { | |
innerRadius = h * .37; | |
} | |
outerRadius = innerRadius * 1.1; | |
self.fill = color; | |
var arc_svg = d3.svg.arc().innerRadius(innerRadius).outerRadius(outerRadius) | |
var chord_svg = d3.svg.chord().radius(innerRadius); | |
var comp = { | |
bigger: function(a, b) { return a.value > b.value ? a : b }, | |
smaller: function(a, b) { return a.value < b.value ? a : b } | |
} | |
for (key in options) { | |
self[key] = options[key]; | |
} | |
self.update = function(data) { | |
if (!chord.matrix()) { | |
chord.matrix(data); | |
self.render(); | |
} else { | |
var old = { | |
groups: chord.groups(), | |
chords: chord.chords() | |
}; | |
chord.matrix(data); | |
self.transition(old); | |
} | |
}; | |
self.clear = function() { | |
d3.select(self.container).selectAll('svg').remove(); | |
}; | |
self.transition = function(old) { | |
svg.selectAll(".arc") | |
.data(chord.groups) | |
.transition() | |
.ease("linear") | |
.duration(1000) | |
.attrTween("d", arcTween(arc_svg, old)); | |
svg.selectAll(".chord") | |
.selectAll("path") | |
.data(chord.chords) | |
.transition() | |
.ease("linear") | |
.duration(1000) | |
.style("fill", function(d) { return self.fill(comp[coloring](d.source, d.target).index); }) | |
.attrTween("d", chordTween(chord_svg, old)); | |
}; | |
self.render = function() { | |
self.clear(); | |
svg = d3.select(self.container) | |
.append("svg") | |
.attr("width", w) | |
.attr("height", h) | |
.append("g") | |
.attr("transform", "translate(" + w / 2 + "," + h / 2 + ")"); | |
svg.append("g") | |
.selectAll("path") | |
.data(chord.groups) | |
.enter().append("path") | |
.attr("class", "arc") | |
.style("fill", function(d) { return self.fill(d.index); }) | |
.style("stroke", "#ccc")//function(d) { return self.fill(d.index); }) | |
.attr("d", arc_svg); | |
svg.append("g") | |
.attr("class", "chord") | |
.selectAll("path") | |
.data(chord.chords) | |
.enter().append("path") | |
.style("fill", function(d) { return self.fill(comp[coloring](d.source, d.target).index); }) | |
.attr("d", chord_svg) | |
.style("opacity", 0.8); | |
self.drawLegend(); | |
}; | |
self.drawLegend = function() { | |
var legendData = []; | |
for (var i=0; i<names.length; i++) { | |
legendData.push({name:names[i],color:color(i)}); | |
} | |
//TODO: refactor this duplication!! | |
svg.append("g") | |
.selectAll("rect") | |
.data(legendData) | |
.enter().append("rect") | |
.attr("class","legend") | |
.attr("width",25) | |
.attr("height",25) | |
.style("fill",function(d) {return d.color;}) | |
.attr("transform", function(d,i) { | |
return "translate("+ -3*h/4+","+i*30+")" | |
}); | |
svg.append("g") | |
.selectAll("text") | |
.data(legendData) | |
.enter().append("text") | |
.attr("x",14) | |
.attr("dy","0.35em") | |
.attr("transform", function(d,i) { | |
var vertPos = i*30 + 13; | |
return "translate("+ -23*h/32 +","+vertPos+")" | |
}) | |
.text(function(d){return d.name;}) | |
} | |
return self; | |
}; | |
/* Utility functions */ | |
function arcTween(arc_svg, old) { | |
return function(d,i) { | |
var i = d3.interpolate(old.groups[i], d); | |
return function(t) { | |
return arc_svg(i(t)); | |
} | |
} | |
} | |
function chordTween(chord_svg, old) { | |
return function(d,i) { | |
var i = d3.interpolate(old.chords[i], d); | |
return function(t) { | |
return chord_svg(i(t)); | |
} | |
} | |
} | |
var counter = 0; | |
var eventOrder = []; | |
var jsondata = []; | |
d3.json(datafile, function(data) { | |
jsondata = data.events | |
for (var i=0; i<data.events.length; i++) { | |
var lenderIndex = null; | |
for (var j=0; j<names.length; j++) { | |
if (names[j] === jsondata[i].lender) { | |
lenderIndex = j; | |
} | |
} | |
for (var j=0; j<names.length; j++) { | |
for (var k=0; k<data.events[i].borrower.length; k++) { | |
if (names[j] === jsondata[i].borrower[k]) { | |
eventOrder.push([lenderIndex,j,jsondata[i].amount,jsondata[i].timeOfDay]); | |
} | |
} | |
} | |
} | |
}); | |
function initChord() { | |
var chord = d3.chart.chord({ | |
container: "#evolution", | |
fill: color | |
}); | |
var lender, borrower, amount; | |
chord.update(lunchData); | |
setInterval(function() { | |
if (counter < eventOrder.length-1) { | |
counter++; | |
$("#ticker").text(eventOrder[counter][3]); | |
lender = eventOrder[counter][0]; | |
borrower = eventOrder[counter][1]; | |
amount = eventOrder[counter][2]; | |
lunchData[lender][borrower] += amount; | |
chord.update(lunchData); | |
} | |
}, 1000) | |
} | |
var i=0; | |
initChord(); | |
</script> | |
</body> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"events": [ | |
{ | |
"lender":"Alex", | |
"borrower":["Liz"], | |
"timeOfDay":"March 1", | |
"amount":4 | |
}, | |
{ | |
"lender":"Liz", | |
"borrower":["Alex"], | |
"timeOfDay":"March 2", | |
"amount":5 | |
}, | |
{ | |
"lender":"Alex", | |
"borrower":["Liz"], | |
"timeOfDay":"March 3", | |
"amount":5 | |
}, | |
{ | |
"lender":"Liz", | |
"borrower":["Alex"], | |
"timeOfDay":"March 4", | |
"amount":8 | |
}, | |
{ | |
"lender":"Alex", | |
"borrower":["Liz"], | |
"timeOfDay":"March 5", | |
"amount":3 | |
}, | |
{ | |
"lender":"Liz", | |
"borrower":["Alex"], | |
"timeOfDay":"March 6", | |
"amount":8 | |
}, | |
{ | |
"lender":"Alex", | |
"borrower":["Liz"], | |
"timeOfDay":"March 7", | |
"amount":6 | |
}, | |
{ | |
"lender":"Liz", | |
"borrower":["Alex"], | |
"timeOfDay":"March 8", | |
"amount":5 | |
}, | |
{ | |
"lender":"Alex", | |
"borrower":["Liz"], | |
"timeOfDay":"March 9", | |
"amount":5 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Lauren"], | |
"timeOfDay":"March 10", | |
"amount":15 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Philip"], | |
"timeOfDay":"March 11", | |
"amount":12 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Lauren"], | |
"timeOfDay":"March 12", | |
"amount":15 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Philip"], | |
"timeOfDay":"March 13", | |
"amount":12 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Lauren"], | |
"timeOfDay":"March 14", | |
"amount":15 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Philip"], | |
"timeOfDay":"March 15", | |
"amount":12 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Lauren"], | |
"timeOfDay":"March 16", | |
"amount":15 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Philip"], | |
"timeOfDay":"March 17", | |
"amount":12 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Lauren"], | |
"timeOfDay":"March 18", | |
"amount":15 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Philip"], | |
"timeOfDay":"March 19", | |
"amount":12 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Philip","Liz","Chris"], | |
"timeOfDay":"March 20", | |
"amount":20 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Lauren","Liz","Chris"], | |
"timeOfDay":"March 21", | |
"amount":24 | |
}, | |
{ | |
"lender":"Liz", | |
"borrower":["Philip","Lauren","Chris"], | |
"timeOfDay":"March 22", | |
"amount":23 | |
}, | |
{ | |
"lender":"Chris", | |
"borrower":["Philip","Liz","Lauren"], | |
"timeOfDay":"March 23", | |
"amount":14 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Philip","Liz","Chris"], | |
"timeOfDay":"March 24", | |
"amount":20 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Lauren","Liz","Chris"], | |
"timeOfDay":"March 25", | |
"amount":24 | |
}, | |
{ | |
"lender":"Liz", | |
"borrower":["Philip","Lauren","Chris"], | |
"timeOfDay":"March 26", | |
"amount":23 | |
}, | |
{ | |
"lender":"Chris", | |
"borrower":["Philip","Liz","Lauren"], | |
"timeOfDay":"March 27", | |
"amount":14 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Philip","Liz","Chris"], | |
"timeOfDay":"March 28", | |
"amount":20 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Lauren","Liz","Chris"], | |
"timeOfDay":"March 29", | |
"amount":24 | |
}, | |
{ | |
"lender":"Liz", | |
"borrower":["Philip","Lauren","Chris"], | |
"timeOfDay":"March 30", | |
"amount":23 | |
}, | |
{ | |
"lender":"Chris", | |
"borrower":["Philip","Liz","Lauren"], | |
"timeOfDay":"March 31", | |
"amount":14 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Alex"], | |
"timeOfDay":"April 1", | |
"amount":40 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Chris"], | |
"timeOfDay":"April 2", | |
"amount":16 | |
}, | |
{ | |
"lender":"Alex", | |
"borrower":["Lauren"], | |
"timeOfDay":"April 3", | |
"amount":35 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Alex"], | |
"timeOfDay":"April 4", | |
"amount":16 | |
}, | |
{ | |
"lender":"Alex", | |
"borrower":["Lauren"], | |
"timeOfDay":"April 5", | |
"amount":35 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Alex"], | |
"timeOfDay":"April 6", | |
"amount":16 | |
}, | |
{ | |
"lender":"Alex", | |
"borrower":["Lauren"], | |
"timeOfDay":"April 7", | |
"amount":35 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Alex"], | |
"timeOfDay":"April 8", | |
"amount":16 | |
}, | |
{ | |
"lender":"Alex", | |
"borrower":["Lauren"], | |
"timeOfDay":"April 9", | |
"amount":35 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Alex"], | |
"timeOfDay":"April 10", | |
"amount":16 | |
}, | |
{ | |
"lender":"Alex", | |
"borrower":["Lauren"], | |
"timeOfDay":"April 11", | |
"amount":19 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Alex"], | |
"timeOfDay":"April 12", | |
"amount":19 | |
}, | |
{ | |
"lender":"Ryan", | |
"borrower":["Chris"], | |
"timeOfDay":"April 13", | |
"amount":18 | |
}, | |
{ | |
"lender":"Chris", | |
"borrower":["Ryan"], | |
"timeOfDay":"April 14", | |
"amount":18 | |
}, | |
{ | |
"lender":"Ryan", | |
"borrower":["Chris"], | |
"timeOfDay":"April 15", | |
"amount":18 | |
}, | |
{ | |
"lender":"Chris", | |
"borrower":["Ryan"], | |
"timeOfDay":"April 16", | |
"amount":18 | |
}, | |
{ | |
"lender":"Ryan", | |
"borrower":["Chris"], | |
"timeOfDay":"April 17", | |
"amount":18 | |
}, | |
{ | |
"lender":"Chris", | |
"borrower":["Ryan"], | |
"timeOfDay":"April 18", | |
"amount":18 | |
}, | |
{ | |
"lender":"Ryan", | |
"borrower":["Chris"], | |
"timeOfDay":"April 19", | |
"amount":18 | |
}, | |
{ | |
"lender":"Chris", | |
"borrower":["Ryan"], | |
"timeOfDay":"April 20", | |
"amount":18 | |
}, | |
{ | |
"lender":"Ryan", | |
"borrower":["Philip","Alex"], | |
"timeOfDay":"April 21", | |
"amount":37 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Liz"], | |
"timeOfDay":"April 22", | |
"amount":47 | |
}, | |
{ | |
"lender":"Liz", | |
"borrower":["Ryan","Alex"], | |
"timeOfDay":"April 23", | |
"amount":17 | |
}, | |
{ | |
"lender":"Chris", | |
"borrower":["Liz"], | |
"timeOfDay":"April 24", | |
"amount":27 | |
}, | |
{ | |
"lender":"Chris", | |
"borrower":["Lauren","Ryan"], | |
"timeOfDay":"April 25", | |
"amount":17 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Lauren"], | |
"timeOfDay":"April 26", | |
"amount":20 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Philip"], | |
"timeOfDay":"April 27", | |
"amount":10 | |
}, | |
{ | |
"lender":"Liz", | |
"borrower":["Alex","Philip"], | |
"timeOfDay":"April 28", | |
"amount":16 | |
}, | |
{ | |
"lender":"Ryan", | |
"borrower":["Lauren"], | |
"timeOfDay":"April 29", | |
"amount":15 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Ryan"], | |
"timeOfDay":"April 30", | |
"amount":11 | |
}, | |
{ | |
"lender":"Ryan", | |
"borrower":["Lauren"], | |
"timeOfDay":"May 1", | |
"amount":13 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Ryan"], | |
"timeOfDay":"May 2", | |
"amount":17 | |
}, | |
{ | |
"lender":"Chris", | |
"borrower":["Alex"], | |
"timeOfDay":"May 3", | |
"amount":19 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Lauren"], | |
"timeOfDay":"May 4", | |
"amount":15 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Philip"], | |
"timeOfDay":"May 5", | |
"amount":12 | |
}, | |
{ | |
"lender":"Ryan", | |
"borrower":["Philip"], | |
"timeOfDay":"May 6", | |
"amount":15 | |
}, | |
{ | |
"lender":"Alex", | |
"borrower":["Liz"], | |
"timeOfDay":"May 7", | |
"amount":19 | |
}, | |
{ | |
"lender":"Liz", | |
"borrower":["Alex"], | |
"timeOfDay":"May 8", | |
"amount":35 | |
}, | |
{ | |
"lender":"Chris", | |
"borrower":["Liz"], | |
"timeOfDay":"May 9", | |
"amount":19 | |
}, | |
{ | |
"lender":"Lauren", | |
"borrower":["Alex"], | |
"timeOfDay":"May 10", | |
"amount":3 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Alex","Liz"], | |
"timeOfDay":"May 11", | |
"amount":10 | |
}, | |
{ | |
"lender":"Philip", | |
"borrower":["Ryan"], | |
"timeOfDay":"May 12", | |
"amount":20 | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment