[ Launch: tributary meta vis ] 5175430 by enjalot
[ Launch: tributary meta vis ] 5175381 by poezn
[ Launch: tributary meta vis ] 5175328 by poezn
[ Launch: tributary meta vis ] 5175210 by enjalot
-
-
Save enjalot/5175430 to your computer and use it in GitHub Desktop.
tributary meta vis
This file contains 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
{"description":"tributary meta vis","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"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},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":true,"loop":true,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/Loh9N0r.png"} |
This file contains 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
var cw = 510; | |
var ch = 236; | |
var ah = 100; | |
var aws = 3; | |
var margin = 102; | |
var amargin = 66; | |
var strokecolor = "#C9FD23"; | |
var ustrokecolor = "#23FDEC"; | |
//var weekdayColor = "#CFDB49"; | |
//var weekendColor = "#64B4CE"; | |
var weekdayColor = weekendColor = strokecolor; | |
var titley = 50; | |
var duration = 15000; | |
tributary.duration = duration; | |
var dateformat = d3.time.format("%b %d, %Y") | |
var trib_url = 'http://tributary.io/', | |
//users_url = trib_url + 'api/users', | |
created_url = trib_url + 'api/latest/created/limit=2000', | |
trib_inlet = trib_url + 'inlet/'; | |
var svg = d3.select("svg"); | |
d3.selectAll("#display") | |
.style({ | |
background: "#151F38" | |
}) | |
tributary.init = function(g) { | |
if(!tributary.inlets) return; | |
//accumulate inlets; | |
//inlets come back in order so don't really need to do this | |
var firstInlet = d3.min(tributary.inlets, function(d) { return d3.time.day.floor(d.createdAt) }); | |
var lastInlet = d3.max(tributary.inlets, function(d) { return d.createdAt }); | |
console.log(tributary.inlets[tributary.inlets.length-1]) | |
var weekdayFirst = firstInlet.getDay(); | |
//console.log("first", firstInlet, "last", lastInlet); | |
//console.log("number", tributary.inlets.length); | |
var days = d3.time.day.range(firstInlet, lastInlet); | |
days.unshift(firstInlet); | |
//console.log(days); | |
var daily = {}; | |
var userdaily = {}; | |
var dictusers = {}; | |
tributary.inlets.forEach(function(inlet) { | |
var day = d3.time.day.floor(inlet.createdAt); | |
daily[day] = daily[day]+1 || 1; | |
if(!inlet.user) return; | |
if(!dictusers[inlet.user.login]) { | |
dictusers[inlet.user.login] = day; | |
userdaily[day] = userdaily[day]+1 || 1 | |
} | |
}) | |
//console.log(daily) | |
var cumulative = []; | |
var cusers = [] | |
var val = 0; | |
var uval = 0; | |
days.forEach(function(day) { | |
val += daily[day] || 0; | |
cumulative.push(val); | |
uval += userdaily[day] || 0; | |
cusers.push(uval); | |
}) | |
var firstUser = Infinity | |
var lastUser = 0 | |
var listusers = []; | |
for(var u in dictusers) { | |
/* if(+dictusers[u] < +firstUser) { | |
firstUser = dictusers[u]; | |
} else if(+dictusers[u] > +lastUser) { | |
lastUser = dictusers[u]; | |
}*/ | |
listusers.push(dictusers[u]); | |
} | |
firstUser = d3.min(listusers); | |
lastUser = d3.max(listusers); | |
console.log(firstUser, lastUser, listusers.length); | |
var utimescale = d3.time.scale() | |
.domain([firstInlet, lastInlet]) | |
.range([margin, cw + margin]); | |
var cuyscale = d3.scale.linear() | |
.domain([0, tributary.inlets.length]) | |
.range([margin+ch, margin]); | |
var uline = d3.svg.line() | |
.interpolate("basis") | |
.x(function(d,i) { | |
return utimescale(days[i]); | |
}) | |
.y(function(d,i) { | |
return cuyscale(d); | |
}) | |
cumg = g.append("g") | |
.classed("cumulative", true) | |
cumg.append("path") | |
.attr("d", uline(cusers)) | |
.style({ | |
"opacity": 0.1, | |
stroke: ustrokecolor | |
}) | |
cumg2 = g.append("g") | |
.classed("cumulative2", true) | |
cumg2.append("path") | |
.attr("d", uline(cusers)) | |
cumg3 = g.append("g") | |
.classed("cumulative3", true) | |
.style({ | |
stroke: ustrokecolor | |
}) | |
cumg3.append("path") | |
.attr("d", uline(cusers)) | |
.style({ | |
stroke: ustrokecolor | |
}) | |
var timescale = d3.time.scale() | |
.domain([firstInlet, lastInlet]) | |
.range([margin, cw + margin]); | |
var cyscale = d3.scale.linear() | |
.domain([0, tributary.inlets.length]) | |
.range([margin+ch, margin]); | |
var line = d3.svg.line() | |
.interpolate("basis") | |
.x(function(d,i) { | |
return timescale(days[i]); | |
}) | |
.y(function(d,i) { | |
return cyscale(d); | |
}) | |
var cumg = g.append("g") | |
.classed("cumulative", true) | |
cumg.append("path") | |
.attr("d", line(cumulative)) | |
.style({ | |
stroke: strokecolor, | |
"opacity": 0.1 | |
}) | |
var cumg2 = g.append("g") | |
.classed("cumulative2", true) | |
cumg2.append("path") | |
.attr("d", line(cumulative)) | |
.style({ | |
stroke: strokecolor | |
}) | |
var cumg3 = g.append("g") | |
.classed("cumulative3", true) | |
cumg3.append("path") | |
.attr("d", line(cumulative)) | |
.style({ | |
stroke: strokecolor | |
}) | |
var dailyActivity = []; | |
days.forEach(function(day) { | |
dailyActivity.push(daily[day] || 0); | |
}) | |
var ayscale = d3.scale.linear() | |
.domain([0, d3.max(dailyActivity)]) | |
.range([2, ah]) | |
var aw = ah/days.length; | |
var activity = g.append("g") | |
.attr("transform", "translate(" + [0, amargin] + ")") | |
.classed("activity", true) | |
activity.selectAll("rect.inlets") | |
.data(dailyActivity) | |
.enter() | |
.append("rect") | |
.classed("inlets", true) | |
.attr({ | |
x: function(d,i) { | |
return timescale(days[i]) - aw/2 | |
}, | |
y: function(d,i) { | |
return ch + margin + 42; | |
}, | |
rx: 3, | |
ry: 3, | |
width: aw + aws, | |
height: function(d,i) { | |
return ayscale(d); | |
} | |
}) | |
.style({ | |
fill: function(d, i) { | |
if (days[i] % 7 - weekdayFirst > 0) { | |
// weekdays | |
return weekdayColor; | |
} | |
// weekend | |
return weekendColor; | |
} | |
}) | |
//TEXT | |
g.append("g") | |
.classed("numbertitle", true) | |
.append("text") | |
.classed("cumulativeinlets", true) | |
//.text("cumulative inlets created: " + tributary.inlets.length) | |
.attr({ | |
x: margin, | |
y: margin - titley, | |
fill: strokecolor | |
}) | |
g.append("g") | |
.classed("numbertitle", true) | |
.append("text") | |
.classed("cumulativeusers", true) | |
.attr({ | |
x: margin - 0, | |
y: margin - titley + 36, | |
fill: ustrokecolor | |
}) | |
var firstday = g.append("g") | |
.classed("numbertitle", true) | |
.classed("firstday", true) | |
firstday.append("rect") | |
.attr({ | |
x: margin, | |
y: margin + ch + amargin/2, | |
width: 3, | |
height: 51, | |
fill: strokecolor | |
//stroke: strokecolor | |
}) | |
firstday.append("text") | |
.text(dateformat(firstInlet)) | |
.attr({ | |
x: margin + 12, | |
y: margin + ch + amargin + 4, | |
fill: strokecolor | |
//stroke: strokecolor | |
}) | |
var lastday = g.append("g") | |
.classed("numbertitle", true) | |
.classed("lastday", true) | |
lastday.append("rect") | |
.attr({ | |
x: margin + cw - 1.5, | |
y: margin + ch + amargin/2, | |
width: 3, | |
height: 51, | |
fill: strokecolor | |
//stroke: strokecolor | |
}) | |
lastday.append("text") | |
.text(dateformat(lastInlet)) | |
.attr({ | |
x: margin + cw - 12, | |
y: margin + ch + amargin + 4, | |
fill: strokecolor | |
//stroke: strokecolor | |
}) | |
g.append("text") | |
.classed("curact", true) | |
.classed("numbertitle", true) | |
.attr({ | |
x: margin, | |
y: margin + ch + amargin + ah*2, | |
fill: strokecolor | |
}) | |
//Track cumulative | |
g.append("circle") | |
.classed("curcum", true) | |
.attr({ | |
r: 6, | |
fill: strokecolor | |
}) | |
g.append("circle") | |
.classed("curcum", true) | |
.attr({ | |
r: 10, | |
fill: strokecolor | |
}) | |
g.append("circle") | |
.classed("ucurcum", true) | |
.attr({ | |
r: 5, | |
fill: ustrokecolor | |
}) | |
g.append("circle") | |
.classed("ucurcum", true) | |
.attr({ | |
r: 10, | |
fill: ustrokecolor | |
}) | |
tributary.timescale = timescale; | |
tributary.cyscale = cyscale; | |
tributary.days = days; | |
tributary.cumulative = cumulative; | |
tributary.activity = dailyActivity; | |
tributary.cusers = cusers; | |
tributary.listusers = listusers | |
} | |
tributary.run = function(g, t) { | |
if(!tributary.inlets) return; | |
var day = Math.floor(t * (tributary.days.length-1)); | |
//console.log("day", day); | |
var activity = g.select("g.activity"); | |
var sel = activity.selectAll("rect").filter(function(d,i) { | |
return i == day; | |
}).classed("selected", true); | |
sel = activity.selectAll("rect").filter(function(d,i) { | |
return i != day; | |
}).classed("selected", false); | |
g.select(".cumulativeinlets").text("cumulative inlets created: " + (tributary.cumulative[day])) | |
g.select(".cumulativeusers").text("cumulative users created: " + (tributary.cusers[day]+1)) | |
if(day === 0) { | |
g.select(".firstday").classed("selected", true) | |
} else if(day == tributary.days.length-1) { | |
g.select(".lastday").classed("selected", true) | |
} else { | |
g.select(".firstday").classed("selected", false) | |
g.select(".lastday").classed("selected", false) | |
} | |
if(day == 0) { | |
g.selectAll(".curcum") | |
.attr({ | |
cx: tributary.timescale(tributary.days[day]), | |
cy: tributary.cyscale(tributary.cumulative[day]) | |
}) | |
g.selectAll(".ucurcum") | |
.attr({ | |
cx: tributary.timescale(tributary.days[day]), | |
cy: tributary.cyscale(tributary.cusers[day]) | |
}) | |
} | |
g.selectAll(".curcum") | |
.transition() | |
.duration(tributary.duration/tributary.days.length - 100) | |
.attr({ | |
cx: tributary.timescale(tributary.days[day]), | |
cy: tributary.cyscale(tributary.cumulative[day]) | |
}) | |
g.selectAll(".ucurcum") | |
.transition() | |
.duration(tributary.duration/tributary.days.length - 100) | |
.attr({ | |
cx: tributary.timescale(tributary.days[day]), | |
cy: tributary.cyscale(tributary.cusers[day]) | |
}) | |
var weekdayFirst = tributary.days[0].getDay(); | |
var weekdayend = (tributary.days[day] % 7 - weekdayFirst) > 0? "weekday": "weekend"; | |
g.select(".curact") | |
.text(tributary.activity[day] + " inlets created on " + dateformat(tributary.days[day]) ) | |
.attr("x", tributary.sw/2) | |
g.select(".curact") | |
.append("tspan") | |
.classed("weekdayend", true) | |
//.text(" a " + weekdayend) | |
if(weekdayend === "weekday") { | |
g.select(".weekdayend") | |
.attr("fill", weekdayColor); | |
} else { | |
g.select(".weekdayend") | |
.attr("fill", weekendColor); | |
} | |
} | |
//delete tributary.inlets | |
if(!tributary.inlets) { | |
d3.json(created_url, function(err, res) { | |
tributary.inlets = res; | |
tributary.inlets.forEach(function(d) { | |
d.createdAt = new Date(d.createdAt) | |
}) | |
tributary.duration = duration; | |
tributary.init(tributary.g); | |
}) | |
} else { | |
tributary.duration = duration; | |
tributary.init(tributary.g); | |
} |
This file contains 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
.cumulative { | |
fill: none; | |
stroke: #000; | |
stroke-width: 3; | |
stroke-linecap: round; | |
stroke-width:18; | |
stroke-opacity: 1; | |
} | |
.cumulative2 { | |
fill: none; | |
stroke-width:11; | |
stroke: #39721A; | |
opacity: 0.3; | |
stroke-linecap: round; | |
} | |
.cumulative3 { | |
fill: none; | |
stroke-width:3; | |
stroke-linecap: round; | |
} | |
.numbertitle { | |
font: Helvetica; | |
font-size: 39px; | |
stroke-opacity: 0.3; | |
stroke-width: 3; | |
} | |
.cumulativeusers { | |
font-size: 30px; | |
} | |
.firstday rect { | |
fill-opacity: 0.6; | |
stroke-opacity: 0.5; | |
} | |
.firstday text { | |
font-size: 30px; | |
} | |
.lastday rect { | |
fill-opacity: 0.6; | |
stroke-opacity: 0.5; | |
} | |
.lastday text { | |
text-anchor: end; | |
font-size: 30px; | |
} | |
.curact { | |
font-size: 25px; | |
text-anchor:middle; | |
} | |
.weekdayend { | |
font-size: 17px; | |
} | |
.curcum { | |
fill-opacity: 0.2; | |
} | |
.ucurcum { | |
fill-opacity: 0.2; | |
} | |
.selected { | |
stroke: #C9FD23; | |
stroke-width: 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment