Refactor project structure
This commit is contained in:
192
web/js/nvd3/lib/horizon.js
Normal file
192
web/js/nvd3/lib/horizon.js
Normal file
@@ -0,0 +1,192 @@
|
||||
(function() {
|
||||
d3.horizon = function() {
|
||||
var bands = 1, // between 1 and 5, typically
|
||||
mode = "offset", // or mirror
|
||||
interpolate = "linear", // or basis, monotone, step-before, etc.
|
||||
x = d3_horizonX,
|
||||
y = d3_horizonY,
|
||||
w = 960,
|
||||
h = 40,
|
||||
duration = 0;
|
||||
|
||||
var color = d3.scale.linear()
|
||||
.domain([-1, 0, 1])
|
||||
.range(["#d62728", "#fff", "#1f77b4"]);
|
||||
|
||||
// For each small multiple…
|
||||
function horizon(g) {
|
||||
g.each(function(d, i) {
|
||||
var g = d3.select(this),
|
||||
n = 2 * bands + 1,
|
||||
xMin = Infinity,
|
||||
xMax = -Infinity,
|
||||
yMax = -Infinity,
|
||||
x0, // old x-scale
|
||||
y0, // old y-scale
|
||||
id; // unique id for paths
|
||||
|
||||
// Compute x- and y-values along with extents.
|
||||
var data = d.map(function(d, i) {
|
||||
var xv = x.call(this, d, i),
|
||||
yv = y.call(this, d, i);
|
||||
if (xv < xMin) xMin = xv;
|
||||
if (xv > xMax) xMax = xv;
|
||||
if (-yv > yMax) yMax = -yv;
|
||||
if (yv > yMax) yMax = yv;
|
||||
return [xv, yv];
|
||||
});
|
||||
|
||||
// Compute the new x- and y-scales, and transform.
|
||||
var x1 = d3.scale.linear().domain([xMin, xMax]).range([0, w]),
|
||||
y1 = d3.scale.linear().domain([0, yMax]).range([0, h * bands]),
|
||||
t1 = d3_horizonTransform(bands, h, mode);
|
||||
|
||||
// Retrieve the old scales, if this is an update.
|
||||
if (this.__chart__) {
|
||||
x0 = this.__chart__.x;
|
||||
y0 = this.__chart__.y;
|
||||
t0 = this.__chart__.t;
|
||||
id = this.__chart__.id;
|
||||
} else {
|
||||
x0 = x1.copy();
|
||||
y0 = y1.copy();
|
||||
t0 = t1;
|
||||
id = ++d3_horizonId;
|
||||
}
|
||||
|
||||
// We'll use a defs to store the area path and the clip path.
|
||||
var defs = g.selectAll("defs")
|
||||
.data([null]);
|
||||
|
||||
// The clip path is a simple rect.
|
||||
defs.enter().append("defs").append("clipPath")
|
||||
.attr("id", "d3_horizon_clip" + id)
|
||||
.append("rect")
|
||||
.attr("width", w)
|
||||
.attr("height", h);
|
||||
|
||||
defs.select("rect").transition()
|
||||
.duration(duration)
|
||||
.attr("width", w)
|
||||
.attr("height", h);
|
||||
|
||||
// We'll use a container to clip all horizon layers at once.
|
||||
g.selectAll("g")
|
||||
.data([null])
|
||||
.enter().append("g")
|
||||
.attr("clip-path", "url(#d3_horizon_clip" + id + ")");
|
||||
|
||||
// Instantiate each copy of the path with different transforms.
|
||||
var path = g.select("g").selectAll("path")
|
||||
.data(d3.range(-1, -bands - 1, -1).concat(d3.range(1, bands + 1)), Number);
|
||||
|
||||
var d0 = d3_horizonArea
|
||||
.interpolate(interpolate)
|
||||
.x(function(d) { return x0(d[0]); })
|
||||
.y0(h * bands)
|
||||
.y1(function(d) { return h * bands - y0(d[1]); })
|
||||
(data);
|
||||
|
||||
var d1 = d3_horizonArea
|
||||
.x(function(d) { return x1(d[0]); })
|
||||
.y1(function(d) { return h * bands - y1(d[1]); })
|
||||
(data);
|
||||
|
||||
path.enter().append("path")
|
||||
.style("fill", color)
|
||||
.attr("transform", t0)
|
||||
.attr("d", d0);
|
||||
|
||||
path.transition()
|
||||
.duration(duration)
|
||||
.style("fill", color)
|
||||
.attr("transform", t1)
|
||||
.attr("d", d1);
|
||||
|
||||
path.exit().transition()
|
||||
.duration(duration)
|
||||
.attr("transform", t1)
|
||||
.attr("d", d1)
|
||||
.remove();
|
||||
|
||||
// Stash the new scales.
|
||||
this.__chart__ = {x: x1, y: y1, t: t1, id: id};
|
||||
});
|
||||
d3.timer.flush();
|
||||
}
|
||||
|
||||
horizon.duration = function(x) {
|
||||
if (!arguments.length) return duration;
|
||||
duration = +x;
|
||||
return horizon;
|
||||
};
|
||||
|
||||
horizon.bands = function(x) {
|
||||
if (!arguments.length) return bands;
|
||||
bands = +x;
|
||||
color.domain([-bands, 0, bands]);
|
||||
return horizon;
|
||||
};
|
||||
|
||||
horizon.mode = function(x) {
|
||||
if (!arguments.length) return mode;
|
||||
mode = x + "";
|
||||
return horizon;
|
||||
};
|
||||
|
||||
horizon.colors = function(x) {
|
||||
if (!arguments.length) return color.range();
|
||||
color.range(x);
|
||||
return horizon;
|
||||
};
|
||||
|
||||
horizon.interpolate = function(x) {
|
||||
if (!arguments.length) return interpolate;
|
||||
interpolate = x + "";
|
||||
return horizon;
|
||||
};
|
||||
|
||||
horizon.x = function(z) {
|
||||
if (!arguments.length) return x;
|
||||
x = z;
|
||||
return horizon;
|
||||
};
|
||||
|
||||
horizon.y = function(z) {
|
||||
if (!arguments.length) return y;
|
||||
y = z;
|
||||
return horizon;
|
||||
};
|
||||
|
||||
horizon.width = function(x) {
|
||||
if (!arguments.length) return w;
|
||||
w = +x;
|
||||
return horizon;
|
||||
};
|
||||
|
||||
horizon.height = function(x) {
|
||||
if (!arguments.length) return h;
|
||||
h = +x;
|
||||
return horizon;
|
||||
};
|
||||
|
||||
return horizon;
|
||||
};
|
||||
|
||||
var d3_horizonArea = d3.svg.area(),
|
||||
d3_horizonId = 0;
|
||||
|
||||
function d3_horizonX(d) {
|
||||
return d[0];
|
||||
}
|
||||
|
||||
function d3_horizonY(d) {
|
||||
return d[1];
|
||||
}
|
||||
|
||||
function d3_horizonTransform(bands, h, mode) {
|
||||
return mode == "offset"
|
||||
? function(d) { return "translate(0," + (d + (d < 0) - bands) * h + ")"; }
|
||||
: function(d) { return (d < 0 ? "scale(1,-1)" : "") + "translate(0," + (d - bands) * h + ")"; };
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user