Created
May 23, 2013 03:21
-
-
Save refactornator/5632565 to your computer and use it in GitHub Desktop.
Zoomdata Trend Line A simple example of a trendline that works in Zoomdata. Just copy and paste this code into a new file in the Zoomdata Visualization Studio and press preview. Based on this example by Mike Bostock http://bost.ocks.org/mike/path/. #Zoomdata
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ©2013 Zoomdata, Inc. All Rights Reserved. | |
$(document).ready( function() { | |
$("#timeControls").hide(); | |
$("head").append("<style>"); | |
css = $("head").children(":last"); | |
css.attr({ | |
type: "text/css" | |
}); | |
cssString = '.axis path, .axis line {' + | |
'fill: none;' + | |
'stroke: #000;' + | |
'shape-rendering: crispEdges;' + | |
'}'; | |
css.append(cssString); | |
}); | |
CurrentVisualizationController = (function (){ | |
var n = 60, | |
minValue = 0, | |
maxValue = 1; | |
var Datum = Backbone.Model.extend({ | |
idAttribute: "timestamp", | |
defaults: { | |
} | |
}); | |
var Graph = Backbone.Collection.extend({ | |
model: Datum, | |
comparator: function(d) { | |
return -d.get('timestamp'); | |
} | |
}); | |
var Visualization = Backbone.View.extend({ | |
el: $('#visualization')[0], | |
defaults: { | |
width: $(document).width() - 10, | |
height: $(document).height() - 90 | |
}, | |
initialize: function (options) { | |
_.bindAll(this, 'render', 'update'); | |
this.settings = $.extend({}, this.defaults, options); | |
this.render(); | |
this.listenTo(this.collection, 'add remove change', this.update); | |
}, | |
render: function () { | |
var margin = {top: 120, right: 10, bottom: 20, left: 60}, | |
width = this.settings.width - margin.left - margin.right, | |
height = this.settings.height - margin.top - margin.bottom; | |
var x = this._x = d3.time.scale() | |
.range([0, width]); | |
var y = this._y = d3.scale.linear() | |
.domain([minValue, maxValue]) | |
.range([height, 0]); | |
this._xAxis = d3.svg.axis().scale(this._x).orient("bottom"); | |
this._yAxis = d3.svg.axis().scale(this._y).orient("left"); | |
this._line = d3.svg.line() | |
.interpolate("basis") | |
.x(function(d, i) { return x(d.timestamp); }) | |
.y(function(d, i) { return y(d.metric); }); | |
this._rootSvg = d3.select(this.el).append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
this._rootSvg.append("defs").append("clipPath") | |
.attr("id", "clip") | |
.append("rect") | |
.attr("width", width) | |
.attr("height", height); | |
this._rootSvg.append("svg:g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(this._xAxis); | |
this._rootSvg.append("svg:g") | |
.attr("class", "y axis") | |
.call(this._yAxis); | |
this._path = this._rootSvg.append("g") | |
.attr("clip-path", "url(#clip)") | |
.append("path") | |
.attr("class", "line") | |
.style('fill', 'none') | |
.style('stroke', '#000') | |
.style('stroke-width', '1.5px'); | |
}, | |
update: function (model) { | |
var width = this.settings.width, | |
height = this.settings.height; | |
var maxDate = this.collection.last().get('timestamp'); | |
var minDate = this.collection.first().get('timestamp'); | |
this._x.domain([maxDate, minDate]); | |
this._y.domain([minValue, maxValue]); | |
this._rootSvg.selectAll("g.x.axis") | |
.call(this._xAxis); | |
this._rootSvg.selectAll("g.y.axis") | |
.call(this._yAxis); | |
var x = this._x; | |
this._path | |
.data([this.collection.toJSON()]) | |
.attr("d", this._line) | |
.attr("transform", null) | |
.transition() | |
.duration(500) | |
.ease("linear"); | |
} | |
}); | |
var CustomVisualizationController = function(source, eventManager) { | |
this.source = source; | |
this.state = new State(); | |
this.state.groupBy = '_ts'; | |
this.state.timeTrendStep = "MINUTE"; | |
this.state.timeWindowScale = "3600000"; | |
this.state.comparison = false; | |
this.state.color = new Metric({ "name": "usersentiment", "func": "avg", "label": "", "type": "NUMBER" }); | |
this.state.volume = new Metric({ "name": "price", "func": "sum", "label": "", "type": "NUMBER" }); | |
this.state.limit = n; | |
var _graph = new Graph(); | |
var _visualization = new Visualization({ collection: _graph }); | |
this.processData = function(data) { | |
if (data instanceof Array && data.length > 0) { | |
var arrayToAdd = []; | |
data.forEach(function(dataItem) { | |
var timestamp = parseInt(dataItem.group, 10); | |
if(!dataItem.current.metrics) { | |
return; | |
} | |
var metric = dataItem.current.metrics.price.sum; | |
if(metric > maxValue) { | |
maxValue = metric; | |
} | |
var datum = new Datum({'timestamp': timestamp, 'metric': metric}); | |
_graph.add(datum, {merge: true}); | |
if(_graph.size() > n) { | |
_graph.reset(_graph.first(n)); | |
} | |
}); | |
} | |
}; | |
return this; | |
}; | |
_.extend(CustomVisualizationController.prototype, VisualizationController); | |
return CurrentVisualizationController = CustomVisualizationController; | |
} ()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment