rickshaw
Version:
Rickshaw is a JavaScript toolkit for creating interactive time series graphs, developed at [Shutterstock](http://www.shutterstock.com)
139 lines (103 loc) • 3.25 kB
JavaScript
Rickshaw.namespace("Rickshaw.Graph.Renderer");
Rickshaw.Graph.Renderer = Rickshaw.Class.create( {
initialize: function(args) {
this.graph = args.graph;
this.tension = args.tension || this.tension;
this.graph.unstacker = this.graph.unstacker || new Rickshaw.Graph.Unstacker( { graph: this.graph } );
this.configure(args);
},
seriesPathFactory: function() {
//implement in subclass
},
seriesStrokeFactory: function() {
// implement in subclass
},
defaults: function() {
return {
tension: 0.8,
strokeWidth: 2,
unstack: true,
padding: { top: 0.01, right: 0, bottom: 0.01, left: 0 },
stroke: false,
fill: false
};
},
domain: function() {
var values = [];
var stackedData = this.graph.stackedData || this.graph.stackData();
var topSeriesData = this.unstack ? stackedData : [ stackedData.slice(-1).shift() ];
topSeriesData.forEach( function(series) {
series.forEach( function(d) {
values.push( d.y + d.y0 );
} );
} );
var xMin = stackedData[0][0].x;
var xMax = stackedData[0][ stackedData[0].length - 1 ].x;
xMin -= (xMax - xMin) * this.padding.left;
xMax += (xMax - xMin) * this.padding.right;
var yMin = this.graph.min === 'auto' ? d3.min( values ) : this.graph.min || 0;
var yMax = this.graph.max || d3.max( values );
if (this.graph.min === 'auto' || yMin < 0) {
yMin -= (yMax - yMin) * this.padding.bottom;
}
if (this.graph.max === undefined) {
yMax += (yMax - yMin) * this.padding.top;
}
return { x: [xMin, xMax], y: [yMin, yMax] };
},
render: function() {
var graph = this.graph;
graph.vis.selectAll('*').remove();
var nodes = graph.vis.selectAll("path")
.data(this.graph.stackedData)
.enter().append("svg:path")
.attr("d", this.seriesPathFactory());
var i = 0;
graph.series.forEach( function(series) {
if (series.disabled) return;
series.path = nodes[0][i++];
this._styleSeries(series);
}, this );
},
_styleSeries: function(series) {
var fill = this.fill ? series.color : 'none';
var stroke = this.stroke ? series.color : 'none';
series.path.setAttribute('fill', fill);
series.path.setAttribute('stroke', stroke);
series.path.setAttribute('stroke-width', this.strokeWidth);
series.path.setAttribute('class', series.className);
},
configure: function(args) {
args = args || {};
Rickshaw.keys(this.defaults()).forEach( function(key) {
if (!args.hasOwnProperty(key)) {
this[key] = this[key] || this.graph[key] || this.defaults()[key];
return;
}
if (typeof this.defaults()[key] == 'object') {
Rickshaw.keys(this.defaults()[key]).forEach( function(k) {
this[key][k] =
args[key][k] !== undefined ? args[key][k] :
this[key][k] !== undefined ? this[key][k] :
this.defaults()[key][k];
}, this );
} else {
this[key] =
args[key] !== undefined ? args[key] :
this[key] !== undefined ? this[key] :
this.graph[key] !== undefined ? this.graph[key] :
this.defaults()[key];
}
}, this );
},
setStrokeWidth: function(strokeWidth) {
if (strokeWidth !== undefined) {
this.strokeWidth = strokeWidth;
}
},
setTension: function(tension) {
if (tension !== undefined) {
this.tension = tension;
}
}
} );