epoch-charting
Version:
A general purpose real-time charting library for building beautiful, smooth, and high performance visualizations.
1,838 lines (1,657 loc) • 116 kB
JavaScript
var base, base1, base2, base3;
if (window.Epoch == null) {
window.Epoch = {};
}
if ((base = window.Epoch).Chart == null) {
base.Chart = {};
}
if ((base1 = window.Epoch).Time == null) {
base1.Time = {};
}
if ((base2 = window.Epoch).Util == null) {
base2.Util = {};
}
if ((base3 = window.Epoch).Formats == null) {
base3.Formats = {};
}
Epoch.warn = function(msg) {
return (console.warn || console.log)("Epoch Warning: " + msg);
};
Epoch.exception = function(msg) {
throw "Epoch Error: " + msg;
};
Epoch.TestContext = (function() {
var VOID_METHODS;
VOID_METHODS = ['arc', 'arcTo', 'beginPath', 'bezierCurveTo', 'clearRect', 'clip', 'closePath', 'drawImage', 'fill', 'fillRect', 'fillText', 'moveTo', 'quadraticCurveTo', 'rect', 'restore', 'rotate', 'save', 'scale', 'scrollPathIntoView', 'setLineDash', 'setTransform', 'stroke', 'strokeRect', 'strokeText', 'transform', 'translate', 'lineTo'];
function TestContext() {
var i, len, method;
this._log = [];
for (i = 0, len = VOID_METHODS.length; i < len; i++) {
method = VOID_METHODS[i];
this._makeFauxMethod(method);
}
}
TestContext.prototype._makeFauxMethod = function(name) {
return this[name] = function() {
var arg;
return this._log.push(name + "(" + (((function() {
var i, len, results;
results = [];
for (i = 0, len = arguments.length; i < len; i++) {
arg = arguments[i];
results.push(arg.toString());
}
return results;
}).apply(this, arguments)).join(',')) + ")");
};
};
TestContext.prototype.getImageData = function() {
var arg;
this._log.push("getImageData(" + (((function() {
var i, len, results;
results = [];
for (i = 0, len = arguments.length; i < len; i++) {
arg = arguments[i];
results.push(arg.toString());
}
return results;
}).apply(this, arguments)).join(',')) + ")");
return {
width: 0,
height: 0,
resolution: 1.0,
data: []
};
};
return TestContext;
})();
var ref, typeFunction,
hasProp = {}.hasOwnProperty;
typeFunction = function(objectName) {
return function(v) {
return Object.prototype.toString.call(v) === ("[object " + objectName + "]");
};
};
Epoch.isArray = (ref = Array.isArray) != null ? ref : typeFunction('Array');
Epoch.isObject = typeFunction('Object');
Epoch.isString = typeFunction('String');
Epoch.isFunction = typeFunction('Function');
Epoch.isNumber = typeFunction('Number');
Epoch.isElement = function(v) {
if (typeof HTMLElement !== "undefined" && HTMLElement !== null) {
return v instanceof HTMLElement;
} else {
return (v != null) && Epoch.isObject(v) && v.nodeType === 1 && Epoch.isString(v.nodeName);
}
};
Epoch.isNonEmptyArray = function(v) {
return Epoch.isArray(v) && v.length > 0;
};
Epoch.Util.copy = function(original) {
var copy, k, v;
if (original == null) {
return null;
}
copy = {};
for (k in original) {
if (!hasProp.call(original, k)) continue;
v = original[k];
copy[k] = v;
}
return copy;
};
Epoch.Util.defaults = function(options, defaults) {
var bothAreObjects, def, k, opt, result, v;
result = Epoch.Util.copy(options);
for (k in defaults) {
if (!hasProp.call(defaults, k)) continue;
v = defaults[k];
opt = options[k];
def = defaults[k];
bothAreObjects = Epoch.isObject(opt) && Epoch.isObject(def);
if ((opt != null) && (def != null)) {
if (bothAreObjects && !Epoch.isArray(opt)) {
result[k] = Epoch.Util.defaults(opt, def);
} else {
result[k] = opt;
}
} else if (opt != null) {
result[k] = opt;
} else {
result[k] = def;
}
}
return result;
};
Epoch.Util.formatSI = function(v, fixed, fixIntegers) {
var base, i, label, q, ref1;
if (fixed == null) {
fixed = 1;
}
if (fixIntegers == null) {
fixIntegers = false;
}
if (v < 1000) {
q = v;
if (!((q | 0) === q && !fixIntegers)) {
q = q.toFixed(fixed);
}
return q;
}
ref1 = ['K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
for (i in ref1) {
if (!hasProp.call(ref1, i)) continue;
label = ref1[i];
base = Math.pow(10, ((i | 0) + 1) * 3);
if (v >= base && v < Math.pow(10, ((i | 0) + 2) * 3)) {
q = v / base;
if (!((q % 1) === 0 && !fixIntegers)) {
q = q.toFixed(fixed);
}
return q + " " + label;
}
}
};
Epoch.Util.formatBytes = function(v, fixed, fix_integers) {
var base, i, label, q, ref1;
if (fixed == null) {
fixed = 1;
}
if (fix_integers == null) {
fix_integers = false;
}
if (v < 1024) {
q = v;
if (!((q % 1) === 0 && !fix_integers)) {
q = q.toFixed(fixed);
}
return q + " B";
}
ref1 = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
for (i in ref1) {
if (!hasProp.call(ref1, i)) continue;
label = ref1[i];
base = Math.pow(1024, (i | 0) + 1);
if (v >= base && v < Math.pow(1024, (i | 0) + 2)) {
q = v / base;
if (!((q % 1) === 0 && !fix_integers)) {
q = q.toFixed(fixed);
}
return q + " " + label;
}
}
};
Epoch.Util.dasherize = function(str) {
return Epoch.Util.trim(str).replace("\n", '').replace(/\s+/g, '-').toLowerCase();
};
Epoch.Util.domain = function(layers, key) {
var domain, entry, j, l, layer, len, len1, ref1, set;
if (key == null) {
key = 'x';
}
set = {};
domain = [];
for (j = 0, len = layers.length; j < len; j++) {
layer = layers[j];
ref1 = layer.values;
for (l = 0, len1 = ref1.length; l < len1; l++) {
entry = ref1[l];
if (set[entry[key]] != null) {
continue;
}
domain.push(entry[key]);
set[entry[key]] = true;
}
}
return domain;
};
Epoch.Util.trim = function(string) {
if (!Epoch.isString(string)) {
return null;
}
return string.replace(/^\s+/g, '').replace(/\s+$/g, '');
};
Epoch.Util.getComputedStyle = function(element, pseudoElement) {
if (Epoch.isFunction(window.getComputedStyle)) {
return window.getComputedStyle(element, pseudoElement);
} else if (element.currentStyle != null) {
return element.currentStyle;
}
};
Epoch.Util.toRGBA = function(color, opacity) {
var all, b, g, parts, r, result, v;
if ((parts = color.match(/^rgba\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*[0-9\.]+\)/))) {
all = parts[0], r = parts[1], g = parts[2], b = parts[3];
result = "rgba(" + r + "," + g + "," + b + "," + opacity + ")";
} else if ((v = d3.rgb(color))) {
result = "rgba(" + v.r + "," + v.g + "," + v.b + "," + opacity + ")";
}
return result;
};
Epoch.Util.getContext = function(node, type) {
if (type == null) {
type = '2d';
}
return node.getContext(type);
};
Epoch.Events = (function() {
function Events() {
this._events = {};
}
Events.prototype.on = function(name, callback) {
var base1;
if (callback == null) {
return;
}
if ((base1 = this._events)[name] == null) {
base1[name] = [];
}
return this._events[name].push(callback);
};
Events.prototype.onAll = function(map) {
var callback, name, results;
if (!Epoch.isObject(map)) {
return;
}
results = [];
for (name in map) {
if (!hasProp.call(map, name)) continue;
callback = map[name];
results.push(this.on(name, callback));
}
return results;
};
Events.prototype.off = function(name, callback) {
var i, results;
if (!Epoch.isArray(this._events[name])) {
return;
}
if (callback == null) {
return delete this._events[name];
}
results = [];
while ((i = this._events[name].indexOf(callback)) >= 0) {
results.push(this._events[name].splice(i, 1));
}
return results;
};
Events.prototype.offAll = function(mapOrList) {
var callback, j, len, name, results, results1;
if (Epoch.isArray(mapOrList)) {
results = [];
for (j = 0, len = mapOrList.length; j < len; j++) {
name = mapOrList[j];
results.push(this.off(name));
}
return results;
} else if (Epoch.isObject(mapOrList)) {
results1 = [];
for (name in mapOrList) {
if (!hasProp.call(mapOrList, name)) continue;
callback = mapOrList[name];
results1.push(this.off(name, callback));
}
return results1;
}
};
Events.prototype.trigger = function(name) {
var args, callback, fn, i, j, len, ref1, results;
if (this._events[name] == null) {
return;
}
args = (function() {
var j, ref1, results;
results = [];
for (i = j = 1, ref1 = arguments.length; 1 <= ref1 ? j < ref1 : j > ref1; i = 1 <= ref1 ? ++j : --j) {
results.push(arguments[i]);
}
return results;
}).apply(this, arguments);
ref1 = this._events[name];
results = [];
for (j = 0, len = ref1.length; j < len; j++) {
callback = ref1[j];
fn = null;
if (Epoch.isString(callback)) {
fn = this[callback];
} else if (Epoch.isFunction(callback)) {
fn = callback;
}
if (fn == null) {
Epoch.exception("Callback for event '" + name + "' is not a function or reference to a method.");
}
results.push(fn.apply(this, args));
}
return results;
};
return Events;
})();
Epoch.Util.flatten = function(multiarray) {
var array, item, j, l, len, len1, result;
if (!Array.isArray(multiarray)) {
throw new Error('Epoch.Util.flatten only accepts arrays');
}
result = [];
for (j = 0, len = multiarray.length; j < len; j++) {
array = multiarray[j];
if (Array.isArray(array)) {
for (l = 0, len1 = array.length; l < len1; l++) {
item = array[l];
result.push(item);
}
} else {
result.push(array);
}
}
return result;
};
d3.selection.prototype.width = function(value) {
if ((value != null) && Epoch.isString(value)) {
return this.style('width', value);
} else if ((value != null) && Epoch.isNumber(value)) {
return this.style('width', value + "px");
} else {
return +Epoch.Util.getComputedStyle(this.node(), null).width.replace('px', '');
}
};
d3.selection.prototype.height = function(value) {
if ((value != null) && Epoch.isString(value)) {
return this.style('height', value);
} else if ((value != null) && Epoch.isNumber(value)) {
return this.style('height', value + "px");
} else {
return +Epoch.Util.getComputedStyle(this.node(), null).height.replace('px', '');
}
};
var d3Seconds;
Epoch.Formats.regular = function(d) {
return d;
};
Epoch.Formats.si = function(d) {
return Epoch.Util.formatSI(d);
};
Epoch.Formats.percent = function(d) {
return (d * 100).toFixed(1) + "%";
};
Epoch.Formats.seconds = function(t) {
return d3Seconds(new Date(t * 1000));
};
d3Seconds = d3.time.format('%I:%M:%S %p');
Epoch.Formats.bytes = function(d) {
return Epoch.Util.formatBytes(d);
};
var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Epoch.Chart.Base = (function(superClass) {
var defaults, optionListeners;
extend(Base, superClass);
defaults = {
width: 320,
height: 240,
dataFormat: null
};
optionListeners = {
'option:width': 'dimensionsChanged',
'option:height': 'dimensionsChanged',
'layer:shown': 'layerChanged',
'layer:hidden': 'layerChanged'
};
function Base(options1) {
this.options = options1 != null ? options1 : {};
Base.__super__.constructor.call(this);
if (this.options.model) {
if (this.options.model.hasData() != null) {
this.setData(this.options.model.getData(this.options.type, this.options.dataFormat));
} else {
this.setData(this.options.data || []);
}
this.options.model.on('data:updated', (function(_this) {
return function() {
return _this.setDataFromModel();
};
})(this));
} else {
this.setData(this.options.data || []);
}
if (this.options.el != null) {
this.el = d3.select(this.options.el);
}
this.width = this.options.width;
this.height = this.options.height;
if (this.el != null) {
if (this.width == null) {
this.width = this.el.width();
}
if (this.height == null) {
this.height = this.el.height();
}
} else {
if (this.width == null) {
this.width = defaults.width;
}
if (this.height == null) {
this.height = defaults.height;
}
this.el = d3.select(document.createElement('DIV')).attr('width', this.width).attr('height', this.height);
}
this.onAll(optionListeners);
}
Base.prototype._getAllOptions = function() {
return Epoch.Util.defaults({}, this.options);
};
Base.prototype._getOption = function(key) {
var parts, scope, subkey;
parts = key.split('.');
scope = this.options;
while (parts.length && (scope != null)) {
subkey = parts.shift();
scope = scope[subkey];
}
return scope;
};
Base.prototype._setOption = function(key, value) {
var parts, scope, subkey;
parts = key.split('.');
scope = this.options;
while (parts.length) {
subkey = parts.shift();
if (parts.length === 0) {
scope[subkey] = arguments[1];
this.trigger("option:" + arguments[0]);
return;
}
if (scope[subkey] == null) {
scope[subkey] = {};
}
scope = scope[subkey];
}
};
Base.prototype._setManyOptions = function(options, prefix) {
var key, results, value;
if (prefix == null) {
prefix = '';
}
results = [];
for (key in options) {
if (!hasProp.call(options, key)) continue;
value = options[key];
if (Epoch.isObject(value)) {
results.push(this._setManyOptions(value, (prefix + key) + "."));
} else {
results.push(this._setOption(prefix + key, value));
}
}
return results;
};
Base.prototype.option = function() {
if (arguments.length === 0) {
return this._getAllOptions();
} else if (arguments.length === 1 && Epoch.isString(arguments[0])) {
return this._getOption(arguments[0]);
} else if (arguments.length === 2 && Epoch.isString(arguments[0])) {
return this._setOption(arguments[0], arguments[1]);
} else if (arguments.length === 1 && Epoch.isObject(arguments[0])) {
return this._setManyOptions(arguments[0]);
}
};
Base.prototype.setDataFromModel = function() {
var prepared;
prepared = this._prepareData(this.options.model.getData(this.options.type, this.options.dataFormat));
this.data = this._annotateLayers(prepared);
return this.draw();
};
Base.prototype.setData = function(data, options) {
var prepared;
if (options == null) {
options = {};
}
prepared = this._prepareData((this.rawData = this._formatData(data)));
return this.data = this._annotateLayers(prepared);
};
Base.prototype._prepareData = function(data) {
return data;
};
Base.prototype._formatData = function(data) {
return Epoch.Data.formatData(data, this.options.type, this.options.dataFormat);
};
Base.prototype._annotateLayers = function(data) {
var category, classes, i, layer, len;
category = 1;
for (i = 0, len = data.length; i < len; i++) {
layer = data[i];
classes = ['layer'];
classes.push("category" + category);
layer.category = category;
layer.visible = true;
if (layer.label != null) {
classes.push(Epoch.Util.dasherize(layer.label));
}
layer.className = classes.join(' ');
category++;
}
return data;
};
Base.prototype._findLayer = function(labelOrIndex) {
var i, index, l, layer, len, ref;
layer = null;
if (Epoch.isString(labelOrIndex)) {
ref = this.data;
for (i = 0, len = ref.length; i < len; i++) {
l = ref[i];
if (l.label === labelOrIndex) {
layer = l;
break;
}
}
} else if (Epoch.isNumber(labelOrIndex)) {
index = parseInt(labelOrIndex);
if (!(index < 0 || index >= this.data.length)) {
layer = this.data[index];
}
}
return layer;
};
Base.prototype.showLayer = function(labelOrIndex) {
var layer;
if (!(layer = this._findLayer(labelOrIndex))) {
return;
}
if (layer.visible) {
return;
}
layer.visible = true;
return this.trigger('layer:shown');
};
Base.prototype.hideLayer = function(labelOrIndex) {
var layer;
if (!(layer = this._findLayer(labelOrIndex))) {
return;
}
if (!layer.visible) {
return;
}
layer.visible = false;
return this.trigger('layer:hidden');
};
Base.prototype.toggleLayer = function(labelOrIndex) {
var layer;
if (!(layer = this._findLayer(labelOrIndex))) {
return;
}
layer.visible = !layer.visible;
if (layer.visible) {
return this.trigger('layer:shown');
} else {
return this.trigger('layer:hidden');
}
};
Base.prototype.isLayerVisible = function(labelOrIndex) {
var layer;
if (!(layer = this._findLayer(labelOrIndex))) {
return null;
}
return layer.visible;
};
Base.prototype.getVisibleLayers = function() {
return this.data.filter(function(layer) {
return layer.visible;
});
};
Base.prototype.update = function(data, draw) {
if (draw == null) {
draw = true;
}
this.setData(data);
if (draw) {
return this.draw();
}
};
Base.prototype.draw = function() {
return this.trigger('draw');
};
Base.prototype._getScaleDomain = function(givenDomain) {
var layers, maxFn, minFn, values;
if (Array.isArray(givenDomain)) {
return givenDomain;
}
if (Epoch.isString(givenDomain)) {
layers = this.getVisibleLayers().filter(function(l) {
return l.range === givenDomain;
}).map(function(l) {
return l.values;
});
if ((layers != null) && layers.length) {
values = Epoch.Util.flatten(layers).map(function(d) {
return d.y;
});
minFn = function(memo, curr) {
if (curr < memo) {
return curr;
} else {
return memo;
}
};
maxFn = function(memo, curr) {
if (curr > memo) {
return curr;
} else {
return memo;
}
};
return [values.reduce(minFn, values[0]), values.reduce(maxFn, values[0])];
}
}
if (Array.isArray(this.options.range)) {
return this.options.range;
} else if (this.options.range && Array.isArray(this.options.range.left)) {
return this.options.range.left;
} else if (this.options.range && Array.isArray(this.options.range.right)) {
return this.options.range.right;
} else {
return this.extent(function(d) {
return d.y;
});
}
};
Base.prototype.extent = function(cmp) {
return [
d3.min(this.getVisibleLayers(), function(layer) {
return d3.min(layer.values, cmp);
}), d3.max(this.getVisibleLayers(), function(layer) {
return d3.max(layer.values, cmp);
})
];
};
Base.prototype.dimensionsChanged = function() {
this.width = this.option('width') || this.width;
this.height = this.option('height') || this.height;
this.el.width(this.width);
return this.el.height(this.height);
};
Base.prototype.layerChanged = function() {
return this.draw();
};
return Base;
})(Epoch.Events);
Epoch.Chart.SVG = (function(superClass) {
extend(SVG, superClass);
function SVG(options1) {
this.options = options1 != null ? options1 : {};
SVG.__super__.constructor.call(this, this.options);
if (this.el != null) {
this.svg = this.el.append('svg');
} else {
this.svg = d3.select(document.createElement('svg'));
}
this.svg.attr({
xmlns: 'http://www.w3.org/2000/svg',
width: this.width,
height: this.height
});
}
SVG.prototype.dimensionsChanged = function() {
SVG.__super__.dimensionsChanged.call(this);
return this.svg.attr('width', this.width).attr('height', this.height);
};
return SVG;
})(Epoch.Chart.Base);
Epoch.Chart.Canvas = (function(superClass) {
extend(Canvas, superClass);
function Canvas(options1) {
this.options = options1 != null ? options1 : {};
Canvas.__super__.constructor.call(this, this.options);
if (this.options.pixelRatio != null) {
this.pixelRatio = this.options.pixelRatio;
} else if (window.devicePixelRatio != null) {
this.pixelRatio = window.devicePixelRatio;
} else {
this.pixelRatio = 1;
}
this.canvas = d3.select(document.createElement('CANVAS'));
this.canvas.style({
'width': this.width + "px",
'height': this.height + "px"
});
this.canvas.attr({
width: this.getWidth(),
height: this.getHeight()
});
if (this.el != null) {
this.el.node().appendChild(this.canvas.node());
}
this.ctx = Epoch.Util.getContext(this.canvas.node());
}
Canvas.prototype.getWidth = function() {
return this.width * this.pixelRatio;
};
Canvas.prototype.getHeight = function() {
return this.height * this.pixelRatio;
};
Canvas.prototype.clear = function() {
return this.ctx.clearRect(0, 0, this.getWidth(), this.getHeight());
};
Canvas.prototype.getStyles = function(selector) {
return Epoch.QueryCSS.getStyles(selector, this.el);
};
Canvas.prototype.dimensionsChanged = function() {
Canvas.__super__.dimensionsChanged.call(this);
this.canvas.style({
'width': this.width + "px",
'height': this.height + "px"
});
return this.canvas.attr({
width: this.getWidth(),
height: this.getHeight()
});
};
Canvas.prototype.redraw = function() {
Epoch.QueryCSS.purge();
return this.draw();
};
return Canvas;
})(Epoch.Chart.Base);
var QueryCSS;
QueryCSS = (function() {
var CONTAINER_HASH_ATTR, PUT_EXPR, REFERENCE_CONTAINER_ID, containerCount, logging, nextContainerId, put;
function QueryCSS() {}
REFERENCE_CONTAINER_ID = '_canvas_css_reference';
CONTAINER_HASH_ATTR = 'data-epoch-container-id';
containerCount = 0;
nextContainerId = function() {
return "epoch-container-" + (containerCount++);
};
PUT_EXPR = /^([^#. ]+)?(#[^. ]+)?(\.[^# ]+)?$/;
logging = false;
put = function(selector) {
var classNames, element, id, match, tag, whole;
match = selector.match(PUT_EXPR);
if (match == null) {
return Epoch.error('Query CSS cannot match given selector: ' + selector);
}
whole = match[0], tag = match[1], id = match[2], classNames = match[3];
tag = (tag != null ? tag : 'div').toUpperCase();
element = document.createElement(tag);
if (id != null) {
element.id = id.substr(1);
}
if (classNames != null) {
element.className = classNames.substr(1).replace(/\./g, ' ');
}
return element;
};
QueryCSS.log = function(b) {
return logging = b;
};
QueryCSS.cache = {};
QueryCSS.styleList = ['fill', 'stroke', 'stroke-width'];
QueryCSS.container = null;
QueryCSS.purge = function() {
return QueryCSS.cache = {};
};
QueryCSS.getContainer = function() {
var container;
if (QueryCSS.container != null) {
return QueryCSS.container;
}
container = document.createElement('DIV');
container.id = REFERENCE_CONTAINER_ID;
document.body.appendChild(container);
return QueryCSS.container = d3.select(container);
};
QueryCSS.hash = function(selector, container) {
var containerId;
containerId = container.attr(CONTAINER_HASH_ATTR);
if (containerId == null) {
containerId = nextContainerId();
container.attr(CONTAINER_HASH_ATTR, containerId);
}
return containerId + "__" + selector;
};
QueryCSS.getStyles = function(selector, container) {
var cache, cacheKey, el, element, i, j, k, len, len1, len2, name, parent, parentNode, parents, ref, ref1, ref2, root, sel, selectorList, styles, subSelector;
cacheKey = QueryCSS.hash(selector, container);
cache = QueryCSS.cache[cacheKey];
if (cache != null) {
return cache;
}
parents = [];
parentNode = container.node().parentNode;
while ((parentNode != null) && parentNode.nodeName.toLowerCase() !== 'body') {
parents.unshift(parentNode);
parentNode = parentNode.parentNode;
}
parents.push(container.node());
selectorList = [];
for (i = 0, len = parents.length; i < len; i++) {
element = parents[i];
sel = element.nodeName.toLowerCase();
if ((element.id != null) && element.id.length > 0) {
sel += '#' + element.id;
}
if ((element.className != null) && element.className.length > 0) {
sel += '.' + Epoch.Util.trim(element.className).replace(/\s+/g, '.');
}
selectorList.push(sel);
}
selectorList.push('svg');
ref1 = Epoch.Util.trim(selector).split(/\s+/);
for (j = 0, len1 = ref1.length; j < len1; j++) {
subSelector = ref1[j];
selectorList.push(subSelector);
}
if (logging) {
console.log(selectorList);
}
parent = root = put(selectorList.shift());
while (selectorList.length) {
el = put(selectorList.shift());
parent.appendChild(el);
parent = el;
}
if (logging) {
console.log(root);
}
QueryCSS.getContainer().node().appendChild(root);
ref = d3.select('#' + REFERENCE_CONTAINER_ID + ' ' + selector);
styles = {};
ref2 = QueryCSS.styleList;
for (k = 0, len2 = ref2.length; k < len2; k++) {
name = ref2[k];
styles[name] = ref.style(name);
}
QueryCSS.cache[cacheKey] = styles;
QueryCSS.getContainer().html('');
return styles;
};
return QueryCSS;
})();
Epoch.QueryCSS = QueryCSS;
var applyLayerLabel, base,
hasProp = {}.hasOwnProperty,
slice = [].slice;
if (Epoch.Data == null) {
Epoch.Data = {};
}
if ((base = Epoch.Data).Format == null) {
base.Format = {};
}
applyLayerLabel = function(layer, options, i, keys) {
var autoLabels, keyLabels, label, labels, ref;
if (keys == null) {
keys = [];
}
ref = [options.labels, options.autoLabels, options.keyLabels], labels = ref[0], autoLabels = ref[1], keyLabels = ref[2];
if ((labels != null) && Epoch.isArray(labels) && labels.length > i) {
layer.label = labels[i];
} else if (keyLabels && keys.length > i) {
layer.label = keys[i];
} else if (autoLabels) {
label = [];
while (i >= 0) {
label.push(String.fromCharCode(65 + (i % 26)));
i -= 26;
}
layer.label = label.join('');
}
return layer;
};
Epoch.Data.Format.array = (function() {
var buildLayers, defaultOptions, format, formatBasicPlot, formatHeatmap, formatPie, formatTimePlot;
defaultOptions = {
x: function(d, i) {
return i;
},
y: function(d, i) {
return d;
},
time: function(d, i, startTime) {
return parseInt(startTime) + parseInt(i);
},
type: 'area',
autoLabels: false,
labels: [],
startTime: parseInt(new Date().getTime() / 1000)
};
buildLayers = function(data, options, mapFn) {
var i, result, series;
result = [];
if (Epoch.isArray(data[0])) {
for (i in data) {
if (!hasProp.call(data, i)) continue;
series = data[i];
result.push(applyLayerLabel({
values: series.map(mapFn)
}, options, parseInt(i)));
}
} else {
result.push(applyLayerLabel({
values: data.map(mapFn)
}, options, 0));
}
return result;
};
formatBasicPlot = function(data, options) {
return buildLayers(data, options, function(d, i) {
return {
x: options.x(d, i),
y: options.y(d, i)
};
});
};
formatTimePlot = function(data, options) {
return buildLayers(data, options, function(d, i) {
return {
time: options.time(d, i, options.startTime),
y: options.y(d, i)
};
});
};
formatHeatmap = function(data, options) {
return buildLayers(data, options, function(d, i) {
return {
time: options.time(d, i, options.startTime),
histogram: d
};
});
};
formatPie = function(data, options) {
var i, result, v;
result = [];
for (i in data) {
if (!hasProp.call(data, i)) continue;
v = data[i];
if (!Epoch.isNumber(data[0])) {
return [];
}
result.push(applyLayerLabel({
value: v
}, options, i));
}
return result;
};
format = function(data, options) {
var opt;
if (data == null) {
data = [];
}
if (options == null) {
options = {};
}
if (!Epoch.isNonEmptyArray(data)) {
return [];
}
opt = Epoch.Util.defaults(options, defaultOptions);
if (opt.type === 'time.heatmap') {
return formatHeatmap(data, opt);
} else if (opt.type.match(/^time\./)) {
return formatTimePlot(data, opt);
} else if (opt.type === 'pie') {
return formatPie(data, opt);
} else {
return formatBasicPlot(data, opt);
}
};
format.entry = function(datum, options) {
var d, data, k, layer, len, opt, ref, results;
if (options == null) {
options = {};
}
if (options.type === 'time.gauge') {
if (datum == null) {
return 0;
}
opt = Epoch.Util.defaults(options, defaultOptions);
d = Epoch.isArray(datum) ? datum[0] : datum;
return opt.y(d, 0);
}
if (datum == null) {
return [];
}
if (options.startTime == null) {
options.startTime = parseInt(new Date().getTime() / 1000);
}
if (Epoch.isArray(datum)) {
data = datum.map(function(d) {
return [d];
});
} else {
data = [datum];
}
ref = format(data, options);
results = [];
for (k = 0, len = ref.length; k < len; k++) {
layer = ref[k];
results.push(layer.values[0]);
}
return results;
};
return format;
})();
Epoch.Data.Format.tuple = (function() {
var buildLayers, defaultOptions, format;
defaultOptions = {
x: function(d, i) {
return d;
},
y: function(d, i) {
return d;
},
time: function(d, i) {
return d;
},
type: 'area',
autoLabels: false,
labels: []
};
buildLayers = function(data, options, mapFn) {
var i, result, series;
if (!Epoch.isArray(data[0])) {
return [];
}
result = [];
if (Epoch.isArray(data[0][0])) {
for (i in data) {
if (!hasProp.call(data, i)) continue;
series = data[i];
result.push(applyLayerLabel({
values: series.map(mapFn)
}, options, parseInt(i)));
}
} else {
result.push(applyLayerLabel({
values: data.map(mapFn)
}, options, 0));
}
return result;
};
format = function(data, options) {
var opt;
if (data == null) {
data = [];
}
if (options == null) {
options = {};
}
if (!Epoch.isNonEmptyArray(data)) {
return [];
}
opt = Epoch.Util.defaults(options, defaultOptions);
if (opt.type === 'pie' || opt.type === 'time.heatmap' || opt.type === 'time.gauge') {
return [];
} else if (opt.type.match(/^time\./)) {
return buildLayers(data, opt, function(d, i) {
return {
time: opt.time(d[0], parseInt(i)),
y: opt.y(d[1], parseInt(i))
};
});
} else {
return buildLayers(data, opt, function(d, i) {
return {
x: opt.x(d[0], parseInt(i)),
y: opt.y(d[1], parseInt(i))
};
});
}
};
format.entry = function(datum, options) {
var data, k, layer, len, ref, results;
if (options == null) {
options = {};
}
if (datum == null) {
return [];
}
if (options.startTime == null) {
options.startTime = parseInt(new Date().getTime() / 1000);
}
if (Epoch.isArray(datum) && Epoch.isArray(datum[0])) {
data = datum.map(function(d) {
return [d];
});
} else {
data = [datum];
}
ref = format(data, options);
results = [];
for (k = 0, len = ref.length; k < len; k++) {
layer = ref[k];
results.push(layer.values[0]);
}
return results;
};
return format;
})();
Epoch.Data.Format.keyvalue = (function() {
var buildLayers, defaultOptions, format, formatBasicPlot, formatTimePlot;
defaultOptions = {
type: 'area',
x: function(d, i) {
return parseInt(i);
},
y: function(d, i) {
return d;
},
time: function(d, i, startTime) {
return parseInt(startTime) + parseInt(i);
},
labels: [],
autoLabels: false,
keyLabels: true,
startTime: parseInt(new Date().getTime() / 1000)
};
buildLayers = function(data, keys, options, mapFn) {
var d, i, j, key, result, values;
result = [];
for (j in keys) {
if (!hasProp.call(keys, j)) continue;
key = keys[j];
values = [];
for (i in data) {
if (!hasProp.call(data, i)) continue;
d = data[i];
values.push(mapFn(d, key, parseInt(i)));
}
result.push(applyLayerLabel({
values: values
}, options, parseInt(j), keys));
}
return result;
};
formatBasicPlot = function(data, keys, options) {
return buildLayers(data, keys, options, function(d, key, i) {
var x;
if (Epoch.isString(options.x)) {
x = d[options.x];
} else {
x = options.x(d, parseInt(i));
}
return {
x: x,
y: options.y(d[key], parseInt(i))
};
});
};
formatTimePlot = function(data, keys, options, rangeName) {
if (rangeName == null) {
rangeName = 'y';
}
return buildLayers(data, keys, options, function(d, key, i) {
var value;
if (Epoch.isString(options.time)) {
value = {
time: d[options.time]
};
} else {
value = {
time: options.time(d, parseInt(i), options.startTime)
};
}
value[rangeName] = options.y(d[key], parseInt(i));
return value;
});
};
format = function(data, keys, options) {
var opt;
if (data == null) {
data = [];
}
if (keys == null) {
keys = [];
}
if (options == null) {
options = {};
}
if (!(Epoch.isNonEmptyArray(data) && Epoch.isNonEmptyArray(keys))) {
return [];
}
opt = Epoch.Util.defaults(options, defaultOptions);
if (opt.type === 'pie' || opt.type === 'time.gauge') {
return [];
} else if (opt.type === 'time.heatmap') {
return formatTimePlot(data, keys, opt, 'histogram');
} else if (opt.type.match(/^time\./)) {
return formatTimePlot(data, keys, opt);
} else {
return formatBasicPlot(data, keys, opt);
}
};
format.entry = function(datum, keys, options) {
var k, layer, len, ref, results;
if (keys == null) {
keys = [];
}
if (options == null) {
options = {};
}
if (!((datum != null) && Epoch.isNonEmptyArray(keys))) {
return [];
}
if (options.startTime == null) {
options.startTime = parseInt(new Date().getTime() / 1000);
}
ref = format([datum], keys, options);
results = [];
for (k = 0, len = ref.length; k < len; k++) {
layer = ref[k];
results.push(layer.values[0]);
}
return results;
};
return format;
})();
Epoch.data = function() {
var args, formatFn, formatter;
formatter = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
if ((formatFn = Epoch.Data.Format[formatter]) == null) {
return [];
}
return formatFn.apply(formatFn, args);
};
Epoch.Data.formatData = function(data, type, dataFormat) {
var a, args, k, len, opts, ref;
if (data == null) {
data = [];
}
if (!Epoch.isNonEmptyArray(data)) {
return data;
}
if (Epoch.isString(dataFormat)) {
opts = {
type: type
};
return Epoch.data(dataFormat, data, opts);
}
if (!Epoch.isObject(dataFormat)) {
return data;
}
if (!((dataFormat.name != null) && Epoch.isString(dataFormat.name))) {
return data;
}
if (Epoch.Data.Format[dataFormat.name] == null) {
return data;
}
args = [dataFormat.name, data];
if ((dataFormat["arguments"] != null) && Epoch.isArray(dataFormat["arguments"])) {
ref = dataFormat["arguments"];
for (k = 0, len = ref.length; k < len; k++) {
a = ref[k];
args.push(a);
}
}
if (dataFormat.options != null) {
opts = dataFormat.options;
if (type != null) {
if (opts.type == null) {
opts.type = type;
}
}
args.push(opts);
} else if (type != null) {
args.push({
type: type
});
}
return Epoch.data.apply(Epoch.data, args);
};
Epoch.Data.formatEntry = function(datum, type, format) {
var a, args, dataFormat, entry, k, len, opts, ref;
if (format == null) {
return datum;
}
if (Epoch.isString(format)) {
opts = {
type: type
};
return Epoch.Data.Format[format].entry(datum, opts);
}
if (!Epoch.isObject(format)) {
return datum;
}
if (!((format.name != null) && Epoch.isString(format.name))) {
return datum;
}
if (Epoch.Data.Format[format.name] == null) {
return datum;
}
dataFormat = Epoch.Util.defaults(format, {});
args = [datum];
if ((dataFormat["arguments"] != null) && Epoch.isArray(dataFormat["arguments"])) {
ref = dataFormat["arguments"];
for (k = 0, len = ref.length; k < len; k++) {
a = ref[k];
args.push(a);
}
}
if (dataFormat.options != null) {
opts = dataFormat.options;
opts.type = type;
args.push(opts);
} else if (type != null) {
args.push({
type: type
});
}
entry = Epoch.Data.Format[dataFormat.name].entry;
return entry.apply(entry, args);
};
var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Epoch.Model = (function(superClass) {
var defaults;
extend(Model, superClass);
defaults = {
dataFormat: null
};
function Model(options) {
if (options == null) {
options = {};
}
Model.__super__.constructor.call(this);
options = Epoch.Util.defaults(options, defaults);
this.dataFormat = options.dataFormat;
this.data = options.data;
this.loading = false;
}
Model.prototype.setData = function(data) {
this.data = data;
return this.trigger('data:updated');
};
Model.prototype.push = function(entry) {
this.entry = entry;
return this.trigger('data:push');
};
Model.prototype.hasData = function() {
return this.data != null;
};
Model.prototype.getData = function(type, dataFormat) {
if (dataFormat == null) {
dataFormat = this.dataFormat;
}
return Epoch.Data.formatData(this.data, type, dataFormat);
};
Model.prototype.getNext = function(type, dataFormat) {
if (dataFormat == null) {
dataFormat = this.dataFormat;
}
return Epoch.Data.formatEntry(this.entry, type, dataFormat);
};
return Model;
})(Epoch.Events);
var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Epoch.Chart.Plot = (function(superClass) {
var defaultAxisMargins, defaults, optionListeners;
extend(Plot, superClass);
defaults = {
domain: null,
range: null,
axes: ['left', 'bottom'],
ticks: {
top: 14,
bottom: 14,
left: 5,
right: 5
},
tickFormats: {
top: Epoch.Formats.regular,
bottom: Epoch.Formats.regular,
left: Epoch.Formats.si,
right: Epoch.Formats.si
}
};
defaultAxisMargins = {
top: 25,
right: 50,
bottom: 25,
left: 50
};
optionListeners = {
'option:margins.top': 'marginsChanged',
'option:margins.right': 'marginsChanged',
'option:margins.bottom': 'marginsChanged',
'option:margins.left': 'marginsChanged',
'option:axes': 'axesChanged',
'option:ticks.top': 'ticksChanged',
'option:ticks.right': 'ticksChanged',
'option:ticks.bottom': 'ticksChanged',
'option:ticks.left': 'ticksChanged',
'option:tickFormats.top': 'tickFormatsChanged',
'option:tickFormats.right': 'tickFormatsChanged',
'option:tickFormats.bottom': 'tickFormatsChanged',
'option:tickFormats.left': 'tickFormatsChanged',
'option:domain': 'domainChanged',
'option:range': 'rangeChanged'
};
function Plot(options) {
var givenMargins, i, len, pos, ref;
this.options = options != null ? options : {};
givenMargins = Epoch.Util.copy(this.options.margins) || {};
Plot.__super__.constructor.call(this, this.options = Epoch.Util.defaults(this.options, defaults));
this.margins = {};
ref = ['top', 'right', 'bottom', 'left'];
for (i = 0, len = ref.length; i < len; i++) {
pos = ref[i];
this.margins[pos] = (this.options.margins != null) && (this.options.margins[pos] != null) ? this.options.margins[pos] : this.hasAxis(pos) ? defaultAxisMargins[pos] : 6;
}
this.g = this.svg.append("g").attr("transform", "translate(" + this.margins.left + ", " + this.margins.top + ")");
this.onAll(optionListeners);
}
Plot.prototype.setTickFormat = function(axis, fn) {
return this.options.tickFormats[axis] = fn;
};
Plot.prototype.hasAxis = function(axis) {
return this.options.axes.indexOf(axis) > -1;
};
Plot.prototype.innerWidth = function() {
return this.width - (this.margins.left + this.margins.right);
};
Plot.prototype.innerHeight = function() {
return this.height - (this.margins.top + this.margins.bottom);
};
Plot.prototype.x = function() {
var domain, ref;
domain = (ref = this.options.domain) != null ? ref : this.extent(function(d) {
return d.x;
});
return d3.scale.linear().domain(domain).range([0, this.innerWidth()]);
};
Plot.prototype.y = function(givenDomain) {
return d3.scale.linear().domain(this._getScaleDomain(givenDomain)).range([this.innerHeight(), 0]);
};
Plot.prototype.bottomAxis = function() {
return d3.svg.axis().scale(this.x()).orient('bottom').ticks(this.options.ticks.bottom).tickFormat(this.options.tickFormats.bottom);
};
Plot.prototype.topAxis = function() {
return d3.svg.axis().scale(this.x()).orient('top').ticks(this.options.ticks.top).tickFormat(this.options.tickFormats.top);
};
Plot.prototype.leftAxis = function() {
var range;
range = this.options.range ? this.options.range.left : null;
return d3.svg.axis().scale(this.y(range)).orient('left').ticks(this.options.ticks.left).tickFormat(this.options.tickFormats.left);
};
Plot.prototype.rightAxis = function() {
var range;
range = this.options.range ? this.options.range.right : null;
return d3.svg.axis().scale(this.y(range)).orient('right').ticks(this.options.ticks.right).tickFormat(this.options.tickFormats.right);
};
Plot.prototype.draw = function() {
if (this._axesDrawn) {
this._redrawAxes();
} else {
this._drawAxes();
}
return Plot.__super__.draw.call(this);
};
Plot.prototype._redrawAxes = function() {
if (this.hasAxis('bottom')) {
this.g.selectAll('.x.axis.bottom').transition().duration(500).ease('linear').call(this.bottomAxis());
}
if (this.hasAxis('top')) {
this.g.selectAll('.x.axis.top').transition().duration(500).ease('linear').call(this.topAxis());
}
if (this.hasAxis('left')) {
this.g.selectAll('.y.axis.left').transition().duration(500).ease('linear').call(this.leftAxis());
}
if (this.hasAxis('right')) {
return this.g.selectAll('.y.axis.right').transition().duration(500).ease('linear').call(this.rightAxis());
}
};
Plot.prototype._drawAxes = function() {
if (this.hasAxis('bottom')) {
this.g.append("g").attr("class", "x axis bottom").attr("transform", "translate(0, " + (this.innerHeight()) + ")").call(this.bottomAxis());
}
if (this.hasAxis('top')) {
this.g.append("g").attr('class', 'x axis top').call(this.topAxis());
}
if (this.hasAxis('left')) {
this.g.append("g").attr("class", "y axis left").call(this.leftAxis());
}
if (this.hasAxis('right')) {
this.g.append('g').attr('class', 'y axis right').attr('transform', "translate(" + (this.innerWidth()) + ", 0)").call(this.rightAxis());
}
return this._axesDrawn = true;
};
Plot.prototype.dimensionsChanged = function() {
Plot.__super__.dimensionsChanged.call(this);
this.g.selectAll('.axis').remove();
this._axesDrawn = false;
return this.draw();
};
Plot.prototype.marginsChanged = function() {
var pos, ref, size;
if (this.options.margins == null) {
return;
}
ref = this.options.margins;
for (pos in ref) {
if (!hasProp.call(ref, pos)) continue;
size = ref[pos];
if (size == null) {
this.margins[pos] = 6;
} else {
this.margins[pos] = size;
}
}
this.g.transition().duration(750).attr("transform", "translate(" + this.margins.left + ", " + this.margins.top + ")");
return this.draw();
};
Plot.prototype.axesChanged = function() {
var i, len, pos, ref;
ref = ['top', 'right', 'bottom', 'left'];
for (i = 0, len = ref.length; i < len; i++) {
pos = ref[i];
if ((this.options.margins != null) && (this.options.margins[pos] != null)) {
continue;
}
if (this.hasAxis(pos)) {
this.margins[pos] = defaultAxisMargins[pos];
} else {
this.margins[pos] = 6;
}
}
this.g.transition().duration(750).attr("transform", "translate(" + this.margins.left + ", " + this.margins.top + ")");
this.g.selectAll('.axis').remove();
this._axesDrawn = false;
return this.draw();
};
Plot.prototype.ticksChanged = function() {
return this.draw();
};
Plot.prototype.tickFormatsChanged = function() {
return this.draw();
};
Plot.prototype.domainChanged = function() {
return this.draw();
};
Plot.prototype.rangeChanged = function() {
return this.draw();
};
return Plot;
})(Epoch.Chart.SVG);
var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Epoch.Chart.Area = (function(superClass) {
extend(Area, superClass);
function Area(options) {
var base;
this.options = options != null ? options : {};
if ((base = this.options).type == null) {
base.type = 'area';
}
Area.__super__.constructor.call(this, this.options);
this.draw();
}
Area.prototype.y = function() {
var a, i, k, layer, len, ref, ref1, ref2, v;
a = [];
ref = this.getVisibleLayers();
for (i = 0, len = ref.length; i < len; i++) {
layer = ref[i];
ref1 = layer.values;
for (k in ref1) {
if (!hasProp.call(ref1, k)) continue;
v = ref1[k];
if (a[k] != null) {
a[k] += v.y;
}
if (a[k] == null) {
a[k] = v.y;
}
}
}
return d3.scale.linear().domain((ref2 = this.options.range) != null ? ref2 : [0, d3.max(a)]).range([this.height - this.margins.top - this.margins.bottom, 0]);
};
Area.prototype.draw = function() {
var area, data, layer, layers, ref, stack, x, y;
ref = [this.x(), this.y(), this.getVisibleLayers()], x = ref[0], y = ref[1], layers = ref[2];
this.g.selectAll('.layer').remove();
if (layers.length === 0) {
return;
}
area = d3.svg.area().x(function(d) {
return x(d.x);
}).y0(function(d) {
return y(d.y0);
}).y1(function(d) {
return y(d.y0 + d.y);
});
stack = d3.layout.stack().values(function(d) {
return d.values;
});
data = stack(layers);
layer = this.g.selectAll('.layer').data(layers, function(d) {
return d.category;
});
layer.select('.area').attr('d', function(d) {
return area(d.values);
});
layer.enter().append('g').attr('class', function(d) {
return d.className;
});
layer.append('path').attr('class', 'area').attr('d', function(d) {
return area(d.values);
});
return Area.__super__.draw.call(this);
};
return Area;
})(Epoch.Chart.Plot);
var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Epoch.Chart.Bar = (function(superClass) {
var defaults, horizontal_defaults, horizontal_specific, optionListeners;
extend(Bar, superClass);
defaults = {
type: 'bar',
style: 'grouped',
orientation: 'vertical',
padding: {
bar: 0.08,
group: 0.1
},
outerPadding: {
bar: 0.08,
group: 0.1
}
};
horizontal_specific = {