Path: blob/master/sandbox/RFinance2014/libraries/widgets/nvd3/js/horizon.js
1433 views
(function() {1d3.horizon = function() {2var bands = 1, // between 1 and 5, typically3mode = "offset", // or mirror4interpolate = "linear", // or basis, monotone, step-before, etc.5x = d3_horizonX,6y = d3_horizonY,7w = 960,8h = 40,9duration = 0;1011var color = d3.scale.linear()12.domain([-1, 0, 1])13.range(["#d62728", "#fff", "#1f77b4"]);1415// For each small multiple…16function horizon(g) {17g.each(function(d, i) {18var g = d3.select(this),19n = 2 * bands + 1,20xMin = Infinity,21xMax = -Infinity,22yMax = -Infinity,23x0, // old x-scale24y0, // old y-scale25id; // unique id for paths2627// Compute x- and y-values along with extents.28var data = d.map(function(d, i) {29var xv = x.call(this, d, i),30yv = y.call(this, d, i);31if (xv < xMin) xMin = xv;32if (xv > xMax) xMax = xv;33if (-yv > yMax) yMax = -yv;34if (yv > yMax) yMax = yv;35return [xv, yv];36});3738// Compute the new x- and y-scales, and transform.39var x1 = d3.scale.linear().domain([xMin, xMax]).range([0, w]),40y1 = d3.scale.linear().domain([0, yMax]).range([0, h * bands]),41t1 = d3_horizonTransform(bands, h, mode);4243// Retrieve the old scales, if this is an update.44if (this.__chart__) {45x0 = this.__chart__.x;46y0 = this.__chart__.y;47t0 = this.__chart__.t;48id = this.__chart__.id;49} else {50x0 = x1.copy();51y0 = y1.copy();52t0 = t1;53id = ++d3_horizonId;54}5556// We'll use a defs to store the area path and the clip path.57var defs = g.selectAll("defs")58.data([null]);5960// The clip path is a simple rect.61defs.enter().append("defs").append("clipPath")62.attr("id", "d3_horizon_clip" + id)63.append("rect")64.attr("width", w)65.attr("height", h);6667defs.select("rect").transition()68.duration(duration)69.attr("width", w)70.attr("height", h);7172// We'll use a container to clip all horizon layers at once.73g.selectAll("g")74.data([null])75.enter().append("g")76.attr("clip-path", "url(#d3_horizon_clip" + id + ")");7778// Instantiate each copy of the path with different transforms.79var path = g.select("g").selectAll("path")80.data(d3.range(-1, -bands - 1, -1).concat(d3.range(1, bands + 1)), Number);8182var d0 = d3_horizonArea83.interpolate(interpolate)84.x(function(d) { return x0(d[0]); })85.y0(h * bands)86.y1(function(d) { return h * bands - y0(d[1]); })87(data);8889var d1 = d3_horizonArea90.x(function(d) { return x1(d[0]); })91.y1(function(d) { return h * bands - y1(d[1]); })92(data);9394path.enter().append("path")95.style("fill", color)96.attr("transform", t0)97.attr("d", d0);9899path.transition()100.duration(duration)101.style("fill", color)102.attr("transform", t1)103.attr("d", d1);104105path.exit().transition()106.duration(duration)107.attr("transform", t1)108.attr("d", d1)109.remove();110111// Stash the new scales.112this.__chart__ = {x: x1, y: y1, t: t1, id: id};113});114d3.timer.flush();115}116117horizon.duration = function(x) {118if (!arguments.length) return duration;119duration = +x;120return horizon;121};122123horizon.bands = function(x) {124if (!arguments.length) return bands;125bands = +x;126color.domain([-bands, 0, bands]);127return horizon;128};129130horizon.mode = function(x) {131if (!arguments.length) return mode;132mode = x + "";133return horizon;134};135136horizon.colors = function(x) {137if (!arguments.length) return color.range();138color.range(x);139return horizon;140};141142horizon.interpolate = function(x) {143if (!arguments.length) return interpolate;144interpolate = x + "";145return horizon;146};147148horizon.x = function(z) {149if (!arguments.length) return x;150x = z;151return horizon;152};153154horizon.y = function(z) {155if (!arguments.length) return y;156y = z;157return horizon;158};159160horizon.width = function(x) {161if (!arguments.length) return w;162w = +x;163return horizon;164};165166horizon.height = function(x) {167if (!arguments.length) return h;168h = +x;169return horizon;170};171172return horizon;173};174175var d3_horizonArea = d3.svg.area(),176d3_horizonId = 0;177178function d3_horizonX(d) {179return d[0];180}181182function d3_horizonY(d) {183return d[1];184}185186function d3_horizonTransform(bands, h, mode) {187return mode == "offset"188? function(d) { return "translate(0," + (d + (d < 0) - bands) * h + ")"; }189: function(d) { return (d < 0 ? "scale(1,-1)" : "") + "translate(0," + (d - bands) * h + ")"; };190}191})();192193194