Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / webapp / static / fusion / raptor / d3 / js / models / ohlcBar.js
1
2 nv.models.ohlcBar = function() {
3   "use strict";
4   //============================================================
5   // Public Variables with Default Settings
6   //------------------------------------------------------------
7
8   var margin = {top: 0, right: 0, bottom: 0, left: 0}
9     , width = 960
10     , height = 500
11     , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one
12     , x = d3.scale.linear()
13     , y = d3.scale.linear()
14     , getX = function(d) { return d.x }
15     , getY = function(d) { return d.y }
16     , getOpen = function(d) { return d.open }
17     , getClose = function(d) { return d.close }
18     , getHigh = function(d) { return d.high }
19     , getLow = function(d) { return d.low }
20     , forceX = []
21     , forceY = []
22     , padData     = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart
23     , clipEdge = true
24     , color = nv.utils.defaultColor()
25     , xDomain
26     , yDomain
27     , xRange
28     , yRange
29     , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout')
30     ;
31
32   //============================================================
33
34   //============================================================
35   // Private Variables
36   //------------------------------------------------------------
37
38   //TODO: store old scales for transitions
39
40   //============================================================
41
42
43   function chart(selection) {
44     selection.each(function(data) {
45       var availableWidth = width - margin.left - margin.right,
46           availableHeight = height - margin.top - margin.bottom,
47           container = d3.select(this);
48
49
50       //------------------------------------------------------------
51       // Setup Scales
52
53       x   .domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) ));
54
55       if (padData)
56         x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5)  / data[0].values.length ]);
57       else
58         x.range(xRange || [0, availableWidth]);
59
60       y   .domain(yDomain || [
61             d3.min(data[0].values.map(getLow).concat(forceY)),
62             d3.max(data[0].values.map(getHigh).concat(forceY))
63           ])
64           .range(yRange || [availableHeight, 0]);
65
66       // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point
67       if (x.domain()[0] === x.domain()[1])
68         x.domain()[0] ?
69             x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])
70           : x.domain([-1,1]);
71
72       if (y.domain()[0] === y.domain()[1])
73         y.domain()[0] ?
74             y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01])
75           : y.domain([-1,1]);
76
77       //------------------------------------------------------------
78
79
80       //------------------------------------------------------------
81       // Setup containers and skeleton of chart
82
83       var wrap = d3.select(this).selectAll('g.nv-wrap.nv-ohlcBar').data([data[0].values]);
84       var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-ohlcBar');
85       var defsEnter = wrapEnter.append('defs');
86       var gEnter = wrapEnter.append('g');
87       var g = wrap.select('g');
88
89       gEnter.append('g').attr('class', 'nv-ticks');
90
91       wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
92
93       //------------------------------------------------------------
94
95
96       container
97           .on('click', function(d,i) {
98             dispatch.chartClick({
99                 data: d,
100                 index: i,
101                 pos: d3.event,
102                 id: id
103             });
104           });
105
106
107       defsEnter.append('clipPath')
108           .attr('id', 'nv-chart-clip-path-' + id)
109         .append('rect');
110
111       wrap.select('#nv-chart-clip-path-' + id + ' rect')
112           .attr('width', availableWidth)
113           .attr('height', availableHeight);
114
115       g   .attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : '');
116
117
118
119       var ticks = wrap.select('.nv-ticks').selectAll('.nv-tick')
120           .data(function(d) { return d });
121
122       ticks.exit().remove();
123
124
125       var ticksEnter = ticks.enter().append('path')
126           .attr('class', function(d,i,j) { return (getOpen(d,i) > getClose(d,i) ? 'nv-tick negative' : 'nv-tick positive') + ' nv-tick-' + j + '-' + i })
127           .attr('d', function(d,i) {
128             var w = (availableWidth / data[0].values.length) * .9;
129             return 'm0,0l0,'
130                  + (y(getOpen(d,i))
131                  - y(getHigh(d,i)))
132                  + 'l'
133                  + (-w/2)
134                  + ',0l'
135                  + (w/2)
136                  + ',0l0,'
137                  + (y(getLow(d,i)) - y(getOpen(d,i)))
138                  + 'l0,'
139                  + (y(getClose(d,i))
140                  - y(getLow(d,i)))
141                  + 'l'
142                  + (w/2)
143                  + ',0l'
144                  + (-w/2)
145                  + ',0z';
146           })
147           .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',' + y(getHigh(d,i)) + ')'; })
148           //.attr('fill', function(d,i) { return color[0]; })
149           //.attr('stroke', function(d,i) { return color[0]; })
150           //.attr('x', 0 )
151           //.attr('y', function(d,i) {  return y(Math.max(0, getY(d,i))) })
152           //.attr('height', function(d,i) { return Math.abs(y(getY(d,i)) - y(0)) })
153           .on('mouseover', function(d,i) {
154             d3.select(this).classed('hover', true);
155             dispatch.elementMouseover({
156                 point: d,
157                 series: data[0],
158                 pos: [x(getX(d,i)), y(getY(d,i))],  // TODO: Figure out why the value appears to be shifted
159                 pointIndex: i,
160                 seriesIndex: 0,
161                 e: d3.event
162             });
163
164           })
165           .on('mouseout', function(d,i) {
166                 d3.select(this).classed('hover', false);
167                 dispatch.elementMouseout({
168                     point: d,
169                     series: data[0],
170                     pointIndex: i,
171                     seriesIndex: 0,
172                     e: d3.event
173                 });
174           })
175           .on('click', function(d,i) {
176                 dispatch.elementClick({
177                     //label: d[label],
178                     value: getY(d,i),
179                     data: d,
180                     index: i,
181                     pos: [x(getX(d,i)), y(getY(d,i))],
182                     e: d3.event,
183                     id: id
184                 });
185               d3.event.stopPropagation();
186           })
187           .on('dblclick', function(d,i) {
188               dispatch.elementDblClick({
189                   //label: d[label],
190                   value: getY(d,i),
191                   data: d,
192                   index: i,
193                   pos: [x(getX(d,i)), y(getY(d,i))],
194                   e: d3.event,
195                   id: id
196               });
197               d3.event.stopPropagation();
198           });
199
200       ticks
201           .attr('class', function(d,i,j) { return (getOpen(d,i) > getClose(d,i) ? 'nv-tick negative' : 'nv-tick positive') + ' nv-tick-' + j + '-' + i })
202       d3.transition(ticks)
203           .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',' + y(getHigh(d,i)) + ')'; })
204           .attr('d', function(d,i) {
205             var w = (availableWidth / data[0].values.length) * .9;
206             return 'm0,0l0,'
207                  + (y(getOpen(d,i))
208                  - y(getHigh(d,i)))
209                  + 'l'
210                  + (-w/2)
211                  + ',0l'
212                  + (w/2)
213                  + ',0l0,'
214                  + (y(getLow(d,i))
215                  - y(getOpen(d,i)))
216                  + 'l0,'
217                  + (y(getClose(d,i))
218                  - y(getLow(d,i)))
219                  + 'l'
220                  + (w/2)
221                  + ',0l'
222                  + (-w/2)
223                  + ',0z';
224           })
225           //.attr('width', (availableWidth / data[0].values.length) * .9 )
226
227
228       //d3.transition(ticks)
229           //.attr('y', function(d,i) {  return y(Math.max(0, getY(d,i))) })
230           //.attr('height', function(d,i) { return Math.abs(y(getY(d,i)) - y(0)) });
231           //.order();  // not sure if this makes any sense for this model
232
233     });
234
235     return chart;
236   }
237
238
239   //============================================================
240   // Expose Public Variables
241   //------------------------------------------------------------
242
243   chart.dispatch = dispatch;
244
245   chart.options = nv.utils.optionsFunc.bind(chart);
246
247   chart.x = function(_) {
248     if (!arguments.length) return getX;
249     getX = _;
250     return chart;
251   };
252
253   chart.y = function(_) {
254     if (!arguments.length) return getY;
255     getY = _;
256     return chart;
257   };
258
259   chart.open = function(_) {
260     if (!arguments.length) return getOpen;
261     getOpen = _;
262     return chart;
263   };
264
265   chart.close = function(_) {
266     if (!arguments.length) return getClose;
267     getClose = _;
268     return chart;
269   };
270
271   chart.high = function(_) {
272     if (!arguments.length) return getHigh;
273     getHigh = _;
274     return chart;
275   };
276
277   chart.low = function(_) {
278     if (!arguments.length) return getLow;
279     getLow = _;
280     return chart;
281   };
282
283   chart.margin = function(_) {
284     if (!arguments.length) return margin;
285     margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;
286     margin.right  = typeof _.right  != 'undefined' ? _.right  : margin.right;
287     margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
288     margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;
289     return chart;
290   };
291
292   chart.width = function(_) {
293     if (!arguments.length) return width;
294     width = _;
295     return chart;
296   };
297
298   chart.height = function(_) {
299     if (!arguments.length) return height;
300     height = _;
301     return chart;
302   };
303
304   chart.xScale = function(_) {
305     if (!arguments.length) return x;
306     x = _;
307     return chart;
308   };
309
310   chart.yScale = function(_) {
311     if (!arguments.length) return y;
312     y = _;
313     return chart;
314   };
315
316   chart.xDomain = function(_) {
317     if (!arguments.length) return xDomain;
318     xDomain = _;
319     return chart;
320   };
321
322   chart.yDomain = function(_) {
323     if (!arguments.length) return yDomain;
324     yDomain = _;
325     return chart;
326   };
327
328   chart.xRange = function(_) {
329     if (!arguments.length) return xRange;
330     xRange = _;
331     return chart;
332   };
333
334   chart.yRange = function(_) {
335     if (!arguments.length) return yRange;
336     yRange = _;
337     return chart;
338   };
339
340   chart.forceX = function(_) {
341     if (!arguments.length) return forceX;
342     forceX = _;
343     return chart;
344   };
345
346   chart.forceY = function(_) {
347     if (!arguments.length) return forceY;
348     forceY = _;
349     return chart;
350   };
351
352   chart.padData = function(_) {
353     if (!arguments.length) return padData;
354     padData = _;
355     return chart;
356   };
357
358   chart.clipEdge = function(_) {
359     if (!arguments.length) return clipEdge;
360     clipEdge = _;
361     return chart;
362   };
363
364   chart.color = function(_) {
365     if (!arguments.length) return color;
366     color = nv.utils.getColor(_);
367     return chart;
368   };
369
370   chart.id = function(_) {
371     if (!arguments.length) return id;
372     id = _;
373     return chart;
374   };
375
376   //============================================================
377
378
379   return chart;
380 }