Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / webapp / static / fusion / d3 / js / models / backup / bullet.js
1
2 // Chart design based on the recommendations of Stephen Few. Implementation
3 // based on the work of Clint Ivy, Jamie Love, and Jason Davies.
4 // http://projects.instantcognition.com/protovis/bulletchart/
5
6 nv.models.bullet = function() {
7
8   //============================================================
9   // Public Variables with Default Settings
10   //------------------------------------------------------------
11
12   var margin = {top: 0, right: 0, bottom: 0, left: 0}
13     , orient = 'left' // TODO top & bottom
14     , reverse = false
15     , ranges = function(d) { return d.ranges }
16     , markers = function(d) { return d.markers }
17     , measures = function(d) { return d.measures }
18     , forceX = [0] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.)
19     , width = 380
20     , height = 30
21     , tickFormat = null
22     , dispatch = d3.dispatch('elementMouseover', 'elementMouseout')
23     ;
24
25   //============================================================
26
27
28   function chart(selection) {
29     selection.each(function(d, i) {
30       var availableWidth = width - margin.left - margin.right,
31           availableHeight = height - margin.top - margin.bottom,
32           container = d3.select(this),
33           mainGroup = nv.log(this.parentNode.parentNode).getAttribute('transform'),
34           heightFromTop = nv.log(parseInt(mainGroup.replace(/.*,(\d+)\)/,"$1"))); //TODO: There should be a smarter way to get this value
35
36       var rangez = ranges.call(this, d, i).slice().sort(d3.descending),
37           markerz = markers.call(this, d, i).slice().sort(d3.descending),
38           measurez = measures.call(this, d, i).slice().sort(d3.descending);
39
40
41       //------------------------------------------------------------
42       // Setup Scales
43
44       // Compute the new x-scale.
45       var MaxX = Math.max(rangez[0] ? rangez[0]:0 , markerz[0] ? markerz[0] : 0 , measurez[0] ? measurez[0] : 0)
46       var x1 = d3.scale.linear()
47           .domain([0, MaxX]).nice()  // TODO: need to allow forceX and forceY, and xDomain, yDomain
48           .range(reverse ? [availableWidth, 0] : [0, availableWidth]);
49
50       // Retrieve the old x-scale, if this is an update.
51       var x0 = this.__chart__ || d3.scale.linear()
52           .domain([0, Infinity])
53           .range(x1.range());
54
55       // Stash the new scale.
56       this.__chart__ = x1;
57
58       //------------------------------------------------------------
59
60
61       //------------------------------------------------------------
62       // Setup containers and skeleton of chart
63
64       var wrap = container.selectAll('g.nv-wrap.nv-bullet').data([d]);
65       var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-bullet');
66       var gEnter = wrapEnter.append('g');
67       var g = wrap.select('g');
68
69       wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
70
71       //------------------------------------------------------------
72
73
74
75       var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0)
76           w1 = function(d) { return Math.abs(x1(d) - x1(0)) };
77
78
79       // Update the range rects.
80       var range = g.selectAll('rect.nv-range')
81           .data(rangez);
82
83       range.enter().append('rect')
84           .attr('class', function(d, i) { return 'nv-range nv-s' + i; })
85           .attr('width', w0)
86           .attr('height', availableHeight)
87           .attr('x', reverse ? x0 : 0)
88           .on('mouseover', function(d,i) { 
89               dispatch.elementMouseover({
90                 value: d,
91                 label: (i <= 0) ? 'Maximum' : (i > 1) ? 'Minimum' : 'Mean', //TODO: make these labels a variable
92                 pos: [x1(d), heightFromTop]
93               })
94           })
95           .on('mouseout', function(d,i) { 
96               dispatch.elementMouseout({
97                 value: d,
98                 label: (i <= 0) ? 'Minimum' : (i >=1) ? 'Maximum' : 'Mean' //TODO: make these labels a variable
99               })
100           })
101
102       d3.transition(range)
103           .attr('x', reverse ? x1 : 0)
104           .attr('width', w1)
105           .attr('height', availableHeight);
106
107
108       // Update the measure rects.
109       var measure = g.selectAll('rect.nv-measure')
110           .data(measurez);
111
112       measure.enter().append('rect')
113           .attr('class', function(d, i) { return 'nv-measure nv-s' + i; })
114           .attr('width', w0)
115           .attr('height', availableHeight / 3)
116           .attr('x', reverse ? x0 : 0)
117           .attr('y', availableHeight / 3)
118           .on('mouseover', function(d) { 
119               dispatch.elementMouseover({
120                 value: d,
121                 label: 'Current', //TODO: make these labels a variable
122                 pos: [x1(d), heightFromTop]
123               })
124           })
125           .on('mouseout', function(d) { 
126               dispatch.elementMouseout({
127                 value: d,
128                 label: 'Current' //TODO: make these labels a variable
129               })
130           })
131
132       d3.transition(measure)
133           .attr('width', w1)
134           .attr('height', availableHeight / 3)
135           .attr('x', reverse ? x1 : 0)
136           .attr('y', availableHeight / 3);
137
138
139
140       // Update the marker lines.
141       var marker = g.selectAll('path.nv-markerTriangle')
142           .data(markerz);
143
144       var h3 =  availableHeight / 6;
145       marker.enter().append('path')
146           .attr('class', 'nv-markerTriangle')
147           .attr('transform', function(d) { return 'translate(' + x0(d) + ',' + (availableHeight / 2) + ')' })
148           .attr('d', 'M0,' + h3 + 'L' + h3 + ',' + (-h3) + ' ' + (-h3) + ',' + (-h3) + 'Z')
149           .on('mouseover', function(d,i) {
150               dispatch.elementMouseover({
151                 value: d,
152                 label: 'Previous',
153                 pos: [x1(d), heightFromTop]
154               })
155           })
156           .on('mouseout', function(d,i) {
157               dispatch.elementMouseout({
158                 value: d,
159                 label: 'Previous'
160               })
161           });
162
163       d3.transition(marker)
164           .attr('transform', function(d) { return 'translate(' + x1(d) + ',' + (availableHeight / 2) + ')' });
165
166       marker.exit().remove();
167
168     });
169
170     d3.timer.flush();
171
172     return chart;
173   }
174
175
176   //============================================================
177   // Expose Public Variables
178   //------------------------------------------------------------
179
180   chart.dispatch = dispatch;
181
182   // left, right, top, bottom
183   chart.orient = function(_) {
184     if (!arguments.length) return orient;
185     orient = _;
186     reverse = orient == 'right' || orient == 'bottom';
187     return chart;
188   };
189
190   // ranges (bad, satisfactory, good)
191   chart.ranges = function(_) {
192     if (!arguments.length) return ranges;
193     ranges = _;
194     return chart;
195   };
196
197   // markers (previous, goal)
198   chart.markers = function(_) {
199     if (!arguments.length) return markers;
200     markers = _;
201     return chart;
202   };
203
204   // measures (actual, forecast)
205   chart.measures = function(_) {
206     if (!arguments.length) return measures;
207     measures = _;
208     return chart;
209   };
210
211   chart.forceX = function(_) {
212     if (!arguments.length) return forceX;
213     forceX = _;
214     return chart;
215   };
216
217   chart.width = function(_) {
218     if (!arguments.length) return width;
219     width = _;
220     return chart;
221   };
222
223   chart.height = function(_) {
224     if (!arguments.length) return height;
225     height = _;
226     return chart;
227   };
228
229   chart.margin = function(_) {
230     if (!arguments.length) return margin;
231     margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;
232     margin.right  = typeof _.right  != 'undefined' ? _.right  : margin.right;
233     margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
234     margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;
235     return chart;
236   };
237
238   chart.tickFormat = function(_) {
239     if (!arguments.length) return tickFormat;
240     tickFormat = _;
241     return chart;
242   };
243
244   //============================================================
245
246
247   return chart;
248 };
249
250