Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / webapp / app / fusion / external / d3 / js / horizon.js
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 })();