Skip to content

Instantly share code, notes, and snippets.

@refactornator
Created May 23, 2013 03:21
Show Gist options
  • Save refactornator/5632565 to your computer and use it in GitHub Desktop.
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
// ©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