Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
braverock
GitHub Repository: braverock/portfolioanalytics
Path: blob/master/sandbox/RFinance2014/libraries/widgets/nvd3/js/horizon.js
1433 views
1
(function() {
2
d3.horizon = function() {
3
var bands = 1, // between 1 and 5, typically
4
mode = "offset", // or mirror
5
interpolate = "linear", // or basis, monotone, step-before, etc.
6
x = d3_horizonX,
7
y = d3_horizonY,
8
w = 960,
9
h = 40,
10
duration = 0;
11
12
var color = d3.scale.linear()
13
.domain([-1, 0, 1])
14
.range(["#d62728", "#fff", "#1f77b4"]);
15
16
// For each small multiple…
17
function horizon(g) {
18
g.each(function(d, i) {
19
var g = d3.select(this),
20
n = 2 * bands + 1,
21
xMin = Infinity,
22
xMax = -Infinity,
23
yMax = -Infinity,
24
x0, // old x-scale
25
y0, // old y-scale
26
id; // unique id for paths
27
28
// Compute x- and y-values along with extents.
29
var data = d.map(function(d, i) {
30
var xv = x.call(this, d, i),
31
yv = y.call(this, d, i);
32
if (xv < xMin) xMin = xv;
33
if (xv > xMax) xMax = xv;
34
if (-yv > yMax) yMax = -yv;
35
if (yv > yMax) yMax = yv;
36
return [xv, yv];
37
});
38
39
// Compute the new x- and y-scales, and transform.
40
var x1 = d3.scale.linear().domain([xMin, xMax]).range([0, w]),
41
y1 = d3.scale.linear().domain([0, yMax]).range([0, h * bands]),
42
t1 = d3_horizonTransform(bands, h, mode);
43
44
// Retrieve the old scales, if this is an update.
45
if (this.__chart__) {
46
x0 = this.__chart__.x;
47
y0 = this.__chart__.y;
48
t0 = this.__chart__.t;
49
id = this.__chart__.id;
50
} else {
51
x0 = x1.copy();
52
y0 = y1.copy();
53
t0 = t1;
54
id = ++d3_horizonId;
55
}
56
57
// We'll use a defs to store the area path and the clip path.
58
var defs = g.selectAll("defs")
59
.data([null]);
60
61
// The clip path is a simple rect.
62
defs.enter().append("defs").append("clipPath")
63
.attr("id", "d3_horizon_clip" + id)
64
.append("rect")
65
.attr("width", w)
66
.attr("height", h);
67
68
defs.select("rect").transition()
69
.duration(duration)
70
.attr("width", w)
71
.attr("height", h);
72
73
// We'll use a container to clip all horizon layers at once.
74
g.selectAll("g")
75
.data([null])
76
.enter().append("g")
77
.attr("clip-path", "url(#d3_horizon_clip" + id + ")");
78
79
// Instantiate each copy of the path with different transforms.
80
var path = g.select("g").selectAll("path")
81
.data(d3.range(-1, -bands - 1, -1).concat(d3.range(1, bands + 1)), Number);
82
83
var d0 = d3_horizonArea
84
.interpolate(interpolate)
85
.x(function(d) { return x0(d[0]); })
86
.y0(h * bands)
87
.y1(function(d) { return h * bands - y0(d[1]); })
88
(data);
89
90
var d1 = d3_horizonArea
91
.x(function(d) { return x1(d[0]); })
92
.y1(function(d) { return h * bands - y1(d[1]); })
93
(data);
94
95
path.enter().append("path")
96
.style("fill", color)
97
.attr("transform", t0)
98
.attr("d", d0);
99
100
path.transition()
101
.duration(duration)
102
.style("fill", color)
103
.attr("transform", t1)
104
.attr("d", d1);
105
106
path.exit().transition()
107
.duration(duration)
108
.attr("transform", t1)
109
.attr("d", d1)
110
.remove();
111
112
// Stash the new scales.
113
this.__chart__ = {x: x1, y: y1, t: t1, id: id};
114
});
115
d3.timer.flush();
116
}
117
118
horizon.duration = function(x) {
119
if (!arguments.length) return duration;
120
duration = +x;
121
return horizon;
122
};
123
124
horizon.bands = function(x) {
125
if (!arguments.length) return bands;
126
bands = +x;
127
color.domain([-bands, 0, bands]);
128
return horizon;
129
};
130
131
horizon.mode = function(x) {
132
if (!arguments.length) return mode;
133
mode = x + "";
134
return horizon;
135
};
136
137
horizon.colors = function(x) {
138
if (!arguments.length) return color.range();
139
color.range(x);
140
return horizon;
141
};
142
143
horizon.interpolate = function(x) {
144
if (!arguments.length) return interpolate;
145
interpolate = x + "";
146
return horizon;
147
};
148
149
horizon.x = function(z) {
150
if (!arguments.length) return x;
151
x = z;
152
return horizon;
153
};
154
155
horizon.y = function(z) {
156
if (!arguments.length) return y;
157
y = z;
158
return horizon;
159
};
160
161
horizon.width = function(x) {
162
if (!arguments.length) return w;
163
w = +x;
164
return horizon;
165
};
166
167
horizon.height = function(x) {
168
if (!arguments.length) return h;
169
h = +x;
170
return horizon;
171
};
172
173
return horizon;
174
};
175
176
var d3_horizonArea = d3.svg.area(),
177
d3_horizonId = 0;
178
179
function d3_horizonX(d) {
180
return d[0];
181
}
182
183
function d3_horizonY(d) {
184
return d[1];
185
}
186
187
function d3_horizonTransform(bands, h, mode) {
188
return mode == "offset"
189
? function(d) { return "translate(0," + (d + (d < 0) - bands) * h + ")"; }
190
: function(d) { return (d < 0 ? "scale(1,-1)" : "") + "translate(0," + (d - bands) * h + ")"; };
191
}
192
})();
193
194