Skip to content

Instantly share code, notes, and snippets.

@bobbrez
Created July 12, 2013 16:10
Show Gist options
  • Save bobbrez/5985629 to your computer and use it in GitHub Desktop.
Save bobbrez/5985629 to your computer and use it in GitHub Desktop.
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require modernizr-2.6.2.min
//= require jquery
//= require jquery_ujs
//= require underscore-min
//= require backbone-min
//= require handlebars-1.0.0-rc.4
//= require bootstrap.min
//= require d3/d3.v3.min
//= require d3/d3.legend
//= require d3/queue.v1.min
//= require pickadate-3.1.2/picker
//= require pickadate-3.1.2/picker.date
//= require pickadate-3.1.2/picker.time
//= require_tree .
$(function() {
$('.datepicker').pickadate({
format: 'dd/mm/yyyy'
});
});
var Metric = Backbone.Model.extend({
defaults: {
name: '',
reportPath: '',
values: [],
series: []
},
urlRoot: function() {
return this.get('reportPath');
},
parse: function(response, options) {
this.set({ values: response.values,
series: response.series });
}
});
var MetricDisplay = Backbone.View.extend({
initialize: function() {
this.listenTo(this.model, "change", this.render);
this.model.fetch();
}
});
var BFNDisplay = MetricDisplay.extend({
render: function() {
var total = this.model.get('values').length;
this.$el.find('.data-info').append('<h1>' + total + '</h1>');
return this;
}
});
var BarChartDisplay = MetricDisplay.extend({
margin: { top: 20, right: 20, bottom: 50, left: 60 },
width: 900,
height: 500,
key: 'month',
hover: function(d) {
var text = "";
if(this.key == 'class') {
text += "<h4>Class of " + d.class + "</h4>" + d.data.users + " users out of " + d.data.records + " records.";
} else {
var format = d3.time.format("%b '%y");
text += "<h4>" + format(new Date(d.month)) + "</h4>" + d.data.users + " users.";
}
console.log(self);
$(this.id + ' .data-info').html(text);
},
render: function() {
console.log("Render: " + this.model);
var width = this.width - this.margin.left - this.margin.right;
var height = this.height - this.margin.top - this.margin.bottom;
var xScale = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var yScale = d3.scale.linear()
.rangeRound([height, 0]);
var color = d3.scale.ordinal();
var xAxis = d3.svg.axis()
.scale(xScale)
.ticks(20)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var key = this.key;
var id = this.$el.selector;
var values = this.model.get('values');
var graph = d3.select(id + " .graph").append("svg")
.attr("width", width + this.margin.left + this.margin.right)
.attr("height", height + this.margin.top + this.margin.bottom);
var chart = graph.append("g")
.attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");
color.domain(this.model.get('series'));
if(key == 'class') {
var emptyFilter = false;
values = values.filter(function(d) {
if(d.data.users > 0) {
emptyFilter = true;
}
return emptyFilter;
});
};
values.forEach(function(d) {
var y0 = 0;
d.bars = color.domain().map(function(name) { return { name: name, y0: y0, y1: y0 += +d.data[name]}; });
d.total = d.bars[d.bars.length - 1].y1;
});
xScale.domain(values.map(function(d) { return d[key]; }));
yScale.domain([0, d3.max(values, function(d) { return d.total; })]);
if(key == 'class') {
xAxis.tickValues(values.map( function(d,i) { if(d[key].toString().slice(-1) == "0" ) return d[key]; })
.filter(function (d) { return !!d; } ));
}
if(key == 'month') {
var format = d3.time.format("%b '%y");
xAxis.tickValues(values.map( function(d,i) { return format(new Date(d[key])); }));
}
var xAxisRender = chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.call(yAxis);
var bar = chart.selectAll(".bars")
.data(values)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + xScale(d[key]) + ",0)"; })
.on("mouseover", this.hover);
bar.selectAll("rect")
.data(function(d) { return d.bars; })
.enter().append("rect")
.attr("width", xScale.rangeBand())
.attr("y", function(d) { return yScale(d.y1); })
.attr("height", function(d) { return yScale(d.y0) - yScale(d.y1); })
.attr("class", function(d) { return ("q-" + d.name.toLowerCase()); });
var legend = graph.selectAll(".legend")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 25 + ")"; });
legend.append("rect")
.attr("x", width + this.margin.left - 18)
.attr("width", 18)
.attr("height", 18)
.attr("class", function(d) { return ("q-" + d.toLowerCase()); });
legend.append("text")
.attr("x", width + this.margin.left - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
}
});
function metricFactory(url) {
return new Metric({ reportPath: url });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment