Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / webapp / app / fusion / external / d3 / js / models / multiBarTimeSeriesChart.js
1 nv.models.multiBarTimeSeriesChart = function() {
2   "use strict";
3   //============================================================
4   // Public Variables with Default Settings
5   //------------------------------------------------------------
6
7   var multibar = nv.models.multiBarTimeSeries()
8     , xAxis = nv.models.axis()
9     , yAxis = nv.models.axis()
10     , legend = nv.models.legend()
11     , controls = nv.models.legend()
12     ;
13
14   var margin = {top: 30, right: 20, bottom: 50, left: 60}
15     , width = null
16     , height = null
17     , color = nv.utils.defaultColor()
18     , showControls = true
19     , showLegend = true
20     , reduceXTicks = true // if false a tick will show for every data point
21     , rotateLabels = 0
22     , tooltips = true
23     , tooltip = function(key, x, y, e, graph) {
24         return '<h3>' + key + '</h3>' +
25                '<p>' +  y + ' on ' + x + '</p>'
26       }
27     , x //can be accessed via chart.xScale()
28     , y //can be accessed via chart.yScale()
29     , noData = "No Data Available."
30     , dispatch = d3.dispatch('tooltipShow', 'tooltipHide')
31     ;
32
33   multibar
34     .stacked(false)
35     ;
36   xAxis
37     .orient('bottom')
38     .tickPadding(7)
39     .highlightZero(false)
40     .showMaxMin(false)
41     ;
42   yAxis
43     .orient('left')
44     .tickFormat(d3.format(',.1f'))
45     ;
46
47   //============================================================
48
49
50   //============================================================
51   // Private Variables
52   //------------------------------------------------------------
53
54   var showTooltip = function(e, offsetElement) {
55     var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
56         top = e.pos[1] + ( offsetElement.offsetTop || 0),
57         x = xAxis.tickFormat()(multibar.x()(e.point, e.pointIndex)),
58         y = yAxis.tickFormat()(multibar.y()(e.point, e.pointIndex)),
59         content = tooltip(e.series.key, x, y, e, chart);
60
61     nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's', null, offsetElement);
62   };
63
64   //============================================================
65
66
67   function chart(selection) {
68     selection.each(function(data) {
69       var container = d3.select(this),
70           that = this;
71
72       var availableWidth = (width  || parseInt(container.style('width')) || 960)
73                              - margin.left - margin.right,
74           availableHeight = (height || parseInt(container.style('height')) || 400)
75                              - margin.top - margin.bottom;
76
77       chart.update = function() { selection.transition().call(chart) };
78       chart.container = this;
79
80
81       //------------------------------------------------------------
82       // Display noData message if there's nothing to show.
83
84       if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {
85         var noDataText = container.selectAll('.nv-noData').data([noData]);
86
87         noDataText.enter().append('text')
88           .attr('class', 'nvd3 nv-noData')
89           .attr('dy', '-.7em')
90           .style('text-anchor', 'middle');
91
92         noDataText
93           .attr('x', margin.left + availableWidth / 2)
94           .attr('y', margin.top + availableHeight / 2)
95           .text(function(d) { return d });
96
97         return chart;
98       } else {
99         container.selectAll('.nv-noData').remove();
100       }
101
102       //------------------------------------------------------------
103
104
105       //------------------------------------------------------------
106       // Setup Scales
107
108       x = multibar.xScale();
109       y = multibar.yScale();
110
111       //------------------------------------------------------------
112
113
114       //------------------------------------------------------------
115       // Setup containers and skeleton of chart
116
117       var wrap = container.selectAll('g.nv-wrap.nv-multiBarWithLegend').data([data]);
118       var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multiBarWithLegend').append('g');
119       var g = wrap.select('g');
120
121       gEnter.append('g').attr('class', 'nv-x nv-axis');
122       gEnter.append('g').attr('class', 'nv-y nv-axis');
123       gEnter.append('g').attr('class', 'nv-barsWrap');
124       gEnter.append('g').attr('class', 'nv-legendWrap');
125       gEnter.append('g').attr('class', 'nv-controlsWrap');
126
127       //------------------------------------------------------------
128
129
130       //------------------------------------------------------------
131       // Legend
132
133       if (showLegend) {
134         legend.width(availableWidth / 2);
135
136         g.select('.nv-legendWrap')
137             .datum(data)
138             .call(legend);
139
140         if ( margin.top != legend.height()) {
141           margin.top = legend.height();
142           availableHeight = (height || parseInt(container.style('height')) || 400)
143                              - margin.top - margin.bottom;
144         }
145
146         g.select('.nv-legendWrap')
147             .attr('transform', 'translate(' + (availableWidth / 2) + ',' + (-margin.top) +')');
148       }
149
150       //------------------------------------------------------------
151
152
153       //------------------------------------------------------------
154       // Controls
155
156       if (showControls) {
157         var controlsData = [
158           { key: 'Grouped', disabled: multibar.stacked() },
159           { key: 'Stacked', disabled: !multibar.stacked() }
160         ];
161
162         controls.width(180).color(['#444', '#444', '#444']);
163         g.select('.nv-controlsWrap')
164             .datum(controlsData)
165             .attr('transform', 'translate(0,' + (-margin.top) +')')
166             .call(controls);
167       }
168
169       //------------------------------------------------------------
170
171
172       wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
173
174
175       //------------------------------------------------------------
176       // Main Chart Component(s)
177
178       multibar
179         .width(availableWidth)
180         .height(availableHeight)
181         .color(data.map(function(d,i) {
182           return d.color || color(d, i);
183         }).filter(function(d,i) { return !data[i].disabled }))
184
185
186       var barsWrap = g.select('.nv-barsWrap')
187           .datum(data.filter(function(d) { return !d.disabled }))
188
189       d3.transition(barsWrap).call(multibar);
190
191       //------------------------------------------------------------
192
193
194       //------------------------------------------------------------
195       // Setup Axes
196
197       xAxis
198         .scale(x)
199         .ticks(availableWidth / 100)        
200         .tickSize(-availableHeight, 0);
201
202       g.select('.nv-x.nv-axis')
203           .attr('transform', 'translate(0,' + y.range()[0] + ')');
204       d3.transition(g.select('.nv-x.nv-axis'))
205           .call(xAxis);
206
207       var xTicks = g.select('.nv-x.nv-axis > g').selectAll('g');
208
209       xTicks
210           .selectAll('line, text')
211           .style('opacity', 1)
212
213       if (reduceXTicks)
214         xTicks
215           .filter(function(d,i) {
216               return i % Math.ceil(data[0].values.length / (availableWidth / 100)) !== 0;
217             })
218           .selectAll('text, line')
219           .style('opacity', 0);
220
221       if(rotateLabels)
222         xTicks
223             .selectAll('text')
224             .attr('transform', function(d,i,j) { return 'rotate('+rotateLabels+' 0,0)' })
225             .attr('text-transform', rotateLabels > 0 ? 'start' : 'end');
226
227       yAxis
228         .scale(y)
229         .ticks( availableHeight / 36 )
230         .tickSize( -availableWidth, 0);
231
232       d3.transition(g.select('.nv-y.nv-axis'))
233           .call(yAxis);
234
235       //------------------------------------------------------------
236
237
238
239       //============================================================
240       // Event Handling/Dispatching (in chart's scope)
241       //------------------------------------------------------------
242
243       legend.dispatch.on('legendClick', function(d,i) {
244         d.disabled = !d.disabled;
245
246         if (!data.filter(function(d) { return !d.disabled }).length) {
247           data.map(function(d) {
248             d.disabled = false;
249             wrap.selectAll('.nv-series').classed('disabled', false);
250             return d;
251           });
252         }
253
254         selection.transition().call(chart);
255       });
256
257       controls.dispatch.on('legendClick', function(d,i) {
258         if (!d.disabled) return;
259         controlsData = controlsData.map(function(s) {
260           s.disabled = true;
261           return s;
262         });
263         d.disabled = false;
264
265         switch (d.key) {
266           case 'Grouped':
267             multibar.stacked(false);
268             break;
269           case 'Stacked':
270             multibar.stacked(true);
271             break;
272         }
273
274         selection.transition().call(chart);
275       });
276
277       dispatch.on('tooltipShow', function(e) {
278         if (tooltips) showTooltip(e, that.parentNode)
279       });
280
281       //============================================================
282
283
284     });
285
286     return chart;
287   }
288
289
290   //============================================================
291   // Event Handling/Dispatching (out of chart's scope)
292   //------------------------------------------------------------
293
294   multibar.dispatch.on('elementMouseover.tooltip', function(e) {
295     e.pos = [e.pos[0] +  margin.left, e.pos[1] + margin.top];
296     dispatch.tooltipShow(e);
297   });
298
299   multibar.dispatch.on('elementMouseout.tooltip', function(e) {
300     dispatch.tooltipHide(e);
301   });
302   dispatch.on('tooltipHide', function() {
303     if (tooltips) nv.tooltip.cleanup();
304   });
305
306   //============================================================
307
308
309   //============================================================
310   // Expose Public Variables
311   //------------------------------------------------------------
312
313   // expose chart's sub-components
314   chart.dispatch = dispatch;
315   chart.multibar = multibar;
316   chart.legend = legend;
317   chart.xAxis = xAxis;
318   chart.yAxis = yAxis;
319
320   d3.rebind(chart, multibar, 'x', 'y', 'xDomain', 'yDomain', 'xRange', 'yRange', 'forceX', 'forceY', 'clipEdge', 'id', 'stacked', 'delay');
321
322   chart.options = nv.utils.optionsFunc.bind(chart);
323   
324   chart.margin = function(_) {
325     if (!arguments.length) return margin;
326     margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;
327     margin.right  = typeof _.right  != 'undefined' ? _.right  : margin.right;
328     margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
329     margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;
330     return chart;
331   };
332
333   chart.width = function(_) {
334     if (!arguments.length) return width;
335     width = _;
336     return chart;
337   };
338
339   chart.height = function(_) {
340     if (!arguments.length) return height;
341     height = _;
342     return chart;
343   };
344
345   chart.color = function(_) {
346     if (!arguments.length) return color;
347     color = nv.utils.getColor(_);
348     legend.color(color);
349     return chart;
350   };
351
352   chart.showControls = function(_) {
353     if (!arguments.length) return showControls;
354     showControls = _;
355     return chart;
356   };
357
358   chart.showLegend = function(_) {
359     if (!arguments.length) return showLegend;
360     showLegend = _;
361     return chart;
362   };
363
364   chart.reduceXTicks= function(_) {
365     if (!arguments.length) return reduceXTicks;
366     reduceXTicks = _;
367     return chart;
368   };
369
370   chart.rotateLabels = function(_) {
371     if (!arguments.length) return rotateLabels;
372     rotateLabels = _;
373     return chart;
374   }
375
376   chart.tooltip = function(_) {
377     if (!arguments.length) return tooltip;
378     tooltip = _;
379     return chart;
380   };
381
382   chart.tooltips = function(_) {
383     if (!arguments.length) return tooltips;
384     tooltips = _;
385     return chart;
386   };
387
388   chart.tooltipContent = function(_) {
389     if (!arguments.length) return tooltip;
390     tooltip = _;
391     return chart;
392   };
393
394   chart.noData = function(_) {
395     if (!arguments.length) return noData;
396     noData = _;
397     return chart;
398   };
399
400   //============================================================
401
402
403   return chart;
404 }
405