Skip to content

Instantly share code, notes, and snippets.

@korc
Created August 30, 2014 15:52
Show Gist options
  • Save korc/996a4280dd60b20a086b to your computer and use it in GitHub Desktop.
Save korc/996a4280dd60b20a086b to your computer and use it in GitHub Desktop.
Timeline object using d3js framework
function D3TimeLine(container, attributes, data) {
if(container) this._=container;
for(var k in attributes) this[k]=attributes[k];
if(data) this.data=data;
}
D3TimeLine.prototype={
axisDomainStyle: {"fill-opacity": 0.1},
brushExtentStyle: {"fill-opacity": 0.1},
getDataValue: function(d) {return d.count;},
dateVal: function(val) { return new Date(typeof(val)==="number"?val*1000:val); },
get _() {
return this._container||(this._container=d3.select("body").append("svg"));
},
set _(container) {
this._container=(typeof(container)==="string")?d3.select(container):container;
},
get width() {
return this._width||(this._width||parseInt(window.getComputedStyle(this._.node()).width));
}, set width(val) { this._width=val; },
get height() {
return this._height||(this._height||parseInt(window.getComputedStyle(this._.node()).height));
}, set height(val) { this._height=val; },
get barG() {
return this._bar_g||(this._bar_g=this._.append("g").classed("bars", true));
},
get bars() { return this.barG.selectAll("rect.bar"); },
get labels() { return this.barG.selectAll("text.value"); },
get xAxis() {
return this._xAxis||(this._xAxis=d3.svg.axis().tickSubdivide(true));
},
get xAxisG() {
if(!this._xAxisG) {
this._xAxisG=this._.append("g")
.attr({class:"x axis", transform:"translate(0,"+this.height+")"})
.call(this.xAxis);
this._xAxisG.select("path.domain").style(this.axisDomainStyle);
}
return this._xAxisG;
},
get startDate() {
return this._startDate||(
this._startDate=this.dateVal(Math.min.apply(null, this.data.map(function(d){ return d.time; }))));
}, set startDate(val) { this._startDate=this.dateVal(val); },
get endDate() {
return this._endDate||(
this._endDate=this.dateVal(Math.max.apply(null, this.data.map(function(d){ return d.time; }))));
}, set endDate(val) { this._endDate=this.dateVal(val); },
get maxValue() {
return this._maxValue||(this._maxValue=Math.max.apply(null, this.data.map(this.getDataValue)));
}, set maxValue(val) { this._maxValue=val; },
get brushG() {
if(!this._brushG) {
this._brushG=this._.append("g").classed("brush", true).call(this.brush);
this._brushG.selectAll("rect").attr("height", this.height);
this._brushG.selectAll("rect.extent").style(this.brushExtentStyle);
}
return this._brushG;
},
get brush() {
return this._brush||( this._brush=d3.svg.brush() );
},
get timeScale() {
return this._timeScale||(this._timeScale=
d3.time.scale().range([0, this.width-1]).domain([ this.startDate, this.endDate ]));
},
get heightScale() {
return this._heightScale||(this._heightScale=
d3.scale.log().range([0, this.height]).domain([0.8, Math.max(this.maxValue,1)]));
},
get data() { return this._data; },
set data(data) {
this._data=data;
var self=this;
this._timeScale=this._heightScale=null;
function getDataHeight(d) { return self.heightScale(self.getDataValue(d)); }
function getDataX(d) {return self.timeScale(self.dateVal(d.time));}
var bars=this.bars.data(data).attr({height:getDataHeight, x:getDataX});
bars.enter().append("rect").classed("bar", true)
.attr({width:1, y:0, height:getDataHeight, x:getDataX});
bars.exit().remove();
var labels=this.labels.data(data).attr({y:getDataHeight, x:getDataX}).text(this.getDataValue);
labels.enter().append("text").classed("value", true)
.attr({y:getDataHeight, x:getDataX}).text(this.getDataValue);
labels.exit().remove();
this.xAxisG.call(this.xAxis.scale(this.timeScale).tickSize(-this.height));
this.brushG.call(this.brush.x(this.timeScale));
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment