Skip to content

Instantly share code, notes, and snippets.

@enjalot
Created March 16, 2013 07:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enjalot/5175430 to your computer and use it in GitHub Desktop.
Save enjalot/5175430 to your computer and use it in GitHub Desktop.
tributary meta vis
{"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"}
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);
}
.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