Skip to content

Instantly share code, notes, and snippets.

@enjalot
Created January 26, 2013 00:30
Show Gist options
  • Save enjalot/4639189 to your computer and use it in GitHub Desktop.
Save enjalot/4639189 to your computer and use it in GitHub Desktop.
crossfilter racetrack
//manually updating the font size for now :)
var fontSize = 14;
// pick which editor tab to change the font size for.
var cm = tributary.getCodeEditor("inlet.js")
if(cm) {
var wrap = cm.getWrapperElement();
d3.select(wrap).select(".CodeMirror-scroll")
.style({
"font-size": fontSize + "px",
"line-height": fontSize + "px"
})
cm.refresh();
}
//font
WebFontConfig = {
google: { families: [ 'Roboto:400,100:latin' ] }
};
(function() {
var wf = document.createElement('script');
var dlp = document.location.protocol;
wf.src = ('https:' == dlp ? 'https' : 'http') +
'://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
wf.type = 'text/javascript';
wf.async = 'true';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wf, s);
})();
{"description":"crossfilter racetrack","endpoint":"","display":"svg","public":true,"require":[{"name":"crossfilter","url":"https://raw.github.com/square/crossfilter/master/crossfilter.min.js"}],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"cars.csv":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12},"conf.js":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"tab":"edit","display_percent":0.46399999999999975,"fullscreen":false,"thumbnail":"http://i.imgur.com/JAavU2k.png"}
var margin = {top: 171, right: 130, bottom: 2, left: 168},
extent_width = tributary.sw -20,
width = extent_width - margin.left - margin.right,
height = 645 - margin.top - margin.bottom;
var boxWidth = 10,
boxHeight = 10;
var users_url = 'http://tributary.io/api/users';
var created_url = 'http://tributary.io/api/latest/created';
var trib_inlet = 'http://tributary.io/inlet/';
var iso = d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ").parse;
//https://github.com/square/crossfilter/wiki/API-Reference
var xf = crossfilter();
var users = xf.dimension(function(d) { return d.user.login });
var created = xf.dimension(function(d) { return d.createdAt });
var visits = xf.dimension(function(d) { return d.visits });
var nforks = xf.dimension(function(d) { return d.nforks });
var parent = xf.dimension(function(d) { return d.parent });
// bush setup (slider)
var xscale = d3.scale.linear()
.range([0, width]);
var brush = d3.svg.brush()
.on("brush", function() {
var extent = brush.extent();
extent[1] += 5
created.filterRange(extent);
//WHY ISNT THIS WORKING
var usersGroup = users.group();
usersSorted = usersGroup.all().sort(function(a,b) {
return a.value < b.value ? 1 : -1
})
update_content();
})
.x(xscale)
.extent([.85, 1])
var usersSorted;
var usersList;
//grab the users
function getUsers() {
d3.json(users_url, function(err, res) {
tributary.users = {};
tributary.userList = res;
res.forEach(function(u) {
tributary.users[u.login] = u;
})
//update_content();
})
}
if(!tributary.users) {
getUsers();
}
function init_data() {
xf.add(tributary.inlets);
var usersGroup = users.group();
usersSorted = usersGroup.all().sort(function(a,b) {
return a.value < b.value ? 1 : -1
})
usersList = _.map(usersSorted, function(d) { return d.key });
xscale.domain(d3.extent(created.top(Infinity), function(d) { return d.createdAt }));
//console.log([.85 * xscale.invert(width), xscale.invert(width)])
created.filterRange([.85 * (xscale.invert(width) - xscale.invert(0)) + xscale.invert(0), xscale.invert(width)+5]);
}
//initialize chart containers
var svg = d3.select("svg");
var userBars = svg.append("g")
.classed("userBars", true)
.attr("transform", translate(0, margin.top))
svg.append("g")
.classed("usernames", true)
.attr("transform", translate(width, margin.top))
var box = svg.append("g")
.classed("funky", true)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("transform", translate(margin.left, margin.top));
var barChart = svg.append("g")
.attr({
transform: translate(10, margin.top)
})
box.append("g").attr({
"class": "x axis",
"transform": translate(0, height)
})
box.append("g").attr({
"class": "x2 axis",
"transform": translate(0, -37)
})
var slider = svg.append("g")
.attr("transform", translate(margin.left,92));
brush(slider);
slider.selectAll("rect.background")
.attr("height", 32);
slider.selectAll("g.resize rect")
.attr("height", 32);
slider.selectAll(".extent")
.attr("height", 32);
var x = d3.time.scale().range([0, width]),
x2 = d3.time.scale().range([0, width]);
var countWidth = margin.left - 30;
var countScale = d3.scale.linear()
.range([10, margin.left-30])
var yScale = d3.scale.ordinal()
.rangeBands([0, height], 0)
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(7)
.tickSubdivide(1)
.tickSize(11, 4, 5);
//slider
var xAxis2 = d3.svg.axis()
.scale(x2)
.orient("bottom")
.ticks(7)
.tickSubdivide(2)
.tickSize(11, 4, 5);
function update_content() {
var filteredData = created.top(Infinity)
//TODO clear all filters and return top)
var data = created.filterAll().top(Infinity);
x.domain(d3.extent(filteredData, function(d) { return d.createdAt } ));
x2.domain(d3.extent(data, function(d) { return d.createdAt } ));
yScale.domain(usersList)
svg.select("g.x.axis")
.call(xAxis)
// slider
svg.select("g.x2.axis")
.call(xAxis2)
var bcSel = barChart.selectAll("rect.count")
.data(usersSorted)
bcSel.enter()
.append("rect")
.classed("count", true);
countScale.domain(d3.extent(usersSorted, function(d) { return d.value }));
bcSel.attr({
x: function(d) { return countWidth - countScale(d.value) + 3},
y: function(d) { return yScale(d.key) - boxHeight/2 -1},
width: function(d) { return countScale(d.value) },
height: boxWidth + 4.2
})
.style({"stroke": "none",
"fill": "#4D453D"})
var ubSel = userBars
.selectAll("rect.userbar")
.data(usersList)
ubSel
.enter()
.append("rect")
.classed("userbar", true)
ubSel
.attr({
"y": function(d) { return yScale(d) - boxHeight/2 - 1 },
"x": margin.left - boxWidth/2,
"width": width + margin.left + margin.right + -162,
"height": boxHeight + 4.2
})
var markers = svg.select("g.funky")
.selectAll("a")
.data(filteredData);
markers
.enter()
.append("a")
.attr({
"xlink:href": function(d){ return trib_inlet + d.gistid },
"xlink:title": function(d){ return d.description },
"xlink:show": "new",
"cursor": "pointer"
})
.append("rect")
.classed("marker", true)
markers.select("a rect")
.attr({
"transform": function(d, i) {
var y_loc = yScale(d.user.login) - boxHeight/2 +1;
return translate(x(d.createdAt)- boxWidth/2, y_loc)
},
"width": boxWidth,
"height": boxHeight
})
markers.exit().remove();
var userNames = svg.select("g.usernames")
.selectAll("g.username")
.data(usersList);
userNames
.enter()
.append("g")
.classed("username", true)
.append("a")
.attr({
"xlink:href": function(d){
return tributary.users[d].html_url
},
"xlink:title": function(d){
return compose_stats(d)
},
"xlink:show": "new",
"cursor": "pointer"
})
.append("text")
userNames.select("text")
.text(function(d) { return d })
.attr({
"y": function(d) { return yScale(d) + 3.864 },
"x": margin.left + 25
})
}
if(!tributary.inlets) {
d3.json(created_url, function(err, res) {
tributary.inlets = res;
tributary.inlets.forEach(function(d) { d.createdAt = +iso(d.createdAt) })
xf.add(tributary.inlets);
init_data();
update_content();
})
} else {
init_data();
update_content();
}
function translate(value_x, value_y){
return "translate(" + [value_x, value_y] + ")"
}
function compose_stats(d){
var stat = tributary.users[d];
return "visits: " + (stat.visits || 0) +
" forks: " + (stat.nforks || 0) +
" inlets: " + (stat.inlets || 0)
}
console.log(tributary)
.marker {
fill:#49BDFF;
fill-opacity: 0.33;
stroke: none
}
.userbar {
fill: #FFFFFF;
fill-opacity: 0.74681
}
.count {
fill: #63ACD5;
fill-opacity: 0.736;
stroke: #fff;
stroke-width: 1
shape-rendering: crispEdges;
}
text {
font-size: 0.55328em;
font-family: Roboto;
font-weight: 300;
}
.axis path,
.axis line {
fill: none;
stroke: #919191;
shape-rendering: crispEdges;
}
#panel #file-list {overflow-x: hidden;}
/*
.x.axis path {
display: none;
}
*/
.background{
visibility: visible !important;
fill: #FFFFFF;
}
.extent {
visibility: visible !important;
fill: #84D8F8;
}
.resize rect {
visibility: visible !important;
fill: #888888;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment