pyk 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +8 -8
  2. data/app/assets/javascripts/lib/chardinjs.min.js +2 -0
  3. data/app/assets/javascripts/lib/crossfilter.js +1383 -1
  4. data/app/assets/javascripts/lib/{d3.js → d3.v3.js} +0 -0
  5. data/app/assets/javascripts/lib/dc.js +3492 -757
  6. data/app/assets/javascripts/lib/jquery.gridster.js +2 -3621
  7. data/app/assets/javascripts/lib/markermanager.js +2 -980
  8. data/app/assets/javascripts/lib/underscore.js +1276 -0
  9. data/app/assets/javascripts/nvd3/lib/colorbrewer.js +302 -0
  10. data/app/assets/javascripts/nvd3/lib/crossfilter.js +1180 -0
  11. data/app/assets/javascripts/nvd3/lib/crossfilter.min.js +1 -0
  12. data/app/assets/javascripts/nvd3/lib/d3.v2.js +7033 -0
  13. data/app/assets/javascripts/nvd3/lib/d3.v2.min.js +4 -0
  14. data/app/assets/javascripts/nvd3/lib/d3.v3.js +8436 -0
  15. data/app/assets/javascripts/nvd3/lib/fisheye.js +86 -0
  16. data/app/assets/javascripts/nvd3/lib/hive.js +80 -0
  17. data/app/assets/javascripts/nvd3/lib/horizon.js +192 -0
  18. data/app/assets/javascripts/nvd3/lib/sankey.js +292 -0
  19. data/app/assets/javascripts/nvd3/nv.d3.js +14312 -0
  20. data/app/assets/javascripts/nvd3/nv.d3.min.js +6 -0
  21. data/app/assets/javascripts/nvd3/src/core.js +122 -0
  22. data/app/assets/javascripts/nvd3/src/interactiveLayer.js +251 -0
  23. data/app/assets/javascripts/nvd3/src/models/axis.js +405 -0
  24. data/app/assets/javascripts/nvd3/src/models/backup/bullet.js +250 -0
  25. data/app/assets/javascripts/nvd3/src/models/backup/bulletChart.js +349 -0
  26. data/app/assets/javascripts/nvd3/src/models/boilerplate.js +104 -0
  27. data/app/assets/javascripts/nvd3/src/models/bullet.js +385 -0
  28. data/app/assets/javascripts/nvd3/src/models/bulletChart.js +343 -0
  29. data/app/assets/javascripts/nvd3/src/models/cumulativeLineChart.js +782 -0
  30. data/app/assets/javascripts/nvd3/src/models/discreteBar.js +349 -0
  31. data/app/assets/javascripts/nvd3/src/models/discreteBarChart.js +333 -0
  32. data/app/assets/javascripts/nvd3/src/models/distribution.js +148 -0
  33. data/app/assets/javascripts/nvd3/src/models/historicalBar.js +331 -0
  34. data/app/assets/javascripts/nvd3/src/models/historicalBarChart.js +419 -0
  35. data/app/assets/javascripts/nvd3/src/models/indentedTree.js +337 -0
  36. data/app/assets/javascripts/nvd3/src/models/legend.js +270 -0
  37. data/app/assets/javascripts/nvd3/src/models/line.js +284 -0
  38. data/app/assets/javascripts/nvd3/src/models/lineChart.js +465 -0
  39. data/app/assets/javascripts/nvd3/src/models/linePlusBarChart.js +433 -0
  40. data/app/assets/javascripts/nvd3/src/models/linePlusBarWithFocusChart.js +658 -0
  41. data/app/assets/javascripts/nvd3/src/models/lineWithFisheye.js +200 -0
  42. data/app/assets/javascripts/nvd3/src/models/lineWithFisheyeChart.js +297 -0
  43. data/app/assets/javascripts/nvd3/src/models/lineWithFocusChart.js +574 -0
  44. data/app/assets/javascripts/nvd3/src/models/multiBar.js +461 -0
  45. data/app/assets/javascripts/nvd3/src/models/multiBarChart.js +524 -0
  46. data/app/assets/javascripts/nvd3/src/models/multiBarHorizontal.js +424 -0
  47. data/app/assets/javascripts/nvd3/src/models/multiBarHorizontalChart.js +434 -0
  48. data/app/assets/javascripts/nvd3/src/models/multiBarTimeSeries.js +384 -0
  49. data/app/assets/javascripts/nvd3/src/models/multiBarTimeSeriesChart.js +405 -0
  50. data/app/assets/javascripts/nvd3/src/models/multiChart.js +452 -0
  51. data/app/assets/javascripts/nvd3/src/models/ohlcBar.js +380 -0
  52. data/app/assets/javascripts/nvd3/src/models/parallelCoordinates.js +239 -0
  53. data/app/assets/javascripts/nvd3/src/models/pie.js +398 -0
  54. data/app/assets/javascripts/nvd3/src/models/pieChart.js +292 -0
  55. data/app/assets/javascripts/nvd3/src/models/scatter.js +674 -0
  56. data/app/assets/javascripts/nvd3/src/models/scatterChart.js +628 -0
  57. data/app/assets/javascripts/nvd3/src/models/scatterPlusLineChart.js +620 -0
  58. data/app/assets/javascripts/nvd3/src/models/sparkline.js +194 -0
  59. data/app/assets/javascripts/nvd3/src/models/sparklinePlus.js +295 -0
  60. data/app/assets/javascripts/nvd3/src/models/stackedArea.js +368 -0
  61. data/app/assets/javascripts/nvd3/src/models/stackedAreaChart.js +629 -0
  62. data/app/assets/javascripts/nvd3/src/tooltip.js +490 -0
  63. data/app/assets/javascripts/nvd3/src/utils.js +152 -0
  64. data/app/assets/javascripts/pyk.js +1 -0
  65. data/app/assets/stylesheets/lib/chardinjs.css +82 -0
  66. data/app/assets/stylesheets/nvd3/nv.d3.css +769 -0
  67. data/app/assets/stylesheets/pyk.css.scss +1 -0
  68. metadata +61 -2
@@ -0,0 +1,368 @@
1
+
2
+ nv.models.stackedArea = 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
+ , color = nv.utils.defaultColor() // a function that computes the color
12
+ , id = Math.floor(Math.random() * 100000) //Create semi-unique ID incase user doesn't selet one
13
+ , getX = function(d) { return d.x } // accessor to get the x value from a data point
14
+ , getY = function(d) { return d.y } // accessor to get the y value from a data point
15
+ , style = 'stack'
16
+ , offset = 'zero'
17
+ , order = 'default'
18
+ , interpolate = 'linear' // controls the line interpolation
19
+ , clipEdge = false // if true, masks lines within x and y scale
20
+ , x //can be accessed via chart.xScale()
21
+ , y //can be accessed via chart.yScale()
22
+ , scatter = nv.models.scatter()
23
+ , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'areaClick', 'areaMouseover', 'areaMouseout')
24
+ ;
25
+
26
+ scatter
27
+ .size(2.2) // default size
28
+ .sizeDomain([2.2,2.2]) // all the same size by default
29
+ ;
30
+
31
+ /************************************
32
+ * offset:
33
+ * 'wiggle' (stream)
34
+ * 'zero' (stacked)
35
+ * 'expand' (normalize to 100%)
36
+ * 'silhouette' (simple centered)
37
+ *
38
+ * order:
39
+ * 'inside-out' (stream)
40
+ * 'default' (input order)
41
+ ************************************/
42
+
43
+ //============================================================
44
+
45
+
46
+ function chart(selection) {
47
+ selection.each(function(data) {
48
+ var availableWidth = width - margin.left - margin.right,
49
+ availableHeight = height - margin.top - margin.bottom,
50
+ container = d3.select(this);
51
+
52
+ //------------------------------------------------------------
53
+ // Setup Scales
54
+
55
+ x = scatter.xScale();
56
+ y = scatter.yScale();
57
+
58
+ //------------------------------------------------------------
59
+
60
+ var dataRaw = data;
61
+ // Injecting point index into each point because d3.layout.stack().out does not give index
62
+ data.forEach(function(aseries, i) {
63
+ aseries.seriesIndex = i;
64
+ aseries.values = aseries.values.map(function(d, j) {
65
+ d.index = j;
66
+ d.seriesIndex = i;
67
+ return d;
68
+ });
69
+ });
70
+
71
+ var dataFiltered = data.filter(function(series) {
72
+ return !series.disabled;
73
+ });
74
+
75
+ data = d3.layout.stack()
76
+ .order(order)
77
+ .offset(offset)
78
+ .values(function(d) { return d.values }) //TODO: make values customizeable in EVERY model in this fashion
79
+ .x(getX)
80
+ .y(getY)
81
+ .out(function(d, y0, y) {
82
+ var yHeight = (getY(d) === 0) ? 0 : y;
83
+ d.display = {
84
+ y: yHeight,
85
+ y0: y0
86
+ };
87
+ })
88
+ (dataFiltered);
89
+
90
+
91
+ //------------------------------------------------------------
92
+ // Setup containers and skeleton of chart
93
+
94
+ var wrap = container.selectAll('g.nv-wrap.nv-stackedarea').data([data]);
95
+ var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-stackedarea');
96
+ var defsEnter = wrapEnter.append('defs');
97
+ var gEnter = wrapEnter.append('g');
98
+ var g = wrap.select('g');
99
+
100
+ gEnter.append('g').attr('class', 'nv-areaWrap');
101
+ gEnter.append('g').attr('class', 'nv-scatterWrap');
102
+
103
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
104
+
105
+ //------------------------------------------------------------
106
+
107
+
108
+ scatter
109
+ .width(availableWidth)
110
+ .height(availableHeight)
111
+ .x(getX)
112
+ .y(function(d) { return d.display.y + d.display.y0 })
113
+ .forceY([0])
114
+ .color(data.map(function(d,i) {
115
+ return d.color || color(d, d.seriesIndex);
116
+ }));
117
+
118
+
119
+ var scatterWrap = g.select('.nv-scatterWrap')
120
+ .datum(data);
121
+
122
+ scatterWrap.call(scatter);
123
+
124
+ defsEnter.append('clipPath')
125
+ .attr('id', 'nv-edge-clip-' + id)
126
+ .append('rect');
127
+
128
+ wrap.select('#nv-edge-clip-' + id + ' rect')
129
+ .attr('width', availableWidth)
130
+ .attr('height', availableHeight);
131
+
132
+ g .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : '');
133
+
134
+ var area = d3.svg.area()
135
+ .x(function(d,i) { return x(getX(d,i)) })
136
+ .y0(function(d) {
137
+ return y(d.display.y0)
138
+ })
139
+ .y1(function(d) {
140
+ return y(d.display.y + d.display.y0)
141
+ })
142
+ .interpolate(interpolate);
143
+
144
+ var zeroArea = d3.svg.area()
145
+ .x(function(d,i) { return x(getX(d,i)) })
146
+ .y0(function(d) { return y(d.display.y0) })
147
+ .y1(function(d) { return y(d.display.y0) });
148
+
149
+
150
+ var path = g.select('.nv-areaWrap').selectAll('path.nv-area')
151
+ .data(function(d) { return d });
152
+
153
+ path.enter().append('path').attr('class', function(d,i) { return 'nv-area nv-area-' + i })
154
+ .attr('d', function(d,i){
155
+ return zeroArea(d.values, d.seriesIndex);
156
+ })
157
+ .on('mouseover', function(d,i) {
158
+ d3.select(this).classed('hover', true);
159
+ dispatch.areaMouseover({
160
+ point: d,
161
+ series: d.key,
162
+ pos: [d3.event.pageX, d3.event.pageY],
163
+ seriesIndex: i
164
+ });
165
+ })
166
+ .on('mouseout', function(d,i) {
167
+ d3.select(this).classed('hover', false);
168
+ dispatch.areaMouseout({
169
+ point: d,
170
+ series: d.key,
171
+ pos: [d3.event.pageX, d3.event.pageY],
172
+ seriesIndex: i
173
+ });
174
+ })
175
+ .on('click', function(d,i) {
176
+ d3.select(this).classed('hover', false);
177
+ dispatch.areaClick({
178
+ point: d,
179
+ series: d.key,
180
+ pos: [d3.event.pageX, d3.event.pageY],
181
+ seriesIndex: i
182
+ });
183
+ })
184
+ path.exit().transition()
185
+ .attr('d', function(d,i) { return zeroArea(d.values,i) })
186
+ .remove();
187
+ path
188
+ .style('fill', function(d,i){
189
+ return d.color || color(d, d.seriesIndex)
190
+ })
191
+ .style('stroke', function(d,i){ return d.color || color(d, d.seriesIndex) });
192
+ path.transition()
193
+ .attr('d', function(d,i) {
194
+ return area(d.values,i)
195
+ });
196
+
197
+
198
+
199
+ //============================================================
200
+ // Event Handling/Dispatching (in chart's scope)
201
+ //------------------------------------------------------------
202
+
203
+ scatter.dispatch.on('elementMouseover.area', function(e) {
204
+ g.select('.nv-chart-' + id + ' .nv-area-' + e.seriesIndex).classed('hover', true);
205
+ });
206
+ scatter.dispatch.on('elementMouseout.area', function(e) {
207
+ g.select('.nv-chart-' + id + ' .nv-area-' + e.seriesIndex).classed('hover', false);
208
+ });
209
+
210
+ //============================================================
211
+ //Special offset functions
212
+ chart.d3_stackedOffset_stackPercent = function(stackData) {
213
+ var n = stackData.length, //How many series
214
+ m = stackData[0].length, //how many points per series
215
+ k = 1 / n,
216
+ i,
217
+ j,
218
+ o,
219
+ y0 = [];
220
+
221
+ for (j = 0; j < m; ++j) { //Looping through all points
222
+ for (i = 0, o = 0; i < dataRaw.length; i++) //looping through series'
223
+ o += getY(dataRaw[i].values[j]) //total value of all points at a certian point in time.
224
+
225
+ if (o) for (i = 0; i < n; i++)
226
+ stackData[i][j][1] /= o;
227
+ else
228
+ for (i = 0; i < n; i++)
229
+ stackData[i][j][1] = k;
230
+ }
231
+ for (j = 0; j < m; ++j) y0[j] = 0;
232
+ return y0;
233
+ };
234
+
235
+ });
236
+
237
+
238
+ return chart;
239
+ }
240
+
241
+
242
+ //============================================================
243
+ // Event Handling/Dispatching (out of chart's scope)
244
+ //------------------------------------------------------------
245
+
246
+ scatter.dispatch.on('elementClick.area', function(e) {
247
+ dispatch.areaClick(e);
248
+ })
249
+ scatter.dispatch.on('elementMouseover.tooltip', function(e) {
250
+ e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top],
251
+ dispatch.tooltipShow(e);
252
+ });
253
+ scatter.dispatch.on('elementMouseout.tooltip', function(e) {
254
+ dispatch.tooltipHide(e);
255
+ });
256
+
257
+ //============================================================
258
+
259
+ //============================================================
260
+ // Global getters and setters
261
+ //------------------------------------------------------------
262
+
263
+ chart.dispatch = dispatch;
264
+ chart.scatter = scatter;
265
+
266
+ d3.rebind(chart, scatter, 'interactive', 'size', 'xScale', 'yScale', 'zScale', 'xDomain', 'yDomain', 'xRange', 'yRange',
267
+ 'sizeDomain', 'forceX', 'forceY', 'forceSize', 'clipVoronoi', 'useVoronoi','clipRadius','highlightPoint','clearHighlights');
268
+
269
+ chart.options = nv.utils.optionsFunc.bind(chart);
270
+
271
+ chart.x = function(_) {
272
+ if (!arguments.length) return getX;
273
+ getX = d3.functor(_);
274
+ return chart;
275
+ };
276
+
277
+ chart.y = function(_) {
278
+ if (!arguments.length) return getY;
279
+ getY = d3.functor(_);
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.clipEdge = function(_) {
305
+ if (!arguments.length) return clipEdge;
306
+ clipEdge = _;
307
+ return chart;
308
+ };
309
+
310
+ chart.color = function(_) {
311
+ if (!arguments.length) return color;
312
+ color = nv.utils.getColor(_);
313
+ return chart;
314
+ };
315
+
316
+ chart.offset = function(_) {
317
+ if (!arguments.length) return offset;
318
+ offset = _;
319
+ return chart;
320
+ };
321
+
322
+ chart.order = function(_) {
323
+ if (!arguments.length) return order;
324
+ order = _;
325
+ return chart;
326
+ };
327
+
328
+ //shortcut for offset + order
329
+ chart.style = function(_) {
330
+ if (!arguments.length) return style;
331
+ style = _;
332
+
333
+ switch (style) {
334
+ case 'stack':
335
+ chart.offset('zero');
336
+ chart.order('default');
337
+ break;
338
+ case 'stream':
339
+ chart.offset('wiggle');
340
+ chart.order('inside-out');
341
+ break;
342
+ case 'stream-center':
343
+ chart.offset('silhouette');
344
+ chart.order('inside-out');
345
+ break;
346
+ case 'expand':
347
+ chart.offset('expand');
348
+ chart.order('default');
349
+ break;
350
+ case 'stack_percent':
351
+ chart.offset(chart.d3_stackedOffset_stackPercent);
352
+ chart.order('default');
353
+ break;
354
+ }
355
+
356
+ return chart;
357
+ };
358
+
359
+ chart.interpolate = function(_) {
360
+ if (!arguments.length) return interpolate;
361
+ interpolate = _;
362
+ return chart;
363
+ };
364
+ //============================================================
365
+
366
+
367
+ return chart;
368
+ }
@@ -0,0 +1,629 @@
1
+
2
+ nv.models.stackedAreaChart = function() {
3
+ "use strict";
4
+ //============================================================
5
+ // Public Variables with Default Settings
6
+ //------------------------------------------------------------
7
+
8
+ var stacked = nv.models.stackedArea()
9
+ , xAxis = nv.models.axis()
10
+ , yAxis = nv.models.axis()
11
+ , legend = nv.models.legend()
12
+ , controls = nv.models.legend()
13
+ , interactiveLayer = nv.interactiveGuideline()
14
+ ;
15
+
16
+ var margin = {top: 30, right: 25, bottom: 50, left: 60}
17
+ , width = null
18
+ , height = null
19
+ , color = nv.utils.defaultColor() // a function that takes in d, i and returns color
20
+ , showControls = true
21
+ , showLegend = true
22
+ , showXAxis = true
23
+ , showYAxis = true
24
+ , rightAlignYAxis = false
25
+ , useInteractiveGuideline = false
26
+ , tooltips = true
27
+ , tooltip = function(key, x, y, e, graph) {
28
+ return '<h3>' + key + '</h3>' +
29
+ '<p>' + y + ' on ' + x + '</p>'
30
+ }
31
+ , x //can be accessed via chart.xScale()
32
+ , y //can be accessed via chart.yScale()
33
+ , yAxisTickFormat = d3.format(',.2f')
34
+ , state = { style: stacked.style() }
35
+ , defaultState = null
36
+ , noData = 'No Data Available.'
37
+ , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState')
38
+ , controlWidth = 250
39
+ , cData = ['Stacked','Stream','Expanded']
40
+ , controlLabels = {}
41
+ , transitionDuration = 250
42
+ ;
43
+
44
+ xAxis
45
+ .orient('bottom')
46
+ .tickPadding(7)
47
+ ;
48
+ yAxis
49
+ .orient((rightAlignYAxis) ? 'right' : 'left')
50
+ ;
51
+
52
+ controls.updateState(false);
53
+ //============================================================
54
+
55
+
56
+ //============================================================
57
+ // Private Variables
58
+ //------------------------------------------------------------
59
+
60
+ var showTooltip = function(e, offsetElement) {
61
+ var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
62
+ top = e.pos[1] + ( offsetElement.offsetTop || 0),
63
+ x = xAxis.tickFormat()(stacked.x()(e.point, e.pointIndex)),
64
+ y = yAxis.tickFormat()(stacked.y()(e.point, e.pointIndex)),
65
+ content = tooltip(e.series.key, x, y, e, chart);
66
+
67
+ nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's', null, offsetElement);
68
+ };
69
+
70
+ //============================================================
71
+
72
+
73
+ function chart(selection) {
74
+ selection.each(function(data) {
75
+ var container = d3.select(this),
76
+ that = this;
77
+
78
+ var availableWidth = (width || parseInt(container.style('width')) || 960)
79
+ - margin.left - margin.right,
80
+ availableHeight = (height || parseInt(container.style('height')) || 400)
81
+ - margin.top - margin.bottom;
82
+
83
+ chart.update = function() { container.transition().duration(transitionDuration).call(chart); };
84
+ chart.container = this;
85
+
86
+ //set state.disabled
87
+ state.disabled = data.map(function(d) { return !!d.disabled });
88
+
89
+ if (!defaultState) {
90
+ var key;
91
+ defaultState = {};
92
+ for (key in state) {
93
+ if (state[key] instanceof Array)
94
+ defaultState[key] = state[key].slice(0);
95
+ else
96
+ defaultState[key] = state[key];
97
+ }
98
+ }
99
+
100
+ //------------------------------------------------------------
101
+ // Display No Data message if there's nothing to show.
102
+
103
+ if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {
104
+ var noDataText = container.selectAll('.nv-noData').data([noData]);
105
+
106
+ noDataText.enter().append('text')
107
+ .attr('class', 'nvd3 nv-noData')
108
+ .attr('dy', '-.7em')
109
+ .style('text-anchor', 'middle');
110
+
111
+ noDataText
112
+ .attr('x', margin.left + availableWidth / 2)
113
+ .attr('y', margin.top + availableHeight / 2)
114
+ .text(function(d) { return d });
115
+
116
+ return chart;
117
+ } else {
118
+ container.selectAll('.nv-noData').remove();
119
+ }
120
+
121
+ //------------------------------------------------------------
122
+
123
+
124
+ //------------------------------------------------------------
125
+ // Setup Scales
126
+
127
+ x = stacked.xScale();
128
+ y = stacked.yScale();
129
+
130
+ //------------------------------------------------------------
131
+
132
+
133
+ //------------------------------------------------------------
134
+ // Setup containers and skeleton of chart
135
+
136
+ var wrap = container.selectAll('g.nv-wrap.nv-stackedAreaChart').data([data]);
137
+ var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-stackedAreaChart').append('g');
138
+ var g = wrap.select('g');
139
+
140
+ gEnter.append("rect").style("opacity",0);
141
+ gEnter.append('g').attr('class', 'nv-x nv-axis');
142
+ gEnter.append('g').attr('class', 'nv-y nv-axis');
143
+ gEnter.append('g').attr('class', 'nv-stackedWrap');
144
+ gEnter.append('g').attr('class', 'nv-legendWrap');
145
+ gEnter.append('g').attr('class', 'nv-controlsWrap');
146
+ gEnter.append('g').attr('class', 'nv-interactive');
147
+
148
+ g.select("rect").attr("width",availableWidth).attr("height",availableHeight);
149
+ //------------------------------------------------------------
150
+ // Legend
151
+
152
+ if (showLegend) {
153
+ var legendWidth = (showControls) ? availableWidth - controlWidth : availableWidth;
154
+ legend
155
+ .width(legendWidth);
156
+
157
+ g.select('.nv-legendWrap')
158
+ .datum(data)
159
+ .call(legend);
160
+
161
+ if ( margin.top != legend.height()) {
162
+ margin.top = legend.height();
163
+ availableHeight = (height || parseInt(container.style('height')) || 400)
164
+ - margin.top - margin.bottom;
165
+ }
166
+
167
+ g.select('.nv-legendWrap')
168
+ .attr('transform', 'translate(' + (availableWidth-legendWidth) + ',' + (-margin.top) +')');
169
+ }
170
+
171
+ //------------------------------------------------------------
172
+
173
+
174
+ //------------------------------------------------------------
175
+ // Controls
176
+
177
+ if (showControls) {
178
+ var controlsData = [
179
+ {
180
+ key: controlLabels.stacked || 'Stacked',
181
+ metaKey: 'Stacked',
182
+ disabled: stacked.style() != 'stack',
183
+ style: 'stack'
184
+ },
185
+ {
186
+ key: controlLabels.stream || 'Stream',
187
+ metaKey: 'Stream',
188
+ disabled: stacked.style() != 'stream',
189
+ style: 'stream'
190
+ },
191
+ {
192
+ key: controlLabels.expanded || 'Expanded',
193
+ metaKey: 'Expanded',
194
+ disabled: stacked.style() != 'expand',
195
+ style: 'expand'
196
+ },
197
+ {
198
+ key: controlLabels.stack_percent || 'Stack %',
199
+ metaKey: 'Stack_Percent',
200
+ disabled: stacked.style() != 'stack_percent',
201
+ style: 'stack_percent'
202
+ }
203
+ ];
204
+
205
+ controlWidth = (cData.length/3) * 260;
206
+
207
+ controlsData = controlsData.filter(function(d) {
208
+ return cData.indexOf(d.metaKey) !== -1;
209
+ })
210
+
211
+ controls
212
+ .width( controlWidth )
213
+ .color(['#444', '#444', '#444']);
214
+
215
+ g.select('.nv-controlsWrap')
216
+ .datum(controlsData)
217
+ .call(controls);
218
+
219
+
220
+ if ( margin.top != Math.max(controls.height(), legend.height()) ) {
221
+ margin.top = Math.max(controls.height(), legend.height());
222
+ availableHeight = (height || parseInt(container.style('height')) || 400)
223
+ - margin.top - margin.bottom;
224
+ }
225
+
226
+
227
+ g.select('.nv-controlsWrap')
228
+ .attr('transform', 'translate(0,' + (-margin.top) +')');
229
+ }
230
+
231
+ //------------------------------------------------------------
232
+
233
+
234
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
235
+
236
+ if (rightAlignYAxis) {
237
+ g.select(".nv-y.nv-axis")
238
+ .attr("transform", "translate(" + availableWidth + ",0)");
239
+ }
240
+
241
+ //------------------------------------------------------------
242
+ // Main Chart Component(s)
243
+
244
+ //------------------------------------------------------------
245
+ //Set up interactive layer
246
+ if (useInteractiveGuideline) {
247
+ interactiveLayer
248
+ .width(availableWidth)
249
+ .height(availableHeight)
250
+ .margin({left: margin.left, top: margin.top})
251
+ .svgContainer(container)
252
+ .xScale(x);
253
+ wrap.select(".nv-interactive").call(interactiveLayer);
254
+ }
255
+
256
+ stacked
257
+ .width(availableWidth)
258
+ .height(availableHeight)
259
+
260
+ var stackedWrap = g.select('.nv-stackedWrap')
261
+ .datum(data);
262
+
263
+ stackedWrap.transition().call(stacked);
264
+
265
+ //------------------------------------------------------------
266
+
267
+
268
+ //------------------------------------------------------------
269
+ // Setup Axes
270
+
271
+ if (showXAxis) {
272
+ xAxis
273
+ .scale(x)
274
+ .ticks( availableWidth / 100 )
275
+ .tickSize( -availableHeight, 0);
276
+
277
+ g.select('.nv-x.nv-axis')
278
+ .attr('transform', 'translate(0,' + availableHeight + ')');
279
+
280
+ g.select('.nv-x.nv-axis')
281
+ .transition().duration(0)
282
+ .call(xAxis);
283
+ }
284
+
285
+ if (showYAxis) {
286
+ yAxis
287
+ .scale(y)
288
+ .ticks(stacked.offset() == 'wiggle' ? 0 : availableHeight / 36)
289
+ .tickSize(-availableWidth, 0)
290
+ .setTickFormat( (stacked.style() == 'expand' || stacked.style() == 'stack_percent')
291
+ ? d3.format('%') : yAxisTickFormat);
292
+
293
+ g.select('.nv-y.nv-axis')
294
+ .transition().duration(0)
295
+ .call(yAxis);
296
+ }
297
+
298
+ //------------------------------------------------------------
299
+
300
+
301
+ //============================================================
302
+ // Event Handling/Dispatching (in chart's scope)
303
+ //------------------------------------------------------------
304
+
305
+ stacked.dispatch.on('areaClick.toggle', function(e) {
306
+ if (data.filter(function(d) { return !d.disabled }).length === 1)
307
+ data.forEach(function(d) {
308
+ d.disabled = false;
309
+ });
310
+ else
311
+ data.forEach(function(d,i) {
312
+ d.disabled = (i != e.seriesIndex);
313
+ });
314
+
315
+ state.disabled = data.map(function(d) { return !!d.disabled });
316
+ dispatch.stateChange(state);
317
+
318
+ chart.update();
319
+ });
320
+
321
+ legend.dispatch.on('stateChange', function(newState) {
322
+ state.disabled = newState.disabled;
323
+ dispatch.stateChange(state);
324
+ chart.update();
325
+ });
326
+
327
+ controls.dispatch.on('legendClick', function(d,i) {
328
+ if (!d.disabled) return;
329
+
330
+ controlsData = controlsData.map(function(s) {
331
+ s.disabled = true;
332
+ return s;
333
+ });
334
+ d.disabled = false;
335
+
336
+ stacked.style(d.style);
337
+
338
+
339
+ state.style = stacked.style();
340
+ dispatch.stateChange(state);
341
+
342
+ chart.update();
343
+ });
344
+
345
+
346
+ interactiveLayer.dispatch.on('elementMousemove', function(e) {
347
+ stacked.clearHighlights();
348
+ var singlePoint, pointIndex, pointXLocation, allData = [];
349
+ data
350
+ .filter(function(series, i) {
351
+ series.seriesIndex = i;
352
+ return !series.disabled;
353
+ })
354
+ .forEach(function(series,i) {
355
+ pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());
356
+ stacked.highlightPoint(i, pointIndex, true);
357
+ var point = series.values[pointIndex];
358
+ if (typeof point === 'undefined') return;
359
+ if (typeof singlePoint === 'undefined') singlePoint = point;
360
+ if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex));
361
+
362
+ //If we are in 'expand' mode, use the stacked percent value instead of raw value.
363
+ var tooltipValue = (stacked.style() == 'expand') ? point.display.y : chart.y()(point,pointIndex);
364
+ allData.push({
365
+ key: series.key,
366
+ value: tooltipValue,
367
+ color: color(series,series.seriesIndex),
368
+ stackedValue: point.display
369
+ });
370
+ });
371
+
372
+ allData.reverse();
373
+
374
+ //Highlight the tooltip entry based on which stack the mouse is closest to.
375
+ if (allData.length > 2) {
376
+ var yValue = chart.yScale().invert(e.mouseY);
377
+ var yDistMax = Infinity, indexToHighlight = null;
378
+ allData.forEach(function(series,i) {
379
+ if ( yValue >= series.stackedValue.y0 && yValue <= (series.stackedValue.y0 + series.stackedValue.y))
380
+ {
381
+ indexToHighlight = i;
382
+ return;
383
+ }
384
+ });
385
+ if (indexToHighlight != null)
386
+ allData[indexToHighlight].highlight = true;
387
+ }
388
+
389
+ var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex));
390
+
391
+ //If we are in 'expand' mode, force the format to be a percentage.
392
+ var valueFormatter = (stacked.style() == 'expand') ?
393
+ function(d,i) {return d3.format(".1%")(d);} :
394
+ function(d,i) {return yAxis.tickFormat()(d); };
395
+ interactiveLayer.tooltip
396
+ .position({left: pointXLocation + margin.left, top: e.mouseY + margin.top})
397
+ .chartContainer(that.parentNode)
398
+ .enabled(tooltips)
399
+ .valueFormatter(valueFormatter)
400
+ .data(
401
+ {
402
+ value: xValue,
403
+ series: allData
404
+ }
405
+ )();
406
+
407
+ interactiveLayer.renderGuideLine(pointXLocation);
408
+
409
+ });
410
+
411
+ interactiveLayer.dispatch.on("elementMouseout",function(e) {
412
+ dispatch.tooltipHide();
413
+ stacked.clearHighlights();
414
+ });
415
+
416
+
417
+ dispatch.on('tooltipShow', function(e) {
418
+ if (tooltips) showTooltip(e, that.parentNode);
419
+ });
420
+
421
+ // Update chart from a state object passed to event handler
422
+ dispatch.on('changeState', function(e) {
423
+
424
+ if (typeof e.disabled !== 'undefined') {
425
+ data.forEach(function(series,i) {
426
+ series.disabled = e.disabled[i];
427
+ });
428
+
429
+ state.disabled = e.disabled;
430
+ }
431
+
432
+ if (typeof e.style !== 'undefined') {
433
+ stacked.style(e.style);
434
+ }
435
+
436
+ chart.update();
437
+ });
438
+
439
+ });
440
+
441
+
442
+ return chart;
443
+ }
444
+
445
+
446
+ //============================================================
447
+ // Event Handling/Dispatching (out of chart's scope)
448
+ //------------------------------------------------------------
449
+
450
+ stacked.dispatch.on('tooltipShow', function(e) {
451
+ //disable tooltips when value ~= 0
452
+ //// TODO: consider removing points from voronoi that have 0 value instead of this hack
453
+ /*
454
+ if (!Math.round(stacked.y()(e.point) * 100)) { // 100 will not be good for very small numbers... will have to think about making this valu dynamic, based on data range
455
+ setTimeout(function() { d3.selectAll('.point.hover').classed('hover', false) }, 0);
456
+ return false;
457
+ }
458
+ */
459
+
460
+ e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top],
461
+ dispatch.tooltipShow(e);
462
+ });
463
+
464
+ stacked.dispatch.on('tooltipHide', function(e) {
465
+ dispatch.tooltipHide(e);
466
+ });
467
+
468
+ dispatch.on('tooltipHide', function() {
469
+ if (tooltips) nv.tooltip.cleanup();
470
+ });
471
+
472
+ //============================================================
473
+
474
+
475
+ //============================================================
476
+ // Expose Public Variables
477
+ //------------------------------------------------------------
478
+
479
+ // expose chart's sub-components
480
+ chart.dispatch = dispatch;
481
+ chart.stacked = stacked;
482
+ chart.legend = legend;
483
+ chart.controls = controls;
484
+ chart.xAxis = xAxis;
485
+ chart.yAxis = yAxis;
486
+ chart.interactiveLayer = interactiveLayer;
487
+
488
+ d3.rebind(chart, stacked, 'x', 'y', 'size', 'xScale', 'yScale', 'xDomain', 'yDomain', 'xRange', 'yRange', 'sizeDomain', 'interactive', 'useVoronoi', 'offset', 'order', 'style', 'clipEdge', 'forceX', 'forceY', 'forceSize', 'interpolate');
489
+
490
+ chart.options = nv.utils.optionsFunc.bind(chart);
491
+
492
+ chart.margin = function(_) {
493
+ if (!arguments.length) return margin;
494
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
495
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
496
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
497
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
498
+ return chart;
499
+ };
500
+
501
+ chart.width = function(_) {
502
+ if (!arguments.length) return width;
503
+ width = _;
504
+ return chart;
505
+ };
506
+
507
+ chart.height = function(_) {
508
+ if (!arguments.length) return height;
509
+ height = _;
510
+ return chart;
511
+ };
512
+
513
+ chart.color = function(_) {
514
+ if (!arguments.length) return color;
515
+ color = nv.utils.getColor(_);
516
+ legend.color(color);
517
+ stacked.color(color);
518
+ return chart;
519
+ };
520
+
521
+ chart.showControls = function(_) {
522
+ if (!arguments.length) return showControls;
523
+ showControls = _;
524
+ return chart;
525
+ };
526
+
527
+ chart.showLegend = function(_) {
528
+ if (!arguments.length) return showLegend;
529
+ showLegend = _;
530
+ return chart;
531
+ };
532
+
533
+ chart.showXAxis = function(_) {
534
+ if (!arguments.length) return showXAxis;
535
+ showXAxis = _;
536
+ return chart;
537
+ };
538
+
539
+ chart.showYAxis = function(_) {
540
+ if (!arguments.length) return showYAxis;
541
+ showYAxis = _;
542
+ return chart;
543
+ };
544
+
545
+ chart.rightAlignYAxis = function(_) {
546
+ if(!arguments.length) return rightAlignYAxis;
547
+ rightAlignYAxis = _;
548
+ yAxis.orient( (_) ? 'right' : 'left');
549
+ return chart;
550
+ };
551
+
552
+ chart.useInteractiveGuideline = function(_) {
553
+ if(!arguments.length) return useInteractiveGuideline;
554
+ useInteractiveGuideline = _;
555
+ if (_ === true) {
556
+ chart.interactive(false);
557
+ chart.useVoronoi(false);
558
+ }
559
+ return chart;
560
+ };
561
+
562
+ chart.tooltip = function(_) {
563
+ if (!arguments.length) return tooltip;
564
+ tooltip = _;
565
+ return chart;
566
+ };
567
+
568
+ chart.tooltips = function(_) {
569
+ if (!arguments.length) return tooltips;
570
+ tooltips = _;
571
+ return chart;
572
+ };
573
+
574
+ chart.tooltipContent = function(_) {
575
+ if (!arguments.length) return tooltip;
576
+ tooltip = _;
577
+ return chart;
578
+ };
579
+
580
+ chart.state = function(_) {
581
+ if (!arguments.length) return state;
582
+ state = _;
583
+ return chart;
584
+ };
585
+
586
+ chart.defaultState = function(_) {
587
+ if (!arguments.length) return defaultState;
588
+ defaultState = _;
589
+ return chart;
590
+ };
591
+
592
+ chart.noData = function(_) {
593
+ if (!arguments.length) return noData;
594
+ noData = _;
595
+ return chart;
596
+ };
597
+
598
+ chart.transitionDuration = function(_) {
599
+ if (!arguments.length) return transitionDuration;
600
+ transitionDuration = _;
601
+ return chart;
602
+ };
603
+
604
+ chart.controlsData = function(_) {
605
+ if (!arguments.length) return cData;
606
+ cData = _;
607
+ return chart;
608
+ };
609
+
610
+ chart.controlLabels = function(_) {
611
+ if (!arguments.length) return controlLabels;
612
+ if (typeof _ !== 'object') return controlLabels;
613
+ controlLabels = _;
614
+ return chart;
615
+ };
616
+
617
+ yAxis.setTickFormat = yAxis.tickFormat;
618
+
619
+ yAxis.tickFormat = function(_) {
620
+ if (!arguments.length) return yAxisTickFormat;
621
+ yAxisTickFormat = _;
622
+ return yAxis;
623
+ };
624
+
625
+
626
+ //============================================================
627
+
628
+ return chart;
629
+ }