Skip to content

Instantly share code, notes, and snippets.

@poezn
Last active December 28, 2017 15:26
Show Gist options
  • Save poezn/8e06c2873a2c41c27888 to your computer and use it in GitHub Desktop.
Save poezn/8e06c2873a2c41c27888 to your computer and use it in GitHub Desktop.
Horizon Chart
(function(exports){
var cubism = exports.cubism = {version: "1.6.0"};
var cubism_id = 0;
function cubism_identity(d) { return d; }
cubism.option = function(name, defaultValue) {
var values = cubism.options(name);
return values.length ? values[0] : defaultValue;
};
cubism.options = function(name, defaultValues) {
var options = location.search.substring(1).split("&"),
values = [],
i = -1,
n = options.length,
o;
while (++i < n) {
if ((o = options[i].split("="))[0] == name) {
values.push(decodeURIComponent(o[1]));
}
}
return values.length || arguments.length < 2 ? values : defaultValues;
};
cubism.context = function() {
var context = new cubism_context,
step = 1e4, // ten seconds, in milliseconds
size = 1440, // four hours at ten seconds, in pixels
start0, stop0, // the start and stop for the previous change event
start1, stop1, // the start and stop for the next prepare event
serverDelay = 5e3,
clientDelay = 5e3,
event = d3.dispatch("prepare", "beforechange", "change", "focus"),
scale = context.scale = d3.time.scale().range([0, size]),
timeout,
focus;
function update() {
var now = Date.now();
stop0 = new Date(Math.floor((now - serverDelay - clientDelay) / step) * step);
start0 = new Date(stop0 - size * step);
stop1 = new Date(Math.floor((now - serverDelay) / step) * step);
start1 = new Date(stop1 - size * step);
scale.domain([start0, stop0]);
return context;
}
context.start = function() {
if (timeout) clearTimeout(timeout);
var delay = +stop1 + serverDelay - Date.now();
// If we're too late for the first prepare event, skip it.
if (delay < clientDelay) delay += step;
timeout = setTimeout(function prepare() {
stop1 = new Date(Math.floor((Date.now() - serverDelay) / step) * step);
start1 = new Date(stop1 - size * step);
event.prepare.call(context, start1, stop1);
setTimeout(function() {
scale.domain([start0 = start1, stop0 = stop1]);
event.beforechange.call(context, start1, stop1);
event.change.call(context, start1, stop1);
event.focus.call(context, focus);
}, clientDelay);
timeout = setTimeout(prepare, step);
}, delay);
return context;
};
context.stop = function() {
timeout = clearTimeout(timeout);
return context;
};
timeout = setTimeout(context.start, 10);
// Set or get the step interval in milliseconds.
// Defaults to ten seconds.
context.step = function(_) {
if (!arguments.length) return step;
step = +_;
return update();
};
// Set or get the context size (the count of metric values).
// Defaults to 1440 (four hours at ten seconds).
context.size = function(_) {
if (!arguments.length) return size;
scale.range([0, size = +_]);
return update();
};
// The server delay is the amount of time we wait for the server to compute a
// metric. This delay may result from clock skew or from delays collecting
// metrics from various hosts. Defaults to 4 seconds.
context.serverDelay = function(_) {
if (!arguments.length) return serverDelay;
serverDelay = +_;
return update();
};
// The client delay is the amount of additional time we wait to fetch those
// metrics from the server. The client and server delay combined represent the
// age of the most recent displayed metric. Defaults to 1 second.
context.clientDelay = function(_) {
if (!arguments.length) return clientDelay;
clientDelay = +_;
return update();
};
// Sets the focus to the specified index, and dispatches a "focus" event.
context.focus = function(i) {
event.focus.call(context, focus = i);
return context;
};
// Add, remove or get listeners for events.
context.on = function(type, listener) {
if (arguments.length < 2) return event.on(type);
event.on(type, listener);
// Notify the listener of the current start and stop time, as appropriate.
// This way, metrics can make requests for data immediately,
// and likewise the axis can display itself synchronously.
if (listener != null) {
if (/^prepare(\.|$)/.test(type)) listener.call(context, start1, stop1);
if (/^beforechange(\.|$)/.test(type)) listener.call(context, start0, stop0);
if (/^change(\.|$)/.test(type)) listener.call(context, start0, stop0);
if (/^focus(\.|$)/.test(type)) listener.call(context, focus);
}
return context;
};
d3.select(window).on("keydown.context-" + ++cubism_id, function() {
switch (!d3.event.metaKey && d3.event.keyCode) {
case 37: // left
if (focus == null) focus = size - 1;
if (focus > 0) context.focus(--focus);
break;
case 39: // right
if (focus == null) focus = size - 2;
if (focus < size - 1) context.focus(++focus);
break;
default: return;
}
d3.event.preventDefault();
});
return update();
};
function cubism_context() {}
var cubism_contextPrototype = cubism.context.prototype = cubism_context.prototype;
cubism_contextPrototype.constant = function(value) {
return new cubism_metricConstant(this, +value);
};
cubism_contextPrototype.cube = function(host) {
if (!arguments.length) host = "";
var source = {},
context = this;
source.metric = function(expression) {
return context.metric(function(start, stop, step, callback) {
d3.json(host + "/1.0/metric"
+ "?expression=" + encodeURIComponent(expression)
+ "&start=" + cubism_cubeFormatDate(start)
+ "&stop=" + cubism_cubeFormatDate(stop)
+ "&step=" + step, function(data) {
if (!data) return callback(new Error("unable to load data"));
callback(null, data.map(function(d) { return d.value; }));
});
}, expression += "");
};
// Returns the Cube host.
source.toString = function() {
return host;
};
return source;
};
var cubism_cubeFormatDate = d3.time.format.iso;
/* librato (http://dev.librato.com/v1/post/metrics) source
* If you want to see an example of how to use this source, check: https://gist.github.com/drio/5792680
*/
cubism_contextPrototype.librato = function(user, token) {
var source = {},
context = this;
auth_string = "Basic " + btoa(user + ":" + token);
avail_rsts = [ 1, 60, 900, 3600 ];
/* Given a step, find the best librato resolution to use.
*
* Example:
*
* (s) : cubism step
*
* avail_rsts 1 --------------- 60 --------------- 900 ---------------- 3600
* | (s) |
* | |
* [low_res top_res]
*
* return: low_res (60)
*/
function find_ideal_librato_resolution(step) {
var highest_res = avail_rsts[0],
lowest_res = avail_rsts[avail_rsts.length]; // high and lowest available resolution from librato
/* If step is outside the highest or lowest librato resolution, pick them and we are done */
if (step >= lowest_res)
return lowest_res;
if (step <= highest_res)
return highest_res;
/* If not, find in what resolution interval the step lands. */
var iof, top_res, i;
for (i=step; i<=lowest_res; i++) {
iof = avail_rsts.indexOf(i);
if (iof > -1) {
top_res = avail_rsts[iof];
break;
}
}
var low_res;
for (i=step; i>=highest_res; i--) {
iof = avail_rsts.indexOf(i);
if (iof > -1) {
low_res = avail_rsts[iof];
break;
}
}
/* What's the closest librato resolution given the step ? */
return ((top_res-step) < (step-low_res)) ? top_res : low_res;
}
function find_librato_resolution(sdate, edate, step) {
var i_size = edate - sdate, // interval size
month = 2419200,
week = 604800,
two_days = 172800,
ideal_res;
if (i_size > month)
return 3600;
ideal_res = find_ideal_librato_resolution(step);
/*
* Now we have the ideal resolution, but due to the retention policies at librato, maybe we have
* to use a higher resolution.
* http://support.metrics.librato.com/knowledgebase/articles/66838-understanding-metrics-roll-ups-retention-and-grap
*/
if (i_size > week && ideal_res < 900)
return 900;
else if (i_size > two_days && ideal_res < 60)
return 60;
else
return ideal_res;
}
/* All the logic to query the librato API is here */
var librato_request = function(composite) {
var url_prefix = "https://metrics-api.librato.com/v1/metrics";
function make_url(sdate, edate, step) {
var params = "compose=" + composite +
"&start_time=" + sdate +
"&end_time=" + edate +
"&resolution=" + find_librato_resolution(sdate, edate, step);
return url_prefix + "?" + params;
}
/*
* We are most likely not going to get the same number of measurements
* cubism expects for a particular context: We have to perform down/up
* sampling
*/
function down_up_sampling(isdate, iedate, step, librato_mm) {
var av = [];
for (i=isdate; i<=iedate; i+=step) {
var int_mes = [];
while (librato_mm.length && librato_mm[0].measure_time <= i) {
int_mes.push(librato_mm.shift().value);
}
var v;
if (int_mes.length) { /* Compute the average */
v = int_mes.reduce(function(a, b) { return a + b }) / int_mes.length;
} else { /* No librato values on interval */
v = (av.length) ? av[av.length-1] : 0;
}
av.push(v);
}
return av;
}
request = {};
request.fire = function(isdate, iedate, step, callback_done) {
var a_values = []; /* Store partial values from librato */
/*
* Librato has a limit in the number of measurements we get back in a request (100).
* We recursively perform requests to the API to ensure we have all the data points
* for the interval we are working on.
*/
function actual_request(full_url) {
d3.json(full_url)
.header("X-Requested-With", "XMLHttpRequest")
.header("Authorization", auth_string)
.header("Librato-User-Agent", 'cubism/' + cubism.version)
.get(function (error, data) { /* Callback; data available */
if (!error) {
if (data.measurements.length === 0) {
return
}
data.measurements[0].series.forEach(function(o) { a_values.push(o); });
var still_more_values = 'query' in data && 'next_time' in data.query;
if (still_more_values) {
actual_request(make_url(data.query.next_time, iedate, step));
} else {
var a_adjusted = down_up_sampling(isdate, iedate, step, a_values);
callback_done(a_adjusted);
}
}
});
}
actual_request(make_url(isdate, iedate, step));
};
return request;
};
/*
* The user will use this method to create a cubism source (librato in this case)
* and call .metric() as necessary to create metrics.
*/
source.metric = function(m_composite) {
return context.metric(function(start, stop, step, callback) {
/* All the librato logic is here; .fire() retrieves the metrics' data */
librato_request(m_composite)
.fire(cubism_libratoFormatDate(start),
cubism_libratoFormatDate(stop),
cubism_libratoFormatDate(step),
function(a_values) { callback(null, a_values); });
}, m_composite += "");
};
/* This is not used when the source is librato */
source.toString = function() {
return "librato";
};
return source;
};
var cubism_libratoFormatDate = function(time) {
return Math.floor(time / 1000);
};
cubism_contextPrototype.graphite = function(host) {
if (!arguments.length) host = "";
var source = {},
context = this;
source.metric = function(expression) {
var sum = "sum";
var metric = context.metric(function(start, stop, step, callback) {
var target = expression;
// Apply the summarize, if necessary.
if (step !== 1e4) target = "summarize(" + target + ",'"
+ (!(step % 36e5) ? step / 36e5 + "hour" : !(step % 6e4) ? step / 6e4 + "min" : step / 1e3 + "sec")
+ "','" + sum + "')";
d3.text(host + "/render?format=raw"
+ "&target=" + encodeURIComponent("alias(" + target + ",'')")
+ "&from=" + cubism_graphiteFormatDate(start - 2 * step) // off-by-two?
+ "&until=" + cubism_graphiteFormatDate(stop - 1000), function(text) {
if (!text) return callback(new Error("unable to load data"));
callback(null, cubism_graphiteParse(text));
});
}, expression += "");
metric.summarize = function(_) {
sum = _;
return metric;
};
return metric;
};
source.find = function(pattern, callback) {
d3.json(host + "/metrics/find?format=completer"
+ "&query=" + encodeURIComponent(pattern), function(result) {
if (!result) return callback(new Error("unable to find metrics"));
callback(null, result.metrics.map(function(d) { return d.path; }));
});
};
// Returns the graphite host.
source.toString = function() {
return host;
};
return source;
};
// Graphite understands seconds since UNIX epoch.
function cubism_graphiteFormatDate(time) {
return Math.floor(time / 1000);
}
// Helper method for parsing graphite's raw format.
function cubism_graphiteParse(text) {
var i = text.indexOf("|"),
meta = text.substring(0, i),
c = meta.lastIndexOf(","),
b = meta.lastIndexOf(",", c - 1),
a = meta.lastIndexOf(",", b - 1),
start = meta.substring(a + 1, b) * 1000,
step = meta.substring(c + 1) * 1000;
return text
.substring(i + 1)
.split(",")
.slice(1) // the first value is always None?
.map(function(d) { return +d; });
}
cubism_contextPrototype.gangliaWeb = function(config) {
var host = '',
uriPathPrefix = '/ganglia2/';
if (arguments.length) {
if (config.host) {
host = config.host;
}
if (config.uriPathPrefix) {
uriPathPrefix = config.uriPathPrefix;
/* Add leading and trailing slashes, as appropriate. */
if( uriPathPrefix[0] != '/' ) {
uriPathPrefix = '/' + uriPathPrefix;
}
if( uriPathPrefix[uriPathPrefix.length - 1] != '/' ) {
uriPathPrefix += '/';
}
}
}
var source = {},
context = this;
source.metric = function(metricInfo) {
/* Store the members from metricInfo into local variables. */
var clusterName = metricInfo.clusterName,
metricName = metricInfo.metricName,
hostName = metricInfo.hostName,
isReport = metricInfo.isReport || false,
titleGenerator = metricInfo.titleGenerator ||
/* Reasonable (not necessarily pretty) default for titleGenerator. */
function(unusedMetricInfo) {
/* unusedMetricInfo is, well, unused in this default case. */
return ('clusterName:' + clusterName +
' metricName:' + metricName +
(hostName ? ' hostName:' + hostName : ''));
},
onChangeCallback = metricInfo.onChangeCallback;
/* Default to plain, simple metrics. */
var metricKeyName = isReport ? 'g' : 'm';
var gangliaWebMetric = context.metric(function(start, stop, step, callback) {
function constructGangliaWebRequestQueryParams() {
return ('c=' + clusterName +
'&' + metricKeyName + '=' + metricName +
(hostName ? '&h=' + hostName : '') +
'&cs=' + start/1000 + '&ce=' + stop/1000 + '&step=' + step/1000 + '&graphlot=1');
}
d3.json(host + uriPathPrefix + 'graph.php?' + constructGangliaWebRequestQueryParams(),
function(result) {
if( !result ) {
return callback(new Error("Unable to fetch GangliaWeb data"));
}
callback(null, result[0].data);
});
}, titleGenerator(metricInfo));
gangliaWebMetric.toString = function() {
return titleGenerator(metricInfo);
};
/* Allow users to run their custom code each time a gangliaWebMetric changes.
*
* TODO Consider abstracting away the naked Cubism call, and instead exposing
* a callback that takes in the values array (maybe alongwith the original
* start and stop 'naked' parameters), since it's handy to have the entire
* dataset at your disposal (and users will likely implement onChangeCallback
* primarily to get at this dataset).
*/
if (onChangeCallback) {
gangliaWebMetric.on('change', onChangeCallback);
}
return gangliaWebMetric;
};
// Returns the gangliaWeb host + uriPathPrefix.
source.toString = function() {
return host + uriPathPrefix;
};
return source;
};
function cubism_metric(context) {
if (!(context instanceof cubism_context)) throw new Error("invalid context");
this.context = context;
}
var cubism_metricPrototype = cubism_metric.prototype;
cubism.metric = cubism_metric;
cubism_metricPrototype.valueAt = function() {
return NaN;
};
cubism_metricPrototype.alias = function(name) {
this.toString = function() { return name; };
return this;
};
cubism_metricPrototype.extent = function() {
var i = 0,
n = this.context.size(),
value,
min = Infinity,
max = -Infinity;
while (++i < n) {
value = this.valueAt(i);
if (value < min) min = value;
if (value > max) max = value;
}
return [min, max];
};
cubism_metricPrototype.on = function(type, listener) {
return arguments.length < 2 ? null : this;
};
cubism_metricPrototype.shift = function() {
return this;
};
cubism_metricPrototype.on = function() {
return arguments.length < 2 ? null : this;
};
cubism_contextPrototype.metric = function(request, name) {
var context = this,
metric = new cubism_metric(context),
id = ".metric-" + ++cubism_id,
start = -Infinity,
stop,
step = context.step(),
size = context.size(),
values = [],
event = d3.dispatch("change"),
listening = 0,
fetching;
// Prefetch new data into a temporary array.
function prepare(start1, stop) {
var steps = Math.min(size, Math.round((start1 - start) / step));
if (!steps || fetching) return; // already fetched, or fetching!
fetching = true;
steps = Math.min(size, steps + cubism_metricOverlap);
var start0 = new Date(stop - steps * step);
request(start0, stop, step, function(error, data) {
fetching = false;
if (error) return console.warn(error);
var i = isFinite(start) ? Math.round((start0 - start) / step) : 0;
for (var j = 0, m = data.length; j < m; ++j) values[j + i] = data[j];
event.change.call(metric, start, stop);
});
}
// When the context changes, switch to the new data, ready-or-not!
function beforechange(start1, stop1) {
if (!isFinite(start)) start = start1;
values.splice(0, Math.max(0, Math.min(size, Math.round((start1 - start) / step))));
start = start1;
stop = stop1;
}
//
metric.valueAt = function(i) {
return values[i];
};
//
metric.shift = function(offset) {
return context.metric(cubism_metricShift(request, +offset));
};
//
metric.on = function(type, listener) {
if (!arguments.length) return event.on(type);
// If there are no listeners, then stop listening to the context,
// and avoid unnecessary fetches.
if (listener == null) {
if (event.on(type) != null && --listening == 0) {
context.on("prepare" + id, null).on("beforechange" + id, null);
}
} else {
if (event.on(type) == null && ++listening == 1) {
context.on("prepare" + id, prepare).on("beforechange" + id, beforechange);
}
}
event.on(type, listener);
// Notify the listener of the current start and stop time, as appropriate.
// This way, charts can display synchronous metrics immediately.
if (listener != null) {
if (/^change(\.|$)/.test(type)) listener.call(context, start, stop);
}
return metric;
};
//
if (arguments.length > 1) metric.toString = function() {
return name;
};
return metric;
};
// Number of metric to refetch each period, in case of lag.
var cubism_metricOverlap = 6;
// Wraps the specified request implementation, and shifts time by the given offset.
function cubism_metricShift(request, offset) {
return function(start, stop, step, callback) {
request(new Date(+start + offset), new Date(+stop + offset), step, callback);
};
}
function cubism_metricConstant(context, value) {
cubism_metric.call(this, context);
value = +value;
var name = value + "";
this.valueOf = function() { return value; };
this.toString = function() { return name; };
}
var cubism_metricConstantPrototype = cubism_metricConstant.prototype = Object.create(cubism_metric.prototype);
cubism_metricConstantPrototype.valueAt = function() {
return +this;
};
cubism_metricConstantPrototype.extent = function() {
return [+this, +this];
};
function cubism_metricOperator(name, operate) {
function cubism_metricOperator(left, right) {
if (!(right instanceof cubism_metric)) right = new cubism_metricConstant(left.context, right);
else if (left.context !== right.context) throw new Error("mismatch context");
cubism_metric.call(this, left.context);
this.left = left;
this.right = right;
this.toString = function() { return left + " " + name + " " + right; };
}
var cubism_metricOperatorPrototype = cubism_metricOperator.prototype = Object.create(cubism_metric.prototype);
cubism_metricOperatorPrototype.valueAt = function(i) {
return operate(this.left.valueAt(i), this.right.valueAt(i));
};
cubism_metricOperatorPrototype.shift = function(offset) {
return new cubism_metricOperator(this.left.shift(offset), this.right.shift(offset));
};
cubism_metricOperatorPrototype.on = function(type, listener) {
if (arguments.length < 2) return this.left.on(type);
this.left.on(type, listener);
this.right.on(type, listener);
return this;
};
return function(right) {
return new cubism_metricOperator(this, right);
};
}
cubism_metricPrototype.add = cubism_metricOperator("+", function(left, right) {
return left + right;
});
cubism_metricPrototype.subtract = cubism_metricOperator("-", function(left, right) {
return left - right;
});
cubism_metricPrototype.multiply = cubism_metricOperator("*", function(left, right) {
return left * right;
});
cubism_metricPrototype.divide = cubism_metricOperator("/", function(left, right) {
return left / right;
});
cubism_contextPrototype.horizon = function() {
var context = this,
mode = "offset",
buffer = document.createElement("canvas"),
width = buffer.width = context.size(),
height = buffer.height = 30,
scale = d3.scale.linear().interpolate(d3.interpolateRound),
metric = cubism_identity,
extent = null,
title = cubism_identity,
format = d3.format(".2s"),
colors = ["#08519c","#3182bd","#6baed6","#bdd7e7","#bae4b3","#74c476","#31a354","#006d2c"];
function horizon(selection) {
selection
.on("mousemove.horizon", function() { context.focus(Math.round(d3.mouse(this)[0])); })
.on("mouseout.horizon", function() { context.focus(null); });
selection.append("canvas")
.attr("width", width)
.attr("height", height);
selection.append("span")
.attr("class", "title")
.text(title);
selection.append("span")
.attr("class", "value");
selection.each(function(d, i) {
var that = this,
id = ++cubism_id,
metric_ = typeof metric === "function" ? metric.call(that, d, i) : metric,
colors_ = typeof colors === "function" ? colors.call(that, d, i) : colors,
extent_ = typeof extent === "function" ? extent.call(that, d, i) : extent,
start = -Infinity,
step = context.step(),
canvas = d3.select(that).select("canvas"),
span = d3.select(that).select(".value"),
max_,
m = colors_.length >> 1,
ready;
canvas.datum({id: id, metric: metric_});
canvas = canvas.node().getContext("2d");
function change(start1, stop) {
canvas.save();
// compute the new extent and ready flag
var extent = metric_.extent();
ready = extent.every(isFinite);
if (extent_ != null) extent = extent_;
// if this is an update (with no extent change), copy old values!
var i0 = 0, max = Math.max(-extent[0], extent[1]);
if (this === context) {
if (max == max_) {
i0 = width - cubism_metricOverlap;
var dx = (start1 - start) / step;
if (dx < width) {
var canvas0 = buffer.getContext("2d");
canvas0.clearRect(0, 0, width, height);
canvas0.drawImage(canvas.canvas, dx, 0, width - dx, height, 0, 0, width - dx, height);
canvas.clearRect(0, 0, width, height);
canvas.drawImage(canvas0.canvas, 0, 0);
}
}
start = start1;
}
// update the domain
scale.domain([0, max_ = max]);
// clear for the new data
canvas.clearRect(i0, 0, width - i0, height);
// record whether there are negative values to display
var negative;
// positive bands
for (var j = 0; j < m; ++j) {
canvas.fillStyle = colors_[m + j];
// Adjust the range based on the current band index.
var y0 = (j - m + 1) * height;
scale.range([m * height + y0, y0]);
y0 = scale(0);
for (var i = i0, n = width, y1; i < n; ++i) {
y1 = metric_.valueAt(i);
if (y1 <= 0) { negative = true; continue; }
if (y1 === undefined) continue;
canvas.fillRect(i, y1 = scale(y1), 1, y0 - y1);
}
}
if (negative) {
// enable offset mode
if (mode === "offset") {
canvas.translate(0, height);
canvas.scale(1, -1);
}
// negative bands
for (var j = 0; j < m; ++j) {
canvas.fillStyle = colors_[m - 1 - j];
// Adjust the range based on the current band index.
var y0 = (j - m + 1) * height;
scale.range([m * height + y0, y0]);
y0 = scale(0);
for (var i = i0, n = width, y1; i < n; ++i) {
y1 = metric_.valueAt(i);
if (y1 >= 0) continue;
canvas.fillRect(i, scale(-y1), 1, y0 - scale(-y1));
}
}
}
canvas.restore();
}
function focus(i) {
if (i == null) i = width - 1;
var value = metric_.valueAt(i);
span.datum(value).text(isNaN(value) ? null : format);
}
// Update the chart when the context changes.
context.on("change.horizon-" + id, change);
context.on("focus.horizon-" + id, focus);
// Display the first metric change immediately,
// but defer subsequent updates to the canvas change.
// Note that someone still needs to listen to the metric,
// so that it continues to update automatically.
metric_.on("change.horizon-" + id, function(start, stop) {
change(start, stop), focus();
if (ready) metric_.on("change.horizon-" + id, cubism_identity);
});
});
}
horizon.remove = function(selection) {
selection
.on("mousemove.horizon", null)
.on("mouseout.horizon", null);
selection.selectAll("canvas")
.each(remove)
.remove();
selection.selectAll(".title,.value")
.remove();
function remove(d) {
d.metric.on("change.horizon-" + d.id, null);
context.on("change.horizon-" + d.id, null);
context.on("focus.horizon-" + d.id, null);
}
};
horizon.mode = function(_) {
if (!arguments.length) return mode;
mode = _ + "";
return horizon;
};
horizon.height = function(_) {
if (!arguments.length) return height;
buffer.height = height = +_;
return horizon;
};
horizon.metric = function(_) {
if (!arguments.length) return metric;
metric = _;
return horizon;
};
horizon.scale = function(_) {
if (!arguments.length) return scale;
scale = _;
return horizon;
};
horizon.extent = function(_) {
if (!arguments.length) return extent;
extent = _;
return horizon;
};
horizon.title = function(_) {
if (!arguments.length) return title;
title = _;
return horizon;
};
horizon.format = function(_) {
if (!arguments.length) return format;
format = _;
return horizon;
};
horizon.colors = function(_) {
if (!arguments.length) return colors;
colors = _;
return horizon;
};
return horizon;
};
cubism_contextPrototype.comparison = function() {
var context = this,
width = context.size(),
height = 120,
scale = d3.scale.linear().interpolate(d3.interpolateRound),
primary = function(d) { return d[0]; },
secondary = function(d) { return d[1]; },
extent = null,
title = cubism_identity,
formatPrimary = cubism_comparisonPrimaryFormat,
formatChange = cubism_comparisonChangeFormat,
colors = ["#9ecae1", "#225b84", "#a1d99b", "#22723a"],
strokeWidth = 1.5;
function comparison(selection) {
selection
.on("mousemove.comparison", function() { context.focus(Math.round(d3.mouse(this)[0])); })
.on("mouseout.comparison", function() { context.focus(null); });
selection.append("canvas")
.attr("width", width)
.attr("height", height);
selection.append("span")
.attr("class", "title")
.text(title);
selection.append("span")
.attr("class", "value primary");
selection.append("span")
.attr("class", "value change");
selection.each(function(d, i) {
var that = this,
id = ++cubism_id,
primary_ = typeof primary === "function" ? primary.call(that, d, i) : primary,
secondary_ = typeof secondary === "function" ? secondary.call(that, d, i) : secondary,
extent_ = typeof extent === "function" ? extent.call(that, d, i) : extent,
div = d3.select(that),
canvas = div.select("canvas"),
spanPrimary = div.select(".value.primary"),
spanChange = div.select(".value.change"),
ready;
canvas.datum({id: id, primary: primary_, secondary: secondary_});
canvas = canvas.node().getContext("2d");
function change(start, stop) {
canvas.save();
canvas.clearRect(0, 0, width, height);
// update the scale
var primaryExtent = primary_.extent(),
secondaryExtent = secondary_.extent(),
extent = extent_ == null ? primaryExtent : extent_;
scale.domain(extent).range([height, 0]);
ready = primaryExtent.concat(secondaryExtent).every(isFinite);
// consistent overplotting
var round = start / context.step() & 1
? cubism_comparisonRoundOdd
: cubism_comparisonRoundEven;
// positive changes
canvas.fillStyle = colors[2];
for (var i = 0, n = width; i < n; ++i) {
var y0 = scale(primary_.valueAt(i)),
y1 = scale(secondary_.valueAt(i));
if (y0 < y1) canvas.fillRect(round(i), y0, 1, y1 - y0);
}
// negative changes
canvas.fillStyle = colors[0];
for (i = 0; i < n; ++i) {
var y0 = scale(primary_.valueAt(i)),
y1 = scale(secondary_.valueAt(i));
if (y0 > y1) canvas.fillRect(round(i), y1, 1, y0 - y1);
}
// positive values
canvas.fillStyle = colors[3];
for (i = 0; i < n; ++i) {
var y0 = scale(primary_.valueAt(i)),
y1 = scale(secondary_.valueAt(i));
if (y0 <= y1) canvas.fillRect(round(i), y0, 1, strokeWidth);
}
// negative values
canvas.fillStyle = colors[1];
for (i = 0; i < n; ++i) {
var y0 = scale(primary_.valueAt(i)),
y1 = scale(secondary_.valueAt(i));
if (y0 > y1) canvas.fillRect(round(i), y0 - strokeWidth, 1, strokeWidth);
}
canvas.restore();
}
function focus(i) {
if (i == null) i = width - 1;
var valuePrimary = primary_.valueAt(i),
valueSecondary = secondary_.valueAt(i),
valueChange = (valuePrimary - valueSecondary) / valueSecondary;
spanPrimary
.datum(valuePrimary)
.text(isNaN(valuePrimary) ? null : formatPrimary);
spanChange
.datum(valueChange)
.text(isNaN(valueChange) ? null : formatChange)
.attr("class", "value change " + (valueChange > 0 ? "positive" : valueChange < 0 ? "negative" : ""));
}
// Display the first primary change immediately,
// but defer subsequent updates to the context change.
// Note that someone still needs to listen to the metric,
// so that it continues to update automatically.
primary_.on("change.comparison-" + id, firstChange);
secondary_.on("change.comparison-" + id, firstChange);
function firstChange(start, stop) {
change(start, stop), focus();
if (ready) {
primary_.on("change.comparison-" + id, cubism_identity);
secondary_.on("change.comparison-" + id, cubism_identity);
}
}
// Update the chart when the context changes.
context.on("change.comparison-" + id, change);
context.on("focus.comparison-" + id, focus);
});
}
comparison.remove = function(selection) {
selection
.on("mousemove.comparison", null)
.on("mouseout.comparison", null);
selection.selectAll("canvas")
.each(remove)
.remove();
selection.selectAll(".title,.value")
.remove();
function remove(d) {
d.primary.on("change.comparison-" + d.id, null);
d.secondary.on("change.comparison-" + d.id, null);
context.on("change.comparison-" + d.id, null);
context.on("focus.comparison-" + d.id, null);
}
};
comparison.height = function(_) {
if (!arguments.length) return height;
height = +_;
return comparison;
};
comparison.primary = function(_) {
if (!arguments.length) return primary;
primary = _;
return comparison;
};
comparison.secondary = function(_) {
if (!arguments.length) return secondary;
secondary = _;
return comparison;
};
comparison.scale = function(_) {
if (!arguments.length) return scale;
scale = _;
return comparison;
};
comparison.extent = function(_) {
if (!arguments.length) return extent;
extent = _;
return comparison;
};
comparison.title = function(_) {
if (!arguments.length) return title;
title = _;
return comparison;
};
comparison.formatPrimary = function(_) {
if (!arguments.length) return formatPrimary;
formatPrimary = _;
return comparison;
};
comparison.formatChange = function(_) {
if (!arguments.length) return formatChange;
formatChange = _;
return comparison;
};
comparison.colors = function(_) {
if (!arguments.length) return colors;
colors = _;
return comparison;
};
comparison.strokeWidth = function(_) {
if (!arguments.length) return strokeWidth;
strokeWidth = _;
return comparison;
};
return comparison;
};
var cubism_comparisonPrimaryFormat = d3.format(".2s"),
cubism_comparisonChangeFormat = d3.format("+.0%");
function cubism_comparisonRoundEven(i) {
return i & 0xfffffe;
}
function cubism_comparisonRoundOdd(i) {
return ((i + 1) & 0xfffffe) - 1;
}
cubism_contextPrototype.axis = function() {
var context = this,
scale = context.scale,
axis_ = d3.svg.axis().scale(scale);
var formatDefault = context.step() < 6e4 ? cubism_axisFormatSeconds
: context.step() < 72e5 ? cubism_axisFormatMinutes
: cubism_axisFormatDays;
var format = formatDefault;
function axis(selection) {
var id = ++cubism_id,
tick;
var g = selection.append("svg")
.datum({id: id})
.attr("width", context.size())
.attr("height", Math.max(28, -axis.tickSize()))
.append("g")
.attr("transform", "translate(0," + (axis_.orient() === "top" ? 27 : 4) + ")")
.call(axis_);
context.on("change.axis-" + id, function() {
g.call(axis_);
if (!tick) tick = d3.select(g.node().appendChild(g.selectAll("text").node().cloneNode(true)))
.style("display", "none")
.text(null);
});
context.on("focus.axis-" + id, function(i) {
if (tick) {
if (i == null) {
tick.style("display", "none");
g.selectAll("text").style("fill-opacity", null);
} else {
tick.style("display", null).attr("x", i).text(format(scale.invert(i)));
var dx = tick.node().getComputedTextLength() + 6;
g.selectAll("text").style("fill-opacity", function(d) { return Math.abs(scale(d) - i) < dx ? 0 : 1; });
}
}
});
}
axis.remove = function(selection) {
selection.selectAll("svg")
.each(remove)
.remove();
function remove(d) {
context.on("change.axis-" + d.id, null);
context.on("focus.axis-" + d.id, null);
}
};
axis.focusFormat = function(_) {
if (!arguments.length) return format == formatDefault ? null : _;
format = _ == null ? formatDefault : _;
return axis;
};
return d3.rebind(axis, axis_,
"orient",
"ticks",
"tickSubdivide",
"tickSize",
"tickPadding",
"tickFormat");
};
var cubism_axisFormatSeconds = d3.time.format("%I:%M:%S %p"),
cubism_axisFormatMinutes = d3.time.format("%I:%M %p"),
cubism_axisFormatDays = d3.time.format("%B %d");
cubism_contextPrototype.rule = function() {
var context = this,
metric = cubism_identity;
function rule(selection) {
var id = ++cubism_id;
var line = selection.append("div")
.datum({id: id})
.attr("class", "line")
.call(cubism_ruleStyle);
selection.each(function(d, i) {
var that = this,
id = ++cubism_id,
metric_ = typeof metric === "function" ? metric.call(that, d, i) : metric;
if (!metric_) return;
function change(start, stop) {
var values = [];
for (var i = 0, n = context.size(); i < n; ++i) {
if (metric_.valueAt(i)) {
values.push(i);
}
}
var lines = selection.selectAll(".metric").data(values);
lines.exit().remove();
lines.enter().append("div").attr("class", "metric line").call(cubism_ruleStyle);
lines.style("left", cubism_ruleLeft);
}
context.on("change.rule-" + id, change);
metric_.on("change.rule-" + id, change);
});
context.on("focus.rule-" + id, function(i) {
line.datum(i)
.style("display", i == null ? "none" : null)
.style("left", i == null ? null : cubism_ruleLeft);
});
}
rule.remove = function(selection) {
selection.selectAll(".line")
.each(remove)
.remove();
function remove(d) {
context.on("focus.rule-" + d.id, null);
}
};
rule.metric = function(_) {
if (!arguments.length) return metric;
metric = _;
return rule;
};
return rule;
};
function cubism_ruleStyle(line) {
line
.style("position", "absolute")
.style("top", 0)
.style("bottom", 0)
.style("width", "1px")
.style("pointer-events", "none");
}
function cubism_ruleLeft(i) {
return i + "px";
}
})(this);
_time WIKI/AAPL WIKI/CA WIKI/DATA WIKI/EMC WIKI/HPQ WIKI/IBM WIKI/MSFT WIKI/MSTR WIKI/ORCL WIKI/QLIK WIKI/SPLK WIKI/TDC WIKI/VRNS
2015-02-12T00:00:00.000-0800 126.46 32.405 98.5 27.87 38.37 158.52 43.09 178.75 43.89 30.08 61.93 46.02 36.74
2015-02-13T00:00:00.000-0800 127.08 32.63 99.9 27.99 38.56 160.4 43.87 181.24 43.93 31.17 64.18 45.73 37.34
2015-02-14T00:00:00.000-0800 127.08 32.63 99.9 27.99 38.56 160.4 43.87 181.24 43.93 31.17 64.18 45.73 37.34
2015-02-15T00:00:00.000-0800 127.08 32.63 99.9 27.99 38.56 160.4 43.87 181.24 43.93 31.17 64.18 45.73 37.34
2015-02-16T00:00:00.000-0800 127.08 32.63 99.9 27.99 38.56 160.4 43.87 181.24 43.93 31.17 64.18 45.73 37.34
2015-02-17T00:00:00.000-0800 127.83 32.58 98.45 28.3 38.53 160.96 43.58 179.66 43.84 31.05 63.83 45.08 37.45
2015-02-18T00:00:00.000-0800 128.715 32.59 97.84 28.2 38.15 162.19 43.53 179.66 44.1 30.99 65.9 45.16 30.4
2015-02-19T00:00:00.000-0800 128.45 32.52 99.32 28.72 38.38 163.89 43.5 179.62 44.11 31.165 68.06 45.17 30.91
2015-02-20T00:00:00.000-0800 129.495 32.83 99.28 29.04 38.39 163.65 43.855 179.55 43.77 31.5 68.945 45.29 29.88
2015-02-21T00:00:00.000-0800 129.495 32.83 99.28 29.04 38.39 163.65 43.855 179.55 43.77 31.5 68.945 45.29 29.88
2015-02-22T00:00:00.000-0800 129.495 32.83 99.28 29.04 38.39 163.65 43.855 179.55 43.77 31.5 68.945 45.29 29.88
2015-02-23T00:00:00.000-0800 133.0 32.59 96.85 28.75 38.19 162.91 44.15 177.39 43.78 30.75 68.6 44.63 29.88
2015-02-24T00:00:00.000-0800 132.17 32.7 96.22 29.02 38.49 164.83 44.09 177.33 43.88 31.03 66.44 44.73 30.5
2015-02-25T00:00:00.000-0800 128.79 33.11 97.27 28.91 34.67 162.81 43.99 179.3 43.73 31.99 67.5 43.95 31.14
2015-02-26T00:00:00.000-0800 130.415 32.82 97.42 28.82 34.01 160.87 44.055 179.51 43.89 32.61 69.57 43.96 30.98
2015-02-27T00:00:00.000-0800 128.46 32.52 94.01 28.94 34.84 161.94 43.85 178.34 43.82 32.44 67.25 44.52 30.89
2015-02-28T00:00:00.000-0800 128.46 32.52 94.01 28.94 34.84 161.94 43.85 178.34 43.82 32.44 67.25 44.52 30.89
2015-03-01T00:00:00.000-0800 128.46 32.52 94.01 28.94 34.84 161.94 43.85 178.34 43.82 32.44 67.25 44.52 30.89
2015-03-02T00:00:00.000-0800 129.09 32.84 96.85 28.88 34.92 160.48 43.88 179.59 44.03 32.59 67.12 44.96 31.5
2015-03-03T00:00:00.000-0800 129.36 32.2 94.25 28.39 34.57 161.03 43.28 179.19 43.38 32.35 65.68 44.05 31.16
2015-03-04T00:00:00.000-0800 128.54 31.91 92.11 28.2 34.19 159.42 43.055 174.68 43.61 31.86 63.67 44.64 30.32
2015-03-05T00:00:00.000-0800 126.41 31.96 95.5 28.01 34.0 161.18 43.11 170.3 43.8 32.55 64.65 44.03 30.5
2015-03-06T00:00:00.000-0800 126.6 31.71 92.34 27.65 33.18 158.5 42.36 161.72 42.38 32.0 62.48 42.89 30.25
2015-03-07T00:00:00.000-0800 126.6 31.71 92.34 27.65 33.18 158.5 42.36 161.72 42.38 32.0 62.48 42.89 30.25
2015-03-08T00:00:00.000-0800 126.6 31.71 92.34 27.65 33.18 158.5 42.36 161.72 42.38 32.0 62.48 42.89 30.25
2015-03-09T00:00:00.000-0700 127.14 31.86 92.67 27.86 32.95 160.77 42.85 164.86 42.69 31.86 61.83 42.85 30.35
2015-03-10T00:00:00.000-0700 124.51 31.31 92.04 26.95 32.67 157.81 42.03 161.04 41.82 31.41 60.81 42.18 29.6
2015-03-11T00:00:00.000-0700 122.24 31.22 93.16 25.72 32.61 156.8 41.98 160.21 41.47 30.77 60.83 42.24 30.43
2015-03-12T00:00:00.000-0700 124.45 31.595 94.76 26.17 32.72 157.98 41.02 163.03 41.62 30.935 62.83 42.34 30.52
2015-03-13T00:00:00.000-0700 123.59 31.38 92.66 26.0 32.43 154.28 41.38 164.26 42.38 30.725 62.82 42.14 29.76
2015-03-14T00:00:00.000-0700 123.59 31.38 92.66 26.0 32.43 154.28 41.38 164.26 42.38 30.725 62.82 42.14 29.76
2015-03-15T00:00:00.000-0700 123.59 31.38 92.66 26.0 32.43 154.28 41.38 164.26 42.38 30.725 62.82 42.14 29.76
2015-03-16T00:00:00.000-0700 124.95 31.39 94.47 26.18 32.38 157.08 41.53 168.41 43.41 30.95 62.07 42.19 29.81
2015-03-17T00:00:00.000-0700 127.04 31.55 95.02 25.96 32.43 156.96 41.695 169.96 42.87 30.5 62.84 42.74 29.52
2015-03-18T00:00:00.000-0700 128.47 32.365 97.88 26.47 33.03 159.81 42.5 173.24 44.13 31.1 64.33 42.73 29.88
2015-03-19T00:00:00.000-0700 127.495 32.35 97.45 26.21 32.84 159.81 42.285 173.78 44.16 31.55 63.73 42.73 29.73
2015-03-20T00:00:00.000-0700 125.9 32.91 93.96 26.7 33.28 162.88 42.88 174.76 44.41 32.115 62.1 43.95 29.92
2015-03-21T00:00:00.000-0700 125.9 32.91 93.96 26.7 33.28 162.88 42.88 174.76 44.41 32.115 62.1 43.95 29.92
2015-03-22T00:00:00.000-0700 125.9 32.91 93.96 26.7 33.28 162.88 42.88 174.76 44.41 32.115 62.1 43.95 29.92
2015-03-23T00:00:00.000-0700 127.21 33.05 94.08 26.25 33.45 164.63 42.855 174.35 44.25 32.22 60.72 44.23 29.98
2015-03-24T00:00:00.000-0700 126.69 32.89 93.68 25.81 33.31 163.0 42.9 172.5 43.71 31.87 60.04 43.7 29.61
2015-03-25T00:00:00.000-0700 123.38 31.875 90.73 25.68 32.2 159.2 41.46 166.96 42.93 31.04 58.72 42.67 27.39
2015-03-26T00:00:00.000-0700 124.24 31.83 92.79 25.81 32.01 160.59 41.21 169.54 42.99 31.37 59.58 42.62 27.85
2015-03-27T00:00:00.000-0700 123.25 32.29 93.24 25.17 31.49 160.4 40.97 170.13 42.64 31.56 60.4 42.71 27.24
2015-03-28T00:00:00.000-0700 123.25 32.29 93.24 25.17 31.49 160.4 40.97 170.13 42.64 31.56 60.4 42.71 27.24
2015-03-29T00:00:00.000-0700 123.25 32.29 93.24 25.17 31.49 160.4 40.97 170.13 42.64 31.56 60.4 42.71 27.24
2015-03-30T00:00:00.000-0700 126.37 32.71 93.09 25.52 31.57 162.67 40.96 170.91 43.44 31.68 60.11 43.57 26.95
2015-03-31T00:00:00.000-0700 124.43 32.61 92.52 25.56 31.16 160.5 40.655 169.19 43.15 31.13 59.2 44.14 25.66
2015-04-01T00:00:00.000-0700 124.25 32.13 90.97 25.47 31.29 159.18 40.7 169.16 42.94 31.22 57.82 44.01 24.7
2015-04-02T00:00:00.000-0700 125.32 31.93 91.27 25.53 31.4 160.45 40.29 169.52 42.62 31.72 59.23 43.97 24.74
2015-04-03T00:00:00.000-0700 125.32 31.93 91.27 25.53 31.4 160.45 40.29 169.52 42.62 31.72 59.23 43.97 24.74
2015-04-04T00:00:00.000-0700 125.32 31.93 91.27 25.53 31.4 160.45 40.29 169.52 42.62 31.72 59.23 43.97 24.74
2015-04-05T00:00:00.000-0700 125.32 31.93 91.27 25.53 31.4 160.45 40.29 169.52 42.62 31.72 59.23 43.97 24.74
2015-04-06T00:00:00.000-0700 127.35 32.39 93.04 26.14 31.83 162.04 41.545 170.02 42.96 32.09 60.18 44.72 24.67
2015-04-07T00:00:00.000-0700 126.01 32.27 94.95 26.18 31.42 162.07 41.53 170.28 42.96 32.62 62.09 45.4 25.355
2015-04-08T00:00:00.000-0700 125.6 32.3 97.23 26.23 31.52 161.85 41.42 172.065 43.11 32.68 63.37 45.62 26.17
2015-04-09T00:00:00.000-0700 126.56 31.44 96.76 25.95 31.55 162.34 41.48 173.99 43.2 33.39 63.79 45.89 26.8
2015-04-10T00:00:00.000-0700 127.1 31.545 97.22 25.83 32.11 162.86 41.72 175.99 43.51 33.26 63.17 44.86 27.51
2015-04-11T00:00:00.000-0700 127.1 31.545 97.22 25.83 32.11 162.86 41.72 175.99 43.51 33.26 63.17 44.86 27.51
2015-04-12T00:00:00.000-0700 127.1 31.545 97.22 25.83 32.11 162.86 41.72 175.99 43.51 33.26 63.17 44.86 27.51
2015-04-13T00:00:00.000-0700 126.85 31.06 95.79 25.95 32.7 162.38 41.76 171.96 43.08 33.08 62.47 44.14 27.23
2015-04-14T00:00:00.000-0700 126.3 31.275 95.5 26.2 32.52 162.3 41.65 171.12 42.73 33.59 62.07 43.59 26.32
2015-04-15T00:00:00.000-0700 126.78 31.81 96.05 26.22 33.04 164.13 42.255 173.39 43.99 33.515 63.45 43.72 27.83
2015-04-16T00:00:00.000-0700 126.17 31.855 101.16 26.05 32.81 163.13 42.16 173.35 43.46 33.58 64.67 43.74 26.74
2015-04-17T00:00:00.000-0700 124.75 31.2 95.07 26.61 32.53 160.67 41.62 170.65 43.0 32.92 62.41 43.1 25.69
2015-04-18T00:00:00.000-0700 124.75 31.2 95.07 26.61 32.53 160.67 41.62 170.65 43.0 32.92 62.41 43.1 25.69
2015-04-19T00:00:00.000-0700 124.75 31.2 95.07 26.61 32.53 160.67 41.62 170.65 43.0 32.92 62.41 43.1 25.69
2015-04-20T00:00:00.000-0700 127.6 31.7 95.31 26.78 33.41 166.16 42.9 171.22 43.32 32.95 63.74 43.15 26.7
2015-04-21T00:00:00.000-0700 126.91 31.56 98.85 26.32 33.21 164.26 42.635 175.39 43.42 33.37 64.23 43.45 27.61
2015-04-22T00:00:00.000-0700 128.62 31.9 98.72 27.13 33.51 165.36 42.985 176.32 43.55 33.68 65.92 43.72 27.43
2015-04-23T00:00:00.000-0700 129.67 32.07 102.2 26.59 33.38 170.24 43.34 176.63 43.39 33.65 67.81 44.45 28.32
2015-04-24T00:00:00.000-0700 130.28 32.235 102.4 26.5 33.26 169.78 47.87 175.09 43.08 35.3 67.88 43.98 28.26
2015-04-25T00:00:00.000-0700 130.28 32.235 102.4 26.5 33.26 169.78 47.87 175.09 43.08 35.3 67.88 43.98 28.26
2015-04-26T00:00:00.000-0700 130.28 32.235 102.4 26.5 33.26 169.78 47.87 175.09 43.08 35.3 67.88 43.98 28.26
2015-04-27T00:00:00.000-0700 132.65 31.745 99.91 26.59 33.07 170.73 48.03 173.56 43.61 35.03 67.32 43.86 28.53
2015-04-28T00:00:00.000-0700 130.56 32.18 99.58 27.05 33.24 173.92 49.15 169.7 44.5 34.975 66.63 44.22 29.04
2015-04-29T00:00:00.000-0700 128.64 32.19 100.35 27.08 33.32 174.4 49.06 187.07 44.73 35.58 67.92 44.22 29.27
2015-04-30T00:00:00.000-0700 125.15 31.77 97.84 26.91 32.97 171.29 48.64 182.12 43.62 34.79 66.345 43.99 28.75
2015-05-01T00:00:00.000-0700 128.95 31.83 97.77 27.12 33.8 173.67 48.655 182.68 44.37 34.91 66.71 45.01 29.18
2015-05-02T00:00:00.000-0700 128.95 31.83 97.77 27.12 33.8 173.67 48.655 182.68 44.37 34.91 66.71 45.01 29.18
2015-05-03T00:00:00.000-0700 128.95 31.83 97.77 27.12 33.8 173.67 48.655 182.68 44.37 34.91 66.71 45.01 29.18
2015-05-04T00:00:00.000-0700 128.7 31.8 99.14 27.19 33.65 173.97 48.24 181.3 44.59 35.21 67.17 45.28 29.07
2015-05-05T00:00:00.000-0700 125.8 31.405 97.27 26.48 33.16 173.08 47.6 179.0 43.92 34.89 65.73 44.54 27.45
2015-05-06T00:00:00.000-0700 125.01 31.45 96.75 26.13 32.5 170.05 46.28 179.35 43.26 34.61 66.06 44.94 26.68
2015-05-07T00:00:00.000-0700 125.26 31.4 97.43 26.18 32.82 170.99 46.7 177.54 43.48 34.89 66.59 41.8 20.07
2015-05-08T00:00:00.000-0700 127.62 31.6 110.69 26.93 33.41 172.68 47.75 180.84 44.01 36.105 68.56 40.86 19.87
2015-05-09T00:00:00.000-0700 127.62 31.6 110.69 26.93 33.41 172.68 47.75 180.84 44.01 36.105 68.56 40.86 19.87
2015-05-10T00:00:00.000-0700 127.62 31.6 110.69 26.93 33.41 172.68 47.75 180.84 44.01 36.105 68.56 40.86 19.87
2015-05-11T00:00:00.000-0700 126.32 31.08 112.0 26.82 33.7 171.12 47.37 181.06 43.84 35.91 67.38 40.11 19.51
2015-05-12T00:00:00.000-0700 125.865 31.28 110.15 26.52 32.92 170.55 47.35 177.58 43.57 36.12 67.67 40.01 19.3
2015-05-13T00:00:00.000-0700 126.01 31.53 110.84 26.52 33.3 172.28 47.625 177.43 43.79 36.28 69.71 40.64 19.27
2015-05-14T00:00:00.000-0700 128.95 32.02 112.66 27.03 33.7 174.05 48.72 179.82 44.38 36.58 70.42 40.82 19.72
2015-05-15T00:00:00.000-0700 128.77 31.69 110.09 26.88 33.6 173.26 48.295 178.8 44.15 36.21 70.232 40.22 19.6
2015-05-16T00:00:00.000-0700 128.77 31.69 110.09 26.88 33.6 173.26 48.295 178.8 44.15 36.21 70.232 40.22 19.6
2015-05-17T00:00:00.000-0700 128.77 31.69 110.09 26.88 33.6 173.26 48.295 178.8 44.15 36.21 70.232 40.22 19.6
2015-05-18T00:00:00.000-0700 130.19 31.76 111.91 26.78 33.25 173.06 48.01 179.1 44.24 36.4 67.03 40.46 20.31
2015-05-19T00:00:00.000-0700 130.07 31.73 114.3 26.86 33.4 173.48 47.58 178.69 44.32 36.58 67.94 40.29 20.94
2015-05-20T00:00:00.000-0700 130.06 31.36 113.33 26.64 33.07 173.76 47.58 176.45 44.29 37.17 68.02 40.23 21.49
2015-05-21T00:00:00.000-0700 131.39 31.6 112.96 26.79 33.83 173.34 47.42 175.38 44.28 37.19 69.35 39.93 20.3
2015-05-22T00:00:00.000-0700 132.54 31.33 113.36 26.84 34.76 172.22 46.9 175.3 43.93 37.24 68.94 39.57 20.24
2015-05-23T00:00:00.000-0700 132.54 31.33 113.36 26.84 34.76 172.22 46.9 175.3 43.93 37.24 68.94 39.57 20.24
2015-05-24T00:00:00.000-0700 132.54 31.33 113.36 26.84 34.76 172.22 46.9 175.3 43.93 37.24 68.94 39.57 20.24
2015-05-25T00:00:00.000-0700 132.54 31.33 113.36 26.84 34.76 172.22 46.9 175.3 43.93 37.24 68.94 39.57 20.24
2015-05-26T00:00:00.000-0700 129.62 30.75 112.61 26.29 33.38 170.13 46.59 172.79 43.33 36.44 68.3 38.7 20.04
2015-05-27T00:00:00.000-0700 132.045 31.175 114.86 26.69 33.78 172.0 47.6108 175.31 44.14 36.855 69.35 38.83 20.07
2015-05-28T00:00:00.000-0700 131.78 30.7 113.23 26.52 33.65 171.71 47.45 176.68 43.86 36.84 71.07 38.73 20.16
2015-05-29T00:00:00.000-0700 130.28 30.45 113.21 26.34 33.4 169.65 46.89 175.98 43.49 36.17 67.62 38.94 20.18
2015-05-30T00:00:00.000-0700 130.28 30.45 113.21 26.34 33.4 169.65 46.89 175.98 43.49 36.17 67.62 38.94 20.18
2015-05-31T00:00:00.000-0700 130.28 30.45 113.21 26.34 33.4 169.65 46.89 175.98 43.49 36.17 67.62 38.94 20.18
2015-06-01T00:00:00.000-0700 130.535 30.11 112.9 26.68 33.76 170.18 47.23 176.14 43.79 36.37 66.46 38.62 19.71
2015-06-02T00:00:00.000-0700 129.96 29.9 112.9 26.62 33.88 169.65 46.92 175.88 43.7 36.28 66.165 39.25 20.07
2015-06-03T00:00:00.000-0700 130.12 30.02 114.87 27.05 33.96 169.92 46.85 177.8 43.97 36.98 66.78 40.0 20.88
2015-06-04T00:00:00.000-0700 129.36 29.62 113.51 27.01 33.3 168.38 46.389 174.89 43.77 36.59 65.39 39.12 20.53
2015-06-05T00:00:00.000-0700 128.65 29.67 115.6 27.34 32.92 167.4 46.14 180.43 43.81 37.32 68.66 39.17 21.44
2015-06-06T00:00:00.000-0700 128.65 29.67 115.6 27.34 32.92 167.4 46.14 180.43 43.81 37.32 68.66 39.17 21.44
2015-06-07T00:00:00.000-0700 128.65 29.67 115.6 27.34 32.92 167.4 46.14 180.43 43.81 37.32 68.66 39.17 21.44
2015-06-08T00:00:00.000-0700 127.8 29.45 113.64 26.66 32.69 165.34 45.73 176.87 43.1 36.36 67.95 38.87 21.61
2015-06-09T00:00:00.000-0700 127.42 29.43 116.27 26.71 32.58 165.68 45.65 176.78 43.07 36.22 67.39 38.77 21.28
2015-06-10T00:00:00.000-0700 128.88 30.08 117.73 27.0 32.91 168.92 46.61 181.76 43.94 36.86 69.48 39.04 21.54
2015-06-11T00:00:00.000-0700 128.59 30.265 119.0 27.3 32.52 168.78 46.44 180.64 44.28 36.58 69.16 38.56 21.68
2015-06-12T00:00:00.000-0700 127.17 30.14 119.08 27.07 32.41 166.99 45.97 178.75 44.34 36.65 68.915 38.57 22.47
2015-06-13T00:00:00.000-0700 127.17 30.14 119.08 27.07 32.41 166.99 45.97 178.75 44.34 36.65 68.915 38.57 22.47
2015-06-14T00:00:00.000-0700 127.17 30.14 119.08 27.07 32.41 166.99 45.97 178.75 44.34 36.65 68.915 38.57 22.47
2015-06-15T00:00:00.000-0700 126.92 29.805 120.75 26.94 31.71 166.26 45.475 174.09 43.72 35.97 70.2501 37.5 22.77
2015-06-16T00:00:00.000-0700 127.6 30.17 120.6 27.13 31.65 166.84 45.83 176.2 44.64 36.61 70.58 38.25 22.79
2015-06-17T00:00:00.000-0700 127.3 30.29 120.75 27.25 32.21 167.17 45.97 176.8 44.91 36.98 71.54 38.65 22.7
2015-06-18T00:00:00.000-0700 127.88 30.49 122.54 27.4 32.08 168.25 46.7 178.64 42.74 37.32 73.07 39.02 22.86
2015-06-19T00:00:00.000-0700 126.6 30.48 122.81 27.07 31.8 166.99 46.1 177.54 41.59 37.09 73.19 38.36 22.84
2015-06-20T00:00:00.000-0700 126.6 30.48 122.81 27.07 31.8 166.99 46.1 177.54 41.59 37.09 73.19 38.36 22.84
2015-06-21T00:00:00.000-0700 126.6 30.48 122.81 27.07 31.8 166.99 46.1 177.54 41.59 37.09 73.19 38.36 22.84
2015-06-22T00:00:00.000-0700 127.61 30.66 121.54 27.3 31.7 167.73 46.25 178.62 41.49 37.735 73.6 38.56 23.74
2015-06-23T00:00:00.000-0700 127.03 30.84 122.16 27.46 31.63 168.62 45.91 178.33 41.71 37.86 72.9 38.07 24.67
2015-06-24T00:00:00.000-0700 128.11 30.67 119.68 27.45 31.54 166.97 45.635 174.23 41.2 36.83 71.31 37.6 23.73
2015-06-25T00:00:00.000-0700 127.5 30.175 120.56 27.04 31.21 166.08 45.66 173.89 41.06 36.57 72.35 37.52 23.74
2015-06-26T00:00:00.000-0700 126.75 29.9 117.04 26.455 30.48 165.61 45.31 173.86 41.04 35.97 70.37 37.24 23.11
2015-06-27T00:00:00.000-0700 126.75 29.9 117.04 26.455 30.48 165.61 45.31 173.86 41.04 35.97 70.37 37.24 23.11
2015-06-28T00:00:00.000-0700 126.75 29.9 117.04 26.455 30.48 165.61 45.31 173.86 41.04 35.97 70.37 37.24 23.11
2015-06-29T00:00:00.000-0700 124.53 29.07 113.81 25.99 29.97 162.97 44.39 167.88 40.42 34.54 68.06 36.95 22.1
2015-06-30T00:00:00.000-0700 125.425 29.29 116.07 26.44 30.015 163.01 44.15 170.08 40.41 34.96 69.62 37.01 22.09
2015-07-01T00:00:00.000-0700 126.6 29.51 116.98 26.42 30.52 164.49 44.44 170.06 40.24 35.14 69.47 36.2 22.31
2015-07-02T00:00:00.000-0700 126.44 29.53 117.11 26.5 30.69 165.09 44.36 172.57 40.36 35.7908 69.72 36.02 21.81
2015-07-03T00:00:00.000-0700 126.44 29.53 117.11 26.5 30.69 165.09 44.36 172.57 40.36 35.7908 69.72 36.02 21.81
2015-07-04T00:00:00.000-0700 126.44 29.53 117.11 26.5 30.69 165.09 44.36 172.57 40.36 35.7908 69.72 36.02 21.81
2015-07-05T00:00:00.000-0700 126.44 29.53 117.11 26.5 30.69 165.09 44.36 172.57 40.36 35.7908 69.72 36.02 21.81
2015-07-06T00:00:00.000-0700 126.0 29.52 116.81 26.31 30.57 164.73 44.39 172.47 40.15 35.29 68.57 35.62 21.42
2015-07-07T00:00:00.000-0700 125.69 30.08 117.51 26.6 30.8 165.0 44.305 173.6 40.16 35.365 68.33 35.91 21.74
2015-07-08T00:00:00.000-0700 122.57 29.83 116.26 25.89 30.45 163.16 44.24 172.22 39.77 35.355 67.35 35.41 21.9
2015-07-09T00:00:00.000-0700 120.07 29.985 119.45 25.64 30.39 163.85 44.52 174.44 40.18 36.13 69.0 35.56 23.44
2015-07-10T00:00:00.000-0700 123.28 30.34 121.01 25.79 30.65 166.95 44.594 175.7 40.36 37.07 71.84 35.93 24.01
2015-07-11T00:00:00.000-0700 123.28 30.34 121.01 25.79 30.65 166.95 44.594 175.7 40.36 37.07 71.84 35.93 24.01
2015-07-12T00:00:00.000-0700 123.28 30.34 121.01 25.79 30.65 166.95 44.594 175.7 40.36 37.07 71.84 35.93 24.01
2015-07-13T00:00:00.000-0700 125.66 30.34 121.01 25.79 30.65 166.95 44.594 175.7 40.36 37.07 71.84 35.93 24.01
2015-07-14T00:00:00.000-0700 125.61 30.5 121.78 25.12 30.51 168.61 45.62 180.7 40.78 37.92 72.22 36.31 24.28
2015-07-15T00:00:00.000-0700 126.82 30.52 121.48 25.14 30.5 168.53 45.76 182.87 40.79 37.81 71.62 35.99 23.88
2015-07-16T00:00:00.000-0700 128.51 30.72 125.09 25.21 30.35 171.0 46.66 186.3 40.96 38.37 72.6 35.76 23.67
2015-07-17T00:00:00.000-0700 129.62 30.53 126.34 25.26 30.36 172.51 46.6 185.63 40.4 38.0 72.88 35.62 23.94
2015-07-18T00:00:00.000-0700 129.62 30.53 126.34 25.26 30.36 172.51 46.6 185.63 40.4 38.0 72.88 35.62 23.94
2015-07-19T00:00:00.000-0700 129.62 30.53 126.34 25.26 30.36 172.51 46.6 185.63 40.4 38.0 72.88 35.62 23.94
2015-07-20T00:00:00.000-0700 132.07 30.49 128.15 24.98 30.45 173.22 46.92 184.0 39.93 37.95 73.2 36.85 22.6
2015-07-21T00:00:00.000-0700 130.75 30.59 127.57 24.93 30.66 163.07 47.28 181.5 39.57 37.78 73.01 36.63 22.67
2015-07-22T00:00:00.000-0700 125.22 30.14 128.74 25.38 30.77 160.35 45.51 183.72 39.42 37.43 73.27 36.61 22.73
2015-07-23T00:00:00.000-0700 125.16 29.9 127.27 25.97 31.23 161.73 46.11 179.82 39.0 37.6 74.82 36.71 23.92
2015-07-24T00:00:00.000-0700 124.48 29.07 127.44 25.62 30.81 159.75 45.97 181.43 39.0 40.57 73.91 35.87 23.41
2015-07-25T00:00:00.000-0700 124.48 29.07 127.44 25.62 30.81 159.75 45.97 181.43 39.0 40.57 73.91 35.87 23.41
2015-07-26T00:00:00.000-0700 124.48 29.07 127.44 25.62 30.81 159.75 45.97 181.43 39.0 40.57 73.91 35.87 23.41
2015-07-27T00:00:00.000-0700 122.89 28.75 125.0 26.04 30.25 159.07 45.39 178.17 38.51 39.94 70.6 35.74 22.88
2015-07-28T00:00:00.000-0700 123.32 29.14 127.07 26.78 30.27 160.05 45.34 202.01 39.28 40.67 70.89 36.15 22.39
2015-07-29T00:00:00.000-0700 122.99 29.29 113.49 26.68 30.3 161.09 46.29 204.48 39.79 40.62 68.97 36.38 21.31
2015-07-30T00:00:00.000-0700 122.37 29.43 106.84 26.78 30.62 160.96 46.96 204.81 39.65 40.5 69.25 36.6 21.02
2015-07-31T00:00:00.000-0700 121.46 29.135 104.74 26.89 30.52 161.99 46.79 203.85 39.94 40.46 69.94 37.11 20.79
2015-08-01T00:00:00.000-0700 121.46 29.135 104.74 26.89 30.52 161.99 46.79 203.85 39.94 40.46 69.94 37.11 20.79
2015-08-02T00:00:00.000-0700 121.46 29.135 104.74 26.89 30.52 161.99 46.79 203.85 39.94 40.46 69.94 37.11 20.79
2015-08-03T00:00:00.000-0700 118.435 28.92 101.34 26.34 30.02 158.71 46.81 203.5 39.71 40.55 68.86 36.53 20.24
2015-08-04T00:00:00.000-0700 114.64 29.03 101.18 26.01 29.76 157.6 47.54 214.86 39.66 40.52 68.11 35.99 20.0
2015-08-05T00:00:00.000-0700 115.4 29.2 103.94 26.85 30.3 157.9 47.58 216.245 39.64 40.62 69.31 36.27 21.19
2015-08-06T00:00:00.000-0700 115.17 28.92 99.25 27.21 30.14 156.32 46.62 213.04 39.32 39.33 68.31 30.43 20.65
2015-08-07T00:00:00.000-0700 115.52 29.08 101.77 27.24 29.41 155.12 46.74 215.61 39.56 39.58 67.67 30.0 23.51
2015-08-08T00:00:00.000-0700 115.52 29.08 101.77 27.24 29.41 155.12 46.74 215.61 39.56 39.58 67.67 30.0 23.51
2015-08-09T00:00:00.000-0700 115.52 29.08 101.77 27.24 29.41 155.12 46.74 215.61 39.56 39.58 67.67 30.0 23.51
2015-08-10T00:00:00.000-0700 119.6901 29.47 103.9 27.32 30.24 156.75 47.33 218.85 39.89 40.17 69.4 30.9 23.15
2015-08-11T00:00:00.000-0700 113.5499 29.41 102.16 26.49 29.32 155.51 46.41 215.41 39.17 39.57 68.01 30.25 22.95
2015-08-12T00:00:00.000-0700 115.24 29.46 103.05 26.38 29.1 156.16 46.74 216.98 39.28 40.19 68.03 30.52 22.53
2015-08-13T00:00:00.000-0700 115.15 29.23 104.25 26.37 28.45 155.07 46.73 218.71 39.31 41.18 68.97 30.54 22.98
2015-08-14T00:00:00.000-0700 116.0 29.38 107.44 26.62 28.71 155.75 47.0 218.8 39.41 41.92 69.78 30.53 23.49
2015-08-15T00:00:00.000-0700 116.0 29.38 107.44 26.62 28.71 155.75 47.0 218.8 39.41 41.92 69.78 30.53 23.49
2015-08-16T00:00:00.000-0700 116.0 29.38 107.44 26.62 28.71 155.75 47.0 218.8 39.41 41.92 69.78 30.53 23.49
2015-08-17T00:00:00.000-0700 117.16 29.64 106.49 26.95 28.61 156.31 47.32 221.6 39.72 41.87 70.73 30.63 24.05
2015-08-18T00:00:00.000-0700 116.5 29.53 106.04 26.42 28.39 156.01 47.27 217.73 39.83 41.38 69.92 30.41 23.965
2015-08-19T00:00:00.000-0700 115.01 29.3 104.56 26.15 27.74 153.94 46.61 218.62 39.53 40.63 68.78 29.88 23.83
2015-08-20T00:00:00.000-0700 112.65 28.3 100.6 25.7 27.35 152.66 45.75 209.59 38.63 38.73 64.39 29.63 22.56
2015-08-21T00:00:00.000-0700 106.22 27.385 99.48 25.06 27.47 148.85 43.36 204.66 37.55 37.78 62.28 30.18 21.11
2015-08-22T00:00:00.000-0700 106.22 27.385 99.48 25.06 27.47 148.85 43.36 204.66 37.55 37.78 62.28 30.18 21.11
2015-08-23T00:00:00.000-0700 106.22 27.385 99.48 25.06 27.47 148.85 43.36 204.66 37.55 37.78 62.28 30.18 21.11
2015-08-24T00:00:00.000-0700 103.623 26.57 95.04 23.945 26.75 144.95 41.98 197.0 36.375 35.74 59.81 29.17 20.04
2015-08-25T00:00:00.000-0700 105.875 25.9 94.87 22.67 25.69 140.96 41.1348 196.17 35.45 35.97 59.68 27.7 19.64
2015-08-26T00:00:00.000-0700 109.625 26.61 96.36 24.18 27.1 146.7 42.73 201.14 36.91 37.28 61.48 29.05 19.66
2015-08-27T00:00:00.000-0700 112.844 27.13 97.33 25.02 27.79 148.54 43.9 200.87 36.82 38.63 64.24 29.75 20.0
2015-08-28T00:00:00.000-0700 113.28 27.26 97.16 24.96 28.03 147.98 43.945 200.99 37.46 38.22 62.78 29.49 19.93
2015-08-29T00:00:00.000-0700 113.28 27.26 97.16 24.96 28.03 147.98 43.945 200.99 37.46 38.22 62.78 29.49 19.93
2015-08-30T00:00:00.000-0700 113.28 27.26 97.16 24.96 28.03 147.98 43.945 200.99 37.46 38.22 62.78 29.49 19.93
2015-08-31T00:00:00.000-0700 112.76 27.29 94.17 24.87 28.06 147.89 43.52 198.7 37.09 37.86 61.97 29.23 19.8
2015-09-01T00:00:00.000-0700 107.96 26.51 91.72 24.01 27.81 142.68 41.82 196.04 36.01 37.13 59.59 28.54 19.58
2015-09-02T00:00:00.000-0700 112.34 27.2 95.5 24.13 28.0 145.05 43.36 197.02 36.75 37.97 59.1 28.73 19.97
2015-09-03T00:00:00.000-0700 110.37 27.46 95.08 24.17 28.13 146.78 43.5 198.37 36.9 38.56 59.92 28.46 19.96
2015-09-04T00:00:00.000-0700 109.27 27.07 94.68 23.67 26.99 143.7 42.61 195.12 36.27 38.23 58.27 28.42 19.69
2015-09-05T00:00:00.000-0700 109.27 27.07 94.68 23.67 26.99 143.7 42.61 195.12 36.27 38.23 58.27 28.42 19.69
2015-09-06T00:00:00.000-0700 109.27 27.07 94.68 23.67 26.99 143.7 42.61 195.12 36.27 38.23 58.27 28.42 19.69
2015-09-07T00:00:00.000-0700 109.27 27.07 94.68 23.67 26.99 143.7 42.61 195.12 36.27 38.23 58.27 28.42 19.69
2015-09-08T00:00:00.000-0700 112.21 28.08 95.66 24.24 27.59 147.23 43.89 201.25 37.68 39.59 60.95 29.44 20.06
2015-09-09T00:00:00.000-0700 110.15 27.39 93.42 23.91 27.26 145.05 43.07 198.34 37.09 39.0 59.18 29.32 19.71
2015-09-10T00:00:00.000-0700 112.57 27.52 93.65 23.91 27.33 146.2 43.29 198.41 37.61 39.2 60.06 29.41 17.67
2015-09-11T00:00:00.000-0700 114.21 27.72 93.8 24.6 27.15 147.37 43.48 201.14 37.92 39.29 59.65 29.59 17.98
2015-09-12T00:00:00.000-0700 114.21 27.72 93.8 24.6 27.15 147.37 43.48 201.14 37.92 39.29 59.65 29.59 17.98
2015-09-13T00:00:00.000-0700 114.21 27.72 93.8 24.6 27.15 147.37 43.48 201.14 37.92 39.29 59.65 29.59 17.98
2015-09-14T00:00:00.000-0700 115.3 27.74 94.39 24.35 27.04 145.65 43.05 200.95 37.56 38.96 59.35 29.39 17.51
2015-09-15T00:00:00.000-0700 116.28 28.11 93.01 24.54 27.11 147.53 43.98 207.95 37.99 39.58 59.43 29.8 17.6
2015-09-16T00:00:00.000-0700 116.35 28.22 91.52 24.86 28.47 148.41 44.3 209.87 38.27 39.89 59.21 30.04 17.88
2015-09-17T00:00:00.000-0700 113.92 27.95 84.81 24.7 27.57 148.14 44.25 209.9 36.74 40.03 58.65 29.56 18.62
2015-09-18T00:00:00.000-0700 113.45 27.57 84.68 24.09 26.54 144.51 43.48 206.68 36.38 38.73 58.54 29.11 18.69
2015-09-19T00:00:00.000-0700 113.45 27.57 84.68 24.09 26.54 144.51 43.48 206.68 36.38 38.73 58.54 29.11 18.69
2015-09-20T00:00:00.000-0700 113.45 27.57 84.68 24.09 26.54 144.51 43.48 206.68 36.38 38.73 58.54 29.11 18.69
2015-09-21T00:00:00.000-0700 115.21 27.75 86.48 24.15 26.44 146.48 44.11 208.5 36.83 39.92 59.51 28.81 18.5
2015-09-22T00:00:00.000-0700 113.432 27.34 83.5 23.76 25.65 144.43 43.91 207.07 36.19 39.5 57.63 28.23 17.98
2015-09-23T00:00:00.000-0700 114.32 27.33 84.56 23.82 25.49 143.66 43.87 208.28 35.99 40.13 58.61 28.35 17.76
2015-09-24T00:00:00.000-0700 115.0 27.51 85.59 23.76 25.26 144.41 43.94 205.19 36.06 39.5 57.86 28.43 17.78
2015-09-25T00:00:00.000-0700 114.72 27.36 82.99 23.78 25.01 145.42 43.92 205.19 36.05 39.08 57.21 28.84 17.1
2015-09-26T00:00:00.000-0700 114.72 27.36 82.99 23.78 25.01 145.42 43.92 205.19 36.05 39.08 57.21 28.84 17.1
2015-09-27T00:00:00.000-0700 114.72 27.36 82.99 23.78 25.01 145.42 43.92 205.19 36.05 39.08 57.21 28.84 17.1
2015-09-28T00:00:00.000-0700 112.44 26.73 79.25 23.51 24.57 142.52 43.29 195.28 35.44 36.74 54.02 28.2 16.39
2015-09-29T00:00:00.000-0700 109.06 26.83 77.58 23.13 24.65 142.47 43.44 194.72 35.51 35.29 54.44 29.2 15.22
2015-09-30T00:00:00.000-0700 109.95 27.3 79.78 24.16 25.61 144.97 44.2 196.47 36.12 36.45 55.35 28.96 15.58
2015-10-01T00:00:00.000-0700 109.57 27.38 82.2 24.21 25.35 143.59 44.62 199.3 36.24 36.62 55.92 28.12 15.06
2015-10-02T00:00:00.000-0700 110.38 27.68 84.31 24.69 26.07 144.58 45.57 198.84 36.89 37.8 56.36 29.02 15.6
2015-10-03T00:00:00.000-0700 110.38 27.68 84.31 24.69 26.07 144.58 45.57 198.84 36.89 37.8 56.36 29.02 15.6
2015-10-04T00:00:00.000-0700 110.38 27.68 84.31 24.69 26.07 144.58 45.57 198.84 36.89 37.8 56.36 29.02 15.6
2015-10-05T00:00:00.000-0700 110.78 28.34 83.19 25.31 27.18 149.04 46.61 200.99 37.59 38.63 55.3 29.2 15.97
2015-10-06T00:00:00.000-0700 111.31 28.45 80.93 25.81 28.0 148.78 46.75 197.58 37.73 37.86 55.29 29.49 15.76
2015-10-07T00:00:00.000-0700 110.67 28.635 83.09 25.96 28.01 150.09 46.78 199.58 37.66 37.69 57.44 29.93 16.49
2015-10-08T00:00:00.000-0700 109.5 28.78 79.56 27.18 29.18 152.28 47.45 199.53 37.89 36.86 56.37 29.76 16.5
2015-10-09T00:00:00.000-0700 112.09 29.0 83.0 27.86 29.3 152.39 47.11 205.25 38.1 38.22 58.21 29.47 16.15
2015-10-10T00:00:00.000-0700 112.09 29.0 83.0 27.86 29.3 152.39 47.11 205.25 38.1 38.22 58.21 29.47 16.15
2015-10-11T00:00:00.000-0700 112.09 29.0 83.0 27.86 29.3 152.39 47.11 205.25 38.1 38.22 58.21 29.47 16.15
2015-10-12T00:00:00.000-0700 111.6 28.92 84.46 28.35 29.3 151.14 47.0 206.11 38.04 38.71 57.25 28.58 15.98
2015-10-13T00:00:00.000-0700 111.79 28.69 84.24 27.55 29.23 149.62 46.89 199.38 37.82 35.84 55.95 28.37 15.6
2015-10-14T00:00:00.000-0700 110.21 28.64 81.77 27.11 29.42 150.01 46.68 196.75 37.26 35.77 54.96 28.42 15.36
2015-10-15T00:00:00.000-0700 111.8 28.9 82.95 27.79 28.77 150.09 47.01 199.79 37.55 36.72 56.21 28.62 16.42
2015-10-16T00:00:00.000-0700 111.04 28.92 85.05 27.77 28.86 150.39 47.51 203.11 37.37 36.77 57.68 28.58 16.74
2015-10-17T00:00:00.000-0700 111.04 28.92 85.05 27.77 28.86 150.39 47.51 203.11 37.37 36.77 57.68 28.58 16.74
2015-10-18T00:00:00.000-0700 111.04 28.92 85.05 27.77 28.86 150.39 47.51 203.11 37.37 36.77 57.68 28.58 16.74
2015-10-19T00:00:00.000-0700 111.73 28.48 85.52 27.72 28.98 149.22 47.62 203.73 36.87 36.81 58.79 28.86 16.59
2015-10-20T00:00:00.000-0700 113.78 28.37 86.81 27.49 28.56 140.64 47.77 197.11 36.86 35.09 57.76 28.96 16.51
2015-10-21T00:00:00.000-0700 113.76 27.67 82.25 25.77 28.23 140.92 47.2 190.36 36.62 33.62 54.96 28.0 15.85
2015-10-22T00:00:00.000-0700 115.47 28.01 83.82 25.78 28.77 144.09 48.03 194.92 37.79 34.67 57.06 28.15 15.58
2015-10-23T00:00:00.000-0700 119.08 27.75 83.7 26.1 29.03 144.68 53.03 188.18 38.07 30.8 56.25 28.28 16.02
2015-10-24T00:00:00.000-0700 119.08 27.75 83.7 26.1 29.03 144.68 53.03 188.18 38.07 30.8 56.25 28.28 16.02
2015-10-25T00:00:00.000-0700 119.08 27.75 83.7 26.1 29.03 144.68 53.03 188.18 38.07 30.8 56.25 28.28 16.02
2015-10-26T00:00:00.000-0700 115.21 27.87 82.53 26.17 28.07 143.66 54.25 196.26 38.37 30.12 55.04 28.14 15.59
2015-10-27T00:00:00.000-0700 114.55 27.38 80.96 26.04 27.45 137.86 53.69 168.24 38.34 30.21 54.64 27.79 15.47
2015-10-28T00:00:00.000-0700 119.28 27.75 83.94 26.15 27.98 140.83 53.96 178.85 38.88 31.99 57.24 28.69 15.93
2015-10-29T00:00:00.000-0700 120.53 27.69 81.72 26.16 27.37 140.55 53.36 174.38 38.86 31.73 55.98 28.08 15.39
2015-10-30T00:00:00.000-0700 119.5 27.7 83.96 26.22 26.96 140.08 52.643 172.07 38.84 31.37 56.16 28.11 15.97
2015-10-31T00:00:00.000-0700 119.5 27.7 83.96 26.22 26.96 140.08 52.643 172.07 38.84 31.37 56.16 28.11 15.97
2015-11-01T00:00:00.000-0700 119.5 27.7 83.96 26.22 26.96 140.08 52.643 172.07 38.84 31.37 56.16 28.11 15.97
2015-11-02T00:00:00.000-0800 121.18 27.57 86.19 26.35 13.83 140.37 53.24 176.16 39.75 31.64 56.81 29.1 16.52
2015-11-03T00:00:00.000-0800 122.57 27.86 85.93 26.25 14.29 141.88 54.15 177.12 40.2 30.95 57.14 29.42 17.25
2015-11-04T00:00:00.000-0800 122.0 27.61 87.81 26.2 14.14 141.63 54.4 180.23 40.48 31.14 57.47 29.79 17.08
2015-11-05T00:00:00.000-0800 120.92 27.44 84.39 26.04 14.05 139.89 54.38 176.92 40.35 30.48 55.35 25.58 15.5
2015-11-06T00:00:00.000-0800 121.06 27.4 102.44 25.95 14.01 138.25 54.92 177.65 40.62 32.94 60.17 28.83 16.93
2015-11-07T00:00:00.000-0800 121.06 27.4 102.44 25.95 14.01 138.25 54.92 177.65 40.62 32.94 60.17 28.83 16.93
2015-11-08T00:00:00.000-0800 121.06 27.4 102.44 25.95 14.01 138.25 54.92 177.65 40.62 32.94 60.17 28.83 16.93
2015-11-09T00:00:00.000-0800 120.57 27.07 100.05 25.83 13.87 135.31 54.16 174.86 40.1 32.02 59.07 27.67 16.74
2015-11-10T00:00:00.000-0800 116.73 27.06 96.29 25.25 14.12 135.47 53.51 174.45 39.92 31.8 57.67 27.66 16.5
2015-11-11T00:00:00.000-0800 116.12 27.195 96.75 25.46 13.92 135.02 53.65 174.85 39.04 32.02 57.17 27.0 16.6
2015-11-12T00:00:00.000-0800 115.72 26.79 95.1 25.02 13.31 133.04 53.32 172.72 38.63 31.53 58.78 26.58 16.2
2015-11-13T00:00:00.000-0800 112.34 26.53 93.58 25.03 13.11 131.75 52.84 168.87 37.3 31.52 59.0 26.12 15.7
2015-11-14T00:00:00.000-0800 112.34 26.53 93.58 25.03 13.11 131.75 52.84 168.87 37.3 31.52 59.0 26.12 15.7
2015-11-15T00:00:00.000-0800 112.34 26.53 93.58 25.03 13.11 131.75 52.84 168.87 37.3 31.52 59.0 26.12 15.7
2015-11-16T00:00:00.000-0800 114.175 26.87 92.52 25.27 13.35 133.71 53.765 171.58 38.12 31.17 60.03 26.37 16.46
2015-11-17T00:00:00.000-0800 113.69 26.9 93.74 25.17 13.28 133.82 52.97 171.93 38.13 31.3 61.22 26.53 16.21
2015-11-18T00:00:00.000-0800 117.29 28.04 95.09 25.15 13.64 135.82 53.85 174.82 38.7 32.04 61.92 28.19 16.43
2015-11-19T00:00:00.000-0800 118.78 28.34 93.87 25.04 13.79 136.74 53.94 173.0 39.02 32.59 62.76 28.42 16.64
2015-11-20T00:00:00.000-0800 119.3 28.28 93.59 25.33 14.06 138.5 54.19 173.21 39.34 32.52 60.54 28.45 16.83
2015-11-21T00:00:00.000-0800 119.3 28.28 93.59 25.33 14.06 138.5 54.19 173.21 39.34 32.52 60.54 28.45 16.83
2015-11-22T00:00:00.000-0800 119.3 28.28 93.59 25.33 14.06 138.5 54.19 173.21 39.34 32.52 60.54 28.45 16.83
2015-11-23T00:00:00.000-0800 117.76 28.18 94.73 25.27 14.23 138.46 54.19 173.68 39.14 31.94 58.49 29.65 16.83
2015-11-24T00:00:00.000-0800 118.88 28.2 95.02 25.47 14.64 138.6 54.25 173.3 39.46 32.57 59.5 29.88 17.7
2015-11-25T00:00:00.000-0800 118.03 28.08 96.96 25.42 12.64 138.0 53.69 175.4 39.26 32.705 59.14 29.89 17.73
2015-11-26T00:00:00.000-0800 118.03 28.08 96.96 25.42 12.64 138.0 53.69 175.4 39.26 32.705 59.14 29.89 17.73
2015-11-27T00:00:00.000-0800 117.81 28.2 97.67 25.4 12.61 138.46 53.93 175.56 39.18 32.8 59.84 29.8 17.4
2015-11-28T00:00:00.000-0800 117.81 28.2 97.67 25.4 12.61 138.46 53.93 175.56 39.18 32.8 59.84 29.8 17.4
2015-11-29T00:00:00.000-0800 117.81 28.2 97.67 25.4 12.61 138.46 53.93 175.56 39.18 32.8 59.84 29.8 17.4
2015-11-30T00:00:00.000-0800 118.35 28.11 97.03 25.34 12.54 139.42 54.35 173.37 38.97 31.81 59.5 29.91 17.85
2015-12-01T00:00:00.000-0800 117.34 28.19 97.61 25.54 12.74 141.28 55.22 177.19 39.23 32.53 60.67 30.63 17.8
2015-12-02T00:00:00.000-0800 116.28 28.04 94.99 25.82 11.95 139.7 55.21 176.19 38.7 32.36 59.93 30.03 17.42
2015-12-03T00:00:00.000-0800 115.17 28.28 92.45 25.57 12.15 138.92 54.21 173.58 37.81 31.38 58.27 29.44 16.86
2015-12-04T00:00:00.000-0800 119.03 29.0 94.1 25.92 12.32 140.43 55.91 176.84 39.16 32.06 58.7 29.69 16.8
2015-12-05T00:00:00.000-0800 119.03 29.0 94.1 25.92 12.32 140.43 55.91 176.84 39.16 32.06 58.7 29.69 16.8
2015-12-06T00:00:00.000-0800 119.03 29.0 94.1 25.92 12.32 140.43 55.91 176.84 39.16 32.06 58.7 29.69 16.8
2015-12-07T00:00:00.000-0800 118.28 28.44 92.57 26.14 12.15 139.55 55.81 173.73 38.82 31.05 57.8 28.77 16.41
2015-12-08T00:00:00.000-0800 118.23 27.94 93.63 26.0 12.19 138.05 55.79 175.49 38.73 31.19 57.97 28.14 16.7
2015-12-09T00:00:00.000-0800 115.62 27.57 91.25 26.0 12.11 136.61 54.98 172.53 38.58 31.08 56.74 28.15 16.5
2015-12-10T00:00:00.000-0800 116.17 27.69 92.43 26.05 12.36 136.78 55.27 172.75 38.19 31.15 56.82 28.64 16.99
2015-12-11T00:00:00.000-0800 113.18 27.15 88.23 25.91 12.21 134.57 54.06 174.14 37.21 30.38 53.22 27.07 16.44
2015-12-12T00:00:00.000-0800 113.18 27.15 88.23 25.91 12.21 134.57 54.06 174.14 37.21 30.38 53.22 27.07 16.44
2015-12-13T00:00:00.000-0800 113.18 27.15 88.23 25.91 12.21 134.57 54.06 174.14 37.21 30.38 53.22 27.07 16.44
2015-12-14T00:00:00.000-0800 112.48 27.74 88.24 25.75 12.16 135.93 55.14 175.25 37.65 30.37 52.4 26.88 16.26
2015-12-15T00:00:00.000-0800 110.49 28.13 89.45 25.9 12.21 137.79 55.2 178.93 38.21 30.52 53.83 26.93 16.6
2015-12-16T00:00:00.000-0800 111.338 28.6 92.2 26.0 12.26 139.29 56.13 177.12 38.91 31.01 55.42 27.56 17.2
2015-12-17T00:00:00.000-0800 108.98 28.5 90.21 25.57 11.9 136.75 55.7 173.51 36.93 30.64 54.3 26.82 17.15
2015-12-18T00:00:00.000-0800 105.9 28.22 88.67 25.35 11.51 134.9 54.13 175.74 36.35 29.84 53.64 26.19 17.36
2015-12-19T00:00:00.000-0800 105.9 28.22 88.67 25.35 11.51 134.9 54.13 175.74 36.35 29.84 53.64 26.19 17.36
2015-12-20T00:00:00.000-0800 105.9 28.22 88.67 25.35 11.51 134.9 54.13 175.74 36.35 29.84 53.64 26.19 17.36
2015-12-21T00:00:00.000-0800 107.33 28.095 89.06 25.53 11.43 135.5 54.8 177.37 36.42 30.31 54.46 26.31 17.49
2015-12-22T00:00:00.000-0800 107.23 28.66 93.2 25.77 11.66 137.93 55.35 177.14 36.59 30.79 54.37 26.94 17.95
2015-12-23T00:00:00.000-0800 108.62 29.18 95.17 26.04 11.75 138.54 55.82 177.45 36.93 31.18 56.51 27.2 18.59
2015-12-24T00:00:00.000-0800 108.03 28.97 95.48 26.01 11.73 138.25 55.67 177.61 37.01 31.13 56.78 27.22 19.01
2015-12-25T00:00:00.000-0800 108.03 28.97 95.48 26.01 11.73 138.25 55.67 177.61 37.01 31.13 56.78 27.22 19.01
2015-12-26T00:00:00.000-0800 108.03 28.97 95.48 26.01 11.73 138.25 55.67 177.61 37.01 31.13 56.78 27.22 19.01
2015-12-27T00:00:00.000-0800 108.03 28.97 95.48 26.01 11.73 138.25 55.67 177.61 37.01 31.13 56.78 27.22 19.01
2015-12-28T00:00:00.000-0800 106.82 28.94 95.06 25.91 11.63 137.61 55.95 176.41 36.79 31.4 57.66 26.81 19.08
2015-12-29T00:00:00.000-0800 108.74 29.35 95.09 25.98 11.86 139.78 56.55 180.64 37.04 32.01 58.4 27.07 19.24
2015-12-30T00:00:00.000-0800 107.32 29.11 94.75 25.72 11.84 139.34 56.31 178.92 36.92 32.015 58.79 26.82 19.16
2015-12-31T00:00:00.000-0800 105.26 28.56 94.22 25.68 11.84 137.62 55.48 179.29 36.53 31.66 58.81 26.42 18.8
2016-01-01T00:00:00.000-0800 105.26 28.56 94.22 25.68 11.84 137.62 55.48 179.29 36.53 31.66 58.81 26.42 18.8
2016-01-02T00:00:00.000-0800 105.26 28.56 94.22 25.68 11.84 137.62 55.48 179.29 36.53 31.66 58.81 26.42 18.8
2016-01-03T00:00:00.000-0800 105.26 28.56 94.22 25.68 11.84 137.62 55.48 179.29 36.53 31.66 58.81 26.42 18.8
2016-01-04T00:00:00.000-0800 105.235 28.125 93.79 25.59 11.6 135.95 54.545 171.06 35.75 30.61 57.53 26.25 18.19
2016-01-05T00:00:00.000-0800 102.714 27.88 94.3 25.51 11.71 135.85 55.05 171.77 35.64 30.31 57.2 25.52 18.11
2016-01-06T00:00:00.000-0800 100.7 27.27 93.5 25.25 11.29 135.17 54.05 169.27 35.82 28.5 55.19 24.48 18.21
2016-01-07T00:00:00.000-0800 96.45 26.38 88.57 24.85 10.77 132.86 52.17 161.03 35.04 28.47 52.98 23.66 17.02
2016-01-08T00:00:00.000-0800 96.96 26.35 86.43 24.47 10.58 131.63 52.33 148.15 34.65 28.55 52.01 23.47 16.3
2016-01-09T00:00:00.000-0800 96.96 26.35 86.43 24.47 10.58 131.63 52.33 148.15 34.65 28.55 52.01 23.47 16.3
2016-01-10T00:00:00.000-0800 96.96 26.35 86.43 24.47 10.58 131.63 52.33 148.15 34.65 28.55 52.01 23.47 16.3
2016-01-11T00:00:00.000-0800 98.53 26.2 87.13 24.42 10.65 133.23 52.3 152.45 34.94 28.64 51.35 22.89 16.61
2016-01-12T00:00:00.000-0800 99.96 26.77 88.49 24.66 10.82 132.9 52.77 156.19 35.37 28.66 52.3 23.05 17.12
2016-01-13T00:00:00.000-0800 97.371 26.35 82.15 24.19 10.58 131.17 51.64 150.34 34.08 28.0 50.27 22.69 18.0
2016-01-14T00:00:00.000-0800 99.52 27.06 82.73 24.67 10.62 132.91 53.11 152.53 34.79 28.33 50.76 23.15 19.74
2016-01-15T00:00:00.000-0800 97.02 26.5103 81.06 25.01 10.11 130.03 50.91 149.93 34.12 27.24 50.37 22.96 18.65
2016-01-16T00:00:00.000-0800 97.02 26.5103 81.06 25.01 10.11 130.03 50.91 149.93 34.12 27.24 50.37 22.96 18.65
2016-01-17T00:00:00.000-0800 97.02 26.5103 81.06 25.01 10.11 130.03 50.91 149.93 34.12 27.24 50.37 22.96 18.65
2016-01-18T00:00:00.000-0800 97.02 26.5103 81.06 25.01 10.11 130.03 50.91 149.93 34.12 27.24 50.37 22.96 18.65
2016-01-19T00:00:00.000-0800 96.66 26.1 80.89 24.35 9.76 128.11 50.56 146.34 34.55 25.98 48.45 22.69 17.61
2016-01-20T00:00:00.000-0800 96.826 25.83 79.41 24.11 9.55 121.86 50.79 149.69 33.94 25.88 47.75 23.28 17.83
2016-01-21T00:00:00.000-0800 96.3 26.17 80.74 23.98 9.94 122.91 50.48 150.22 34.12 25.83 48.49 23.4 17.37
2016-01-22T00:00:00.000-0800 101.42 26.73 81.34 24.45 9.8 122.5 52.28 149.91 34.8 26.58 50.23 23.37 18.37
2016-01-23T00:00:00.000-0800 101.42 26.73 81.34 24.45 9.8 122.5 52.28 149.91 34.8 26.58 50.23 23.37 18.37
2016-01-24T00:00:00.000-0800 101.42 26.73 81.34 24.45 9.8 122.5 52.28 149.91 34.8 26.58 50.23 23.37 18.37
2016-01-25T00:00:00.000-0800 99.41 26.25 77.75 23.98 9.49 122.08 51.79 145.88 34.34 25.09 48.66 22.76 17.74
2016-01-26T00:00:00.000-0800 99.99 26.85 77.99 24.3 9.64 122.59 52.17 147.15 35.23 25.34 48.62 22.94 17.79
2016-01-27T00:00:00.000-0800 93.441 27.73 73.57 23.9 9.62 120.96 51.22 142.39 34.91 24.05 47.07 22.96 17.02
2016-01-28T00:00:00.000-0800 94.09 28.195 77.85 24.22 9.48 122.22 52.055 167.26 35.33 24.14 44.34 23.15 16.97
2016-01-29T00:00:00.000-0800 97.085 28.73 80.24 24.77 9.71 124.79 55.09 172.51 36.31 25.04 46.29 24.34 18.82
2016-01-30T00:00:00.000-0800 97.085 28.73 80.24 24.77 9.71 124.79 55.09 172.51 36.31 25.04 46.29 24.34 18.82
2016-01-31T00:00:00.000-0800 97.085 28.73 80.24 24.77 9.71 124.79 55.09 172.51 36.31 25.04 46.29 24.34 18.82
2016-02-01T00:00:00.000-0800 96.43 28.46 80.9 24.52 9.97 124.83 54.71 173.34 36.32 25.37 47.9 24.33 18.71
2016-02-02T00:00:00.000-0800 94.48 27.63 78.83 24.3 9.88 122.94 53.0 171.89 35.35 24.94 45.81 23.27 17.53
2016-02-03T00:00:00.000-0800 96.35 27.87 79.61 24.47 9.65 124.72 52.16 171.48 35.69 25.05 47.0 23.69 17.56
2016-02-04T00:00:00.000-0800 96.6 28.15 81.75 24.75 9.86 127.65 52.0 167.84 36.45 24.93 47.09 25.58 17.0
2016-02-05T00:00:00.000-0800 94.02 28.32 41.33 24.55 9.91 128.57 50.16 156.46 35.7 21.21 36.23 23.54 14.64
2016-02-06T00:00:00.000-0800 94.02 28.32 41.33 24.55 9.91 128.57 50.16 156.46 35.7 21.21 36.23 23.54 14.64
2016-02-07T00:00:00.000-0800 94.02 28.32 41.33 24.55 9.91 128.57 50.16 156.46 35.7 21.21 36.23 23.54 14.64
2016-02-08T00:00:00.000-0800 95.01 27.45 37.22 24.2 9.37 126.98 49.41 155.0 35.61 19.65 31.92 23.12 14.74
2016-02-09T00:00:00.000-0800 94.99 27.57 39.23 24.17 9.19 124.07 49.28 151.96 35.08 19.16 31.92 22.6 13.62
2016-02-10T00:00:00.000-0800 94.27 27.71 39.86 24.55 9.28 120.19 49.71 150.15 35.2 18.88 31.64 23.24 13.88
2016-02-11T00:00:00.000-0800 93.7 27.15 39.98 24.16 9.02 117.85 49.69 149.57 34.84 19.42 30.86 22.62 13.82
2016-02-12T00:00:00.000-0800 93.99 27.7 40.25 24.13 9.42 121.04 50.483 151.9 35.54 17.61 31.32 23.07 16.16
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<style>
body {
font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Helvetica, "Helvetica Neue", Helvetica, sans-serif;
margin: 30px auto;
width: 960px;
position: relative;
}
header {
padding: 6px 0;
}
.group {
margin-bottom: 1em;
}
.axis {
font: 10px sans-serif;
position: fixed;
pointer-events: none;
z-index: 2;
}
.axis text {
-webkit-transition: fill-opacity 250ms linear;
font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Helvetica, "Helvetica Neue", Helvetica, sans-serif;
}
.axis path {
display: none;
}
.axis line {
stroke: #000;
shape-rendering: crispEdges;
}
.axis.top {
background-image: linear-gradient(top, #fff 0%, rgba(255,255,255,0) 100%);
background-image: -o-linear-gradient(top, #fff 0%, rgba(255,255,255,0) 100%);
background-image: -moz-linear-gradient(top, #fff 0%, rgba(255,255,255,0) 100%);
background-image: -webkit-linear-gradient(top, #fff 0%, rgba(255,255,255,0) 100%);
background-image: -ms-linear-gradient(top, #fff 0%, rgba(255,255,255,0) 100%);
top: 0px;
padding: 0 0 24px 0;
}
.axis.bottom {
background-image: linear-gradient(bottom, #fff 0%, rgba(255,255,255,0) 100%);
background-image: -o-linear-gradient(bottom, #fff 0%, rgba(255,255,255,0) 100%);
background-image: -moz-linear-gradient(bottom, #fff 0%, rgba(255,255,255,0) 100%);
background-image: -webkit-linear-gradient(bottom, #fff 0%, rgba(255,255,255,0) 100%);
background-image: -ms-linear-gradient(bottom, #fff 0%, rgba(255,255,255,0) 100%);
bottom: 0px;
padding: 24px 0 0 0;
}
.horizon {
border-bottom: solid 1px #000;
overflow: hidden;
position: relative;
}
.horizon {
border-top: solid 1px #000;
border-bottom: solid 1px #000;
}
.horizon + .horizon {
border-top: none;
}
.horizon canvas {
display: block;
}
.horizon .title,
.horizon .value {
bottom: 0;
line-height: 30px;
margin: 0 6px;
position: absolute;
text-shadow: 0 1px 0 rgba(255,255,255,.5);
white-space: nowrap;
font-size: 12px;
}
.horizon .title {
left: 0;
}
.horizon .value {
right: 0;
}
.line {
background: #000;
z-index: 2;
}
</style>
</head>
<body id="demo">
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js" charset="utf-8"></script>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="cubism.js" charset="utf-8"></script>
<script>
var dF = new Date();
var compareToBaseline = 1,
showChangeInPercent = 1,
smoothen = 1,
width = 960;
d3.csv("data.csv", function(error, data) {
// data = data.slice(200)
var time = _.map(data[0]['_time'], function(d) { return new Date(d); } );
data = _.map(data, function(d) { delete(d['_time']); return d;});
var timeScale = d3.time.scale()
.domain(d3.extent(time));
var context = cubism.context()
// .scale(timeScale)
.serverDelay(0) //correct sign so axis is correct & not in future.
.step(60 * 60 * 24 * 1000 * (data.length / width))
.size(width)
.stop();
d3.select("#demo").selectAll(".axis")
.data(["top", "bottom"])
.enter().append("div")
.attr("class", function(d) { return d + " axis"; })
.each(function(d) { d3.select(this).call(context.axis().ticks(12).orient(d)); });
d3.select("body").append("div")
.attr("class", "rule")
.call(context.rule());
context.on("focus", function(i) {
if (i > 100) {
d3.selectAll(".value").style({
"right": i == null ? null : context.size() - i + "px",
"left": null
});
} else {
d3.selectAll(".value").style({
"left": i == null ? null : i + "px",
"right": null
});
}
});
var stocks = _.keys(data[0]);
data = _.map(stocks, function(stockSymbol, i) {
var compare = +data[0][stockSymbol];
return _.map(d3.range(data.length), function(idx) {
return compareToBaseline ?
showChangeInPercent ? ((+data[idx][stockSymbol] - compare) / compare) : (+data[idx][stockSymbol] - compare)
: +data[idx][stockSymbol];
})
});
function metric(name, values) {
var num = context.size();
console.log(num)
return context.metric(function(start, stop, step, callback) {
var data = _.map(d3.range(num), function(d) {
var value = values[0];
var idxCalculated = values.length / num * d;
var idx = Math.floor(idxCalculated);
if (d > 0) {
var i = d3.interpolateNumber(values[idx-1], values[idx]);
value = smoothen ? i(idxCalculated % 1) : values[idx]
}
return value;
})
callback(null, data);
}, name.substr(5));
};
var metrics = _.map(data, function(d, i) {
return metric(stocks[i], data[i]);
});
var stocks = _.keys(data[0]);
d3.select("body").selectAll(".horizon")
.data(metrics)
.enter().insert("div", ".bottom")
.attr("class", "horizon")
.call(context.horizon()
.mode("mirror")
.colors(["#E06C4C", "#EBA18F", "#F5D2CA", "#C0E2F0", "#7AC4E0", "#1DA4D1"])
.format(compareToBaseline ? showChangeInPercent ? d3.format("+,.3p") : d3.format("+,.2f") : d3.format(".2f")));
})
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment