pyk 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }