Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / webapp / app / fusion / external / d3 / js / models / sparklinePlus.js
1
2 nv.models.sparklinePlus = function() {
3   "use strict";
4   //============================================================
5   // Public Variables with Default Settings
6   //------------------------------------------------------------
7
8   var sparkline = nv.models.sparkline();
9
10   var margin = {top: 15, right: 100, bottom: 10, left: 50}
11     , width = null
12     , height = null
13     , x
14     , y
15     , index = []
16     , paused = false
17     , xTickFormat = d3.format(',r')
18     , yTickFormat = d3.format(',.2f')
19     , showValue = true
20     , alignValue = true
21     , rightAlignValue = false
22     , noData = "No Data Available."
23     ;
24
25   //============================================================
26
27
28   function chart(selection) {
29     selection.each(function(data) {
30       var container = d3.select(this);
31
32       var availableWidth = (width  || parseInt(container.style('width')) || 960)
33                              - margin.left - margin.right,
34           availableHeight = (height || parseInt(container.style('height')) || 400)
35                              - margin.top - margin.bottom;
36
37       
38
39       chart.update = function() { chart(selection) };
40       chart.container = this;
41
42
43       //------------------------------------------------------------
44       // Display No Data message if there's nothing to show.
45
46       if (!data || !data.length) {
47         var noDataText = container.selectAll('.nv-noData').data([noData]);
48
49         noDataText.enter().append('text')
50           .attr('class', 'nvd3 nv-noData')
51           .attr('dy', '-.7em')
52           .style('text-anchor', 'middle');
53
54         noDataText
55           .attr('x', margin.left + availableWidth / 2)
56           .attr('y', margin.top + availableHeight / 2)
57           .text(function(d) { return d });
58
59         return chart;
60       } else {
61         container.selectAll('.nv-noData').remove();
62       }
63
64       var currentValue = sparkline.y()(data[data.length-1], data.length-1);
65
66       //------------------------------------------------------------
67
68
69
70       //------------------------------------------------------------
71       // Setup Scales
72
73       x = sparkline.xScale();
74       y = sparkline.yScale();
75
76       //------------------------------------------------------------
77
78
79       //------------------------------------------------------------
80       // Setup containers and skeleton of chart
81
82       var wrap = container.selectAll('g.nv-wrap.nv-sparklineplus').data([data]);
83       var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-sparklineplus');
84       var gEnter = wrapEnter.append('g');
85       var g = wrap.select('g');
86
87       gEnter.append('g').attr('class', 'nv-sparklineWrap');
88       gEnter.append('g').attr('class', 'nv-valueWrap');
89       gEnter.append('g').attr('class', 'nv-hoverArea');
90
91       wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
92
93       //------------------------------------------------------------
94
95
96       //------------------------------------------------------------
97       // Main Chart Component(s)
98
99       var sparklineWrap = g.select('.nv-sparklineWrap');
100
101       sparkline
102         .width(availableWidth)
103         .height(availableHeight);
104
105       sparklineWrap
106           .call(sparkline);
107
108       //------------------------------------------------------------
109
110
111       var valueWrap = g.select('.nv-valueWrap');
112       
113       var value = valueWrap.selectAll('.nv-currentValue')
114           .data([currentValue]);
115
116       value.enter().append('text').attr('class', 'nv-currentValue')
117           .attr('dx', rightAlignValue ? -8 : 8)
118           .attr('dy', '.9em')
119           .style('text-anchor', rightAlignValue ? 'end' : 'start');
120
121       value
122           .attr('x', availableWidth + (rightAlignValue ? margin.right : 0))
123           .attr('y', alignValue ? function(d) { return y(d) } : 0)
124           .style('fill', sparkline.color()(data[data.length-1], data.length-1))
125           .text(yTickFormat(currentValue));
126
127
128
129       gEnter.select('.nv-hoverArea').append('rect')
130           .on('mousemove', sparklineHover)
131           .on('click', function() { paused = !paused })
132           .on('mouseout', function() { index = []; updateValueLine(); });
133           //.on('mouseout', function() { index = null; updateValueLine(); });
134
135       g.select('.nv-hoverArea rect')
136           .attr('transform', function(d) { return 'translate(' + -margin.left + ',' + -margin.top + ')' })
137           .attr('width', availableWidth + margin.left + margin.right)
138           .attr('height', availableHeight + margin.top);
139
140
141
142       function updateValueLine() { //index is currently global (within the chart), may or may not keep it that way
143         if (paused) return;
144
145         var hoverValue = g.selectAll('.nv-hoverValue').data(index)
146
147         var hoverEnter = hoverValue.enter()
148           .append('g').attr('class', 'nv-hoverValue')
149             .style('stroke-opacity', 0)
150             .style('fill-opacity', 0);
151
152         hoverValue.exit()
153           .transition().duration(250)
154             .style('stroke-opacity', 0)
155             .style('fill-opacity', 0)
156             .remove();
157
158         hoverValue
159             .attr('transform', function(d) { return 'translate(' + x(sparkline.x()(data[d],d)) + ',0)' })
160           .transition().duration(250)
161             .style('stroke-opacity', 1)
162             .style('fill-opacity', 1);
163
164         if (!index.length) return;
165
166         hoverEnter.append('line')
167             .attr('x1', 0)
168             .attr('y1', -margin.top)
169             .attr('x2', 0)
170             .attr('y2', availableHeight);
171
172
173         hoverEnter.append('text').attr('class', 'nv-xValue')
174             .attr('x', -6)
175             .attr('y', -margin.top)
176             .attr('text-anchor', 'end')
177             .attr('dy', '.9em')
178
179
180         g.select('.nv-hoverValue .nv-xValue')
181             .text(xTickFormat(sparkline.x()(data[index[0]], index[0])));
182
183         hoverEnter.append('text').attr('class', 'nv-yValue')
184             .attr('x', 6)
185             .attr('y', -margin.top)
186             .attr('text-anchor', 'start')
187             .attr('dy', '.9em')
188
189         g.select('.nv-hoverValue .nv-yValue')
190             .text(yTickFormat(sparkline.y()(data[index[0]], index[0])));
191
192       }
193
194
195       function sparklineHover() {
196         if (paused) return;
197
198         var pos = d3.mouse(this)[0] - margin.left;
199
200         function getClosestIndex(data, x) {
201           var distance = Math.abs(sparkline.x()(data[0], 0) - x);
202           var closestIndex = 0;
203           for (var i = 0; i < data.length; i++){
204             if (Math.abs(sparkline.x()(data[i], i) - x) < distance) {
205               distance = Math.abs(sparkline.x()(data[i], i) - x);
206               closestIndex = i;
207             }
208           }
209           return closestIndex;
210         }
211
212         index = [getClosestIndex(data, Math.round(x.invert(pos)))];
213
214         updateValueLine();
215       }
216
217     });
218
219     return chart;
220   }
221
222
223   //============================================================
224   // Expose Public Variables
225   //------------------------------------------------------------
226
227   // expose chart's sub-components
228   chart.sparkline = sparkline;
229
230   d3.rebind(chart, sparkline, 'x', 'y', 'xScale', 'yScale', 'color');
231
232   chart.options = nv.utils.optionsFunc.bind(chart);
233   
234   chart.margin = function(_) {
235     if (!arguments.length) return margin;
236     margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;
237     margin.right  = typeof _.right  != 'undefined' ? _.right  : margin.right;
238     margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
239     margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;
240     return chart;
241   };
242
243   chart.width = function(_) {
244     if (!arguments.length) return width;
245     width = _;
246     return chart;
247   };
248
249   chart.height = function(_) {
250     if (!arguments.length) return height;
251     height = _;
252     return chart;
253   };
254
255   chart.xTickFormat = function(_) {
256     if (!arguments.length) return xTickFormat;
257     xTickFormat = _;
258     return chart;
259   };
260
261   chart.yTickFormat = function(_) {
262     if (!arguments.length) return yTickFormat;
263     yTickFormat = _;
264     return chart;
265   };
266
267   chart.showValue = function(_) {
268     if (!arguments.length) return showValue;
269     showValue = _;
270     return chart;
271   };
272
273   chart.alignValue = function(_) {
274     if (!arguments.length) return alignValue;
275     alignValue = _;
276     return chart;
277   };
278
279   chart.rightAlignValue = function(_) {
280     if (!arguments.length) return rightAlignValue;
281     rightAlignValue = _;
282     return chart;
283   };
284
285   chart.noData = function(_) {
286     if (!arguments.length) return noData;
287     noData = _;
288     return chart;
289   };
290
291   //============================================================
292
293
294   return chart;
295 }