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,433 @@
1
+
2
+ nv.models.linePlusBarChart = function() {
3
+ "use strict";
4
+ //============================================================
5
+ // Public Variables with Default Settings
6
+ //------------------------------------------------------------
7
+
8
+ var lines = nv.models.line()
9
+ , bars = nv.models.historicalBar()
10
+ , xAxis = nv.models.axis()
11
+ , y1Axis = nv.models.axis()
12
+ , y2Axis = nv.models.axis()
13
+ , legend = nv.models.legend()
14
+ ;
15
+
16
+ var margin = {top: 30, right: 60, bottom: 50, left: 60}
17
+ , width = null
18
+ , height = null
19
+ , getX = function(d) { return d.x }
20
+ , getY = function(d) { return d.y }
21
+ , color = nv.utils.defaultColor()
22
+ , showLegend = true
23
+ , tooltips = true
24
+ , tooltip = function(key, x, y, e, graph) {
25
+ return '<h3>' + key + '</h3>' +
26
+ '<p>' + y + ' at ' + x + '</p>';
27
+ }
28
+ , x
29
+ , y1
30
+ , y2
31
+ , state = {}
32
+ , defaultState = null
33
+ , noData = "No Data Available."
34
+ , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState')
35
+ ;
36
+
37
+ bars
38
+ .padData(true)
39
+ ;
40
+ lines
41
+ .clipEdge(false)
42
+ .padData(true)
43
+ ;
44
+ xAxis
45
+ .orient('bottom')
46
+ .tickPadding(7)
47
+ .highlightZero(false)
48
+ ;
49
+ y1Axis
50
+ .orient('left')
51
+ ;
52
+ y2Axis
53
+ .orient('right')
54
+ ;
55
+
56
+ //============================================================
57
+
58
+
59
+ //============================================================
60
+ // Private Variables
61
+ //------------------------------------------------------------
62
+
63
+ var showTooltip = function(e, offsetElement) {
64
+ var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
65
+ top = e.pos[1] + ( offsetElement.offsetTop || 0),
66
+ x = xAxis.tickFormat()(lines.x()(e.point, e.pointIndex)),
67
+ y = (e.series.bar ? y1Axis : y2Axis).tickFormat()(lines.y()(e.point, e.pointIndex)),
68
+ content = tooltip(e.series.key, x, y, e, chart);
69
+
70
+ nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's', null, offsetElement);
71
+ }
72
+ ;
73
+
74
+ //------------------------------------------------------------
75
+
76
+
77
+
78
+ function chart(selection) {
79
+ selection.each(function(data) {
80
+ var container = d3.select(this),
81
+ that = this;
82
+
83
+ var availableWidth = (width || parseInt(container.style('width')) || 960)
84
+ - margin.left - margin.right,
85
+ availableHeight = (height || parseInt(container.style('height')) || 400)
86
+ - margin.top - margin.bottom;
87
+
88
+ chart.update = function() { container.transition().call(chart); };
89
+ // chart.container = this;
90
+
91
+ //set state.disabled
92
+ state.disabled = data.map(function(d) { return !!d.disabled });
93
+
94
+ if (!defaultState) {
95
+ var key;
96
+ defaultState = {};
97
+ for (key in state) {
98
+ if (state[key] instanceof Array)
99
+ defaultState[key] = state[key].slice(0);
100
+ else
101
+ defaultState[key] = state[key];
102
+ }
103
+ }
104
+
105
+ //------------------------------------------------------------
106
+ // Display No Data message if there's nothing to show.
107
+
108
+ if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {
109
+ var noDataText = container.selectAll('.nv-noData').data([noData]);
110
+
111
+ noDataText.enter().append('text')
112
+ .attr('class', 'nvd3 nv-noData')
113
+ .attr('dy', '-.7em')
114
+ .style('text-anchor', 'middle');
115
+
116
+ noDataText
117
+ .attr('x', margin.left + availableWidth / 2)
118
+ .attr('y', margin.top + availableHeight / 2)
119
+ .text(function(d) { return d });
120
+
121
+ return chart;
122
+ } else {
123
+ container.selectAll('.nv-noData').remove();
124
+ }
125
+
126
+ //------------------------------------------------------------
127
+
128
+
129
+ //------------------------------------------------------------
130
+ // Setup Scales
131
+
132
+ var dataBars = data.filter(function(d) { return !d.disabled && d.bar });
133
+ var dataLines = data.filter(function(d) { return !d.bar }); // removed the !d.disabled clause here to fix Issue #240
134
+
135
+ //x = xAxis.scale();
136
+ x = dataLines.filter(function(d) { return !d.disabled; }).length && dataLines.filter(function(d) { return !d.disabled; })[0].values.length ? lines.xScale() : bars.xScale();
137
+ //x = dataLines.filter(function(d) { return !d.disabled; }).length ? lines.xScale() : bars.xScale(); //old code before change above
138
+ y1 = bars.yScale();
139
+ y2 = lines.yScale();
140
+
141
+ //------------------------------------------------------------
142
+
143
+ //------------------------------------------------------------
144
+ // Setup containers and skeleton of chart
145
+
146
+ var wrap = d3.select(this).selectAll('g.nv-wrap.nv-linePlusBar').data([data]);
147
+ var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-linePlusBar').append('g');
148
+ var g = wrap.select('g');
149
+
150
+ gEnter.append('g').attr('class', 'nv-x nv-axis');
151
+ gEnter.append('g').attr('class', 'nv-y1 nv-axis');
152
+ gEnter.append('g').attr('class', 'nv-y2 nv-axis');
153
+ gEnter.append('g').attr('class', 'nv-barsWrap');
154
+ gEnter.append('g').attr('class', 'nv-linesWrap');
155
+ gEnter.append('g').attr('class', 'nv-legendWrap');
156
+
157
+ //------------------------------------------------------------
158
+
159
+
160
+ //------------------------------------------------------------
161
+ // Legend
162
+
163
+ if (showLegend) {
164
+ legend.width( availableWidth / 2 );
165
+
166
+ g.select('.nv-legendWrap')
167
+ .datum(data.map(function(series) {
168
+ series.originalKey = series.originalKey === undefined ? series.key : series.originalKey;
169
+ series.key = series.originalKey + (series.bar ? ' (left axis)' : ' (right axis)');
170
+ return series;
171
+ }))
172
+ .call(legend);
173
+
174
+ if ( margin.top != legend.height()) {
175
+ margin.top = legend.height();
176
+ availableHeight = (height || parseInt(container.style('height')) || 400)
177
+ - margin.top - margin.bottom;
178
+ }
179
+
180
+ g.select('.nv-legendWrap')
181
+ .attr('transform', 'translate(' + ( availableWidth / 2 ) + ',' + (-margin.top) +')');
182
+ }
183
+
184
+ //------------------------------------------------------------
185
+
186
+
187
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
188
+
189
+
190
+ //------------------------------------------------------------
191
+ // Main Chart Component(s)
192
+
193
+
194
+ lines
195
+ .width(availableWidth)
196
+ .height(availableHeight)
197
+ .color(data.map(function(d,i) {
198
+ return d.color || color(d, i);
199
+ }).filter(function(d,i) { return !data[i].disabled && !data[i].bar }))
200
+
201
+ bars
202
+ .width(availableWidth)
203
+ .height(availableHeight)
204
+ .color(data.map(function(d,i) {
205
+ return d.color || color(d, i);
206
+ }).filter(function(d,i) { return !data[i].disabled && data[i].bar }))
207
+
208
+
209
+
210
+ var barsWrap = g.select('.nv-barsWrap')
211
+ .datum(dataBars.length ? dataBars : [{values:[]}])
212
+
213
+ var linesWrap = g.select('.nv-linesWrap')
214
+ .datum(dataLines[0] && !dataLines[0].disabled ? dataLines : [{values:[]}] );
215
+ //.datum(!dataLines[0].disabled ? dataLines : [{values:dataLines[0].values.map(function(d) { return [d[0], null] }) }] );
216
+
217
+ d3.transition(barsWrap).call(bars);
218
+ d3.transition(linesWrap).call(lines);
219
+
220
+ //------------------------------------------------------------
221
+
222
+
223
+ //------------------------------------------------------------
224
+ // Setup Axes
225
+
226
+ xAxis
227
+ .scale(x)
228
+ .ticks( availableWidth / 100 )
229
+ .tickSize(-availableHeight, 0);
230
+
231
+ g.select('.nv-x.nv-axis')
232
+ .attr('transform', 'translate(0,' + y1.range()[0] + ')');
233
+ d3.transition(g.select('.nv-x.nv-axis'))
234
+ .call(xAxis);
235
+
236
+
237
+ y1Axis
238
+ .scale(y1)
239
+ .ticks( availableHeight / 36 )
240
+ .tickSize(-availableWidth, 0);
241
+
242
+ d3.transition(g.select('.nv-y1.nv-axis'))
243
+ .style('opacity', dataBars.length ? 1 : 0)
244
+ .call(y1Axis);
245
+
246
+
247
+ y2Axis
248
+ .scale(y2)
249
+ .ticks( availableHeight / 36 )
250
+ .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if y1 has none
251
+
252
+ g.select('.nv-y2.nv-axis')
253
+ .style('opacity', dataLines.length ? 1 : 0)
254
+ .attr('transform', 'translate(' + availableWidth + ',0)');
255
+ //.attr('transform', 'translate(' + x.range()[1] + ',0)');
256
+
257
+ d3.transition(g.select('.nv-y2.nv-axis'))
258
+ .call(y2Axis);
259
+
260
+ //------------------------------------------------------------
261
+
262
+
263
+ //============================================================
264
+ // Event Handling/Dispatching (in chart's scope)
265
+ //------------------------------------------------------------
266
+
267
+ legend.dispatch.on('stateChange', function(newState) {
268
+ state = newState;
269
+ dispatch.stateChange(state);
270
+ chart.update();
271
+ });
272
+
273
+ dispatch.on('tooltipShow', function(e) {
274
+ if (tooltips) showTooltip(e, that.parentNode);
275
+ });
276
+
277
+
278
+ // Update chart from a state object passed to event handler
279
+ dispatch.on('changeState', function(e) {
280
+
281
+ if (typeof e.disabled !== 'undefined') {
282
+ data.forEach(function(series,i) {
283
+ series.disabled = e.disabled[i];
284
+ });
285
+
286
+ state.disabled = e.disabled;
287
+ }
288
+
289
+ chart.update();
290
+ });
291
+
292
+ //============================================================
293
+
294
+
295
+ });
296
+
297
+ return chart;
298
+ }
299
+
300
+
301
+ //============================================================
302
+ // Event Handling/Dispatching (out of chart's scope)
303
+ //------------------------------------------------------------
304
+
305
+ lines.dispatch.on('elementMouseover.tooltip', function(e) {
306
+ e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
307
+ dispatch.tooltipShow(e);
308
+ });
309
+
310
+ lines.dispatch.on('elementMouseout.tooltip', function(e) {
311
+ dispatch.tooltipHide(e);
312
+ });
313
+
314
+ bars.dispatch.on('elementMouseover.tooltip', function(e) {
315
+ e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
316
+ dispatch.tooltipShow(e);
317
+ });
318
+
319
+ bars.dispatch.on('elementMouseout.tooltip', function(e) {
320
+ dispatch.tooltipHide(e);
321
+ });
322
+
323
+ dispatch.on('tooltipHide', function() {
324
+ if (tooltips) nv.tooltip.cleanup();
325
+ });
326
+
327
+ //============================================================
328
+
329
+
330
+ //============================================================
331
+ // Expose Public Variables
332
+ //------------------------------------------------------------
333
+
334
+ // expose chart's sub-components
335
+ chart.dispatch = dispatch;
336
+ chart.legend = legend;
337
+ chart.lines = lines;
338
+ chart.bars = bars;
339
+ chart.xAxis = xAxis;
340
+ chart.y1Axis = y1Axis;
341
+ chart.y2Axis = y2Axis;
342
+
343
+ d3.rebind(chart, lines, 'defined', 'size', 'clipVoronoi', 'interpolate');
344
+ //TODO: consider rebinding x, y and some other stuff, and simply do soemthign lile bars.x(lines.x()), etc.
345
+ //d3.rebind(chart, lines, 'x', 'y', 'size', 'xDomain', 'yDomain', 'xRange', 'yRange', 'forceX', 'forceY', 'interactive', 'clipEdge', 'clipVoronoi', 'id');
346
+
347
+ chart.options = nv.utils.optionsFunc.bind(chart);
348
+
349
+ chart.x = function(_) {
350
+ if (!arguments.length) return getX;
351
+ getX = _;
352
+ lines.x(_);
353
+ bars.x(_);
354
+ return chart;
355
+ };
356
+
357
+ chart.y = function(_) {
358
+ if (!arguments.length) return getY;
359
+ getY = _;
360
+ lines.y(_);
361
+ bars.y(_);
362
+ return chart;
363
+ };
364
+
365
+ chart.margin = function(_) {
366
+ if (!arguments.length) return margin;
367
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
368
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
369
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
370
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
371
+ return chart;
372
+ };
373
+
374
+ chart.width = function(_) {
375
+ if (!arguments.length) return width;
376
+ width = _;
377
+ return chart;
378
+ };
379
+
380
+ chart.height = function(_) {
381
+ if (!arguments.length) return height;
382
+ height = _;
383
+ return chart;
384
+ };
385
+
386
+ chart.color = function(_) {
387
+ if (!arguments.length) return color;
388
+ color = nv.utils.getColor(_);
389
+ legend.color(color);
390
+ return chart;
391
+ };
392
+
393
+ chart.showLegend = function(_) {
394
+ if (!arguments.length) return showLegend;
395
+ showLegend = _;
396
+ return chart;
397
+ };
398
+
399
+ chart.tooltips = function(_) {
400
+ if (!arguments.length) return tooltips;
401
+ tooltips = _;
402
+ return chart;
403
+ };
404
+
405
+ chart.tooltipContent = function(_) {
406
+ if (!arguments.length) return tooltip;
407
+ tooltip = _;
408
+ return chart;
409
+ };
410
+
411
+ chart.state = function(_) {
412
+ if (!arguments.length) return state;
413
+ state = _;
414
+ return chart;
415
+ };
416
+
417
+ chart.defaultState = function(_) {
418
+ if (!arguments.length) return defaultState;
419
+ defaultState = _;
420
+ return chart;
421
+ };
422
+
423
+ chart.noData = function(_) {
424
+ if (!arguments.length) return noData;
425
+ noData = _;
426
+ return chart;
427
+ };
428
+
429
+ //============================================================
430
+
431
+
432
+ return chart;
433
+ }
@@ -0,0 +1,658 @@
1
+
2
+ nv.models.linePlusBarWithFocusChart = function() {
3
+ "use strict";
4
+ //============================================================
5
+ // Public Variables with Default Settings
6
+ //------------------------------------------------------------
7
+
8
+ var lines = nv.models.line()
9
+ , lines2 = nv.models.line()
10
+ , bars = nv.models.historicalBar()
11
+ , bars2 = nv.models.historicalBar()
12
+ , xAxis = nv.models.axis()
13
+ , x2Axis = nv.models.axis()
14
+ , y1Axis = nv.models.axis()
15
+ , y2Axis = nv.models.axis()
16
+ , y3Axis = nv.models.axis()
17
+ , y4Axis = nv.models.axis()
18
+ , legend = nv.models.legend()
19
+ , brush = d3.svg.brush()
20
+ ;
21
+
22
+ var margin = {top: 30, right: 30, bottom: 30, left: 60}
23
+ , margin2 = {top: 0, right: 30, bottom: 20, left: 60}
24
+ , width = null
25
+ , height = null
26
+ , height2 = 100
27
+ , getX = function(d) { return d.x }
28
+ , getY = function(d) { return d.y }
29
+ , color = nv.utils.defaultColor()
30
+ , showLegend = true
31
+ , extent
32
+ , brushExtent = null
33
+ , tooltips = true
34
+ , tooltip = function(key, x, y, e, graph) {
35
+ return '<h3>' + key + '</h3>' +
36
+ '<p>' + y + ' at ' + x + '</p>';
37
+ }
38
+ , x
39
+ , x2
40
+ , y1
41
+ , y2
42
+ , y3
43
+ , y4
44
+ , noData = "No Data Available."
45
+ , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'brush')
46
+ , transitionDuration = 0
47
+ ;
48
+
49
+ lines
50
+ .clipEdge(true)
51
+ ;
52
+ lines2
53
+ .interactive(false)
54
+ ;
55
+ xAxis
56
+ .orient('bottom')
57
+ .tickPadding(5)
58
+ ;
59
+ y1Axis
60
+ .orient('left')
61
+ ;
62
+ y2Axis
63
+ .orient('right')
64
+ ;
65
+ x2Axis
66
+ .orient('bottom')
67
+ .tickPadding(5)
68
+ ;
69
+ y3Axis
70
+ .orient('left')
71
+ ;
72
+ y4Axis
73
+ .orient('right')
74
+ ;
75
+
76
+ //============================================================
77
+
78
+
79
+ //============================================================
80
+ // Private Variables
81
+ //------------------------------------------------------------
82
+
83
+ var showTooltip = function(e, offsetElement) {
84
+ if (extent) {
85
+ e.pointIndex += Math.ceil(extent[0]);
86
+ }
87
+ var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
88
+ top = e.pos[1] + ( offsetElement.offsetTop || 0),
89
+ x = xAxis.tickFormat()(lines.x()(e.point, e.pointIndex)),
90
+ y = (e.series.bar ? y1Axis : y2Axis).tickFormat()(lines.y()(e.point, e.pointIndex)),
91
+ content = tooltip(e.series.key, x, y, e, chart);
92
+
93
+ nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's', null, offsetElement);
94
+ };
95
+
96
+ //------------------------------------------------------------
97
+
98
+
99
+
100
+ function chart(selection) {
101
+ selection.each(function(data) {
102
+ var container = d3.select(this),
103
+ that = this;
104
+
105
+ var availableWidth = (width || parseInt(container.style('width')) || 960)
106
+ - margin.left - margin.right,
107
+ availableHeight1 = (height || parseInt(container.style('height')) || 400)
108
+ - margin.top - margin.bottom - height2,
109
+ availableHeight2 = height2 - margin2.top - margin2.bottom;
110
+
111
+ chart.update = function() { container.transition().duration(transitionDuration).call(chart); };
112
+ chart.container = this;
113
+
114
+
115
+ //------------------------------------------------------------
116
+ // Display No Data message if there's nothing to show.
117
+
118
+ if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {
119
+ var noDataText = container.selectAll('.nv-noData').data([noData]);
120
+
121
+ noDataText.enter().append('text')
122
+ .attr('class', 'nvd3 nv-noData')
123
+ .attr('dy', '-.7em')
124
+ .style('text-anchor', 'middle');
125
+
126
+ noDataText
127
+ .attr('x', margin.left + availableWidth / 2)
128
+ .attr('y', margin.top + availableHeight1 / 2)
129
+ .text(function(d) { return d });
130
+
131
+ return chart;
132
+ } else {
133
+ container.selectAll('.nv-noData').remove();
134
+ }
135
+
136
+ //------------------------------------------------------------
137
+
138
+
139
+ //------------------------------------------------------------
140
+ // Setup Scales
141
+
142
+ var dataBars = data.filter(function(d) { return !d.disabled && d.bar });
143
+ var dataLines = data.filter(function(d) { return !d.bar }); // removed the !d.disabled clause here to fix Issue #240
144
+
145
+ x = bars.xScale();
146
+ x2 = x2Axis.scale();
147
+ y1 = bars.yScale();
148
+ y2 = lines.yScale();
149
+ y3 = bars2.yScale();
150
+ y4 = lines2.yScale();
151
+
152
+ var series1 = data
153
+ .filter(function(d) { return !d.disabled && d.bar })
154
+ .map(function(d) {
155
+ return d.values.map(function(d,i) {
156
+ return { x: getX(d,i), y: getY(d,i) }
157
+ })
158
+ });
159
+
160
+ var series2 = data
161
+ .filter(function(d) { return !d.disabled && !d.bar })
162
+ .map(function(d) {
163
+ return d.values.map(function(d,i) {
164
+ return { x: getX(d,i), y: getY(d,i) }
165
+ })
166
+ });
167
+
168
+ x .range([0, availableWidth]);
169
+
170
+ x2 .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x } ))
171
+ .range([0, availableWidth]);
172
+
173
+
174
+ //------------------------------------------------------------
175
+
176
+
177
+ //------------------------------------------------------------
178
+ // Setup containers and skeleton of chart
179
+
180
+ var wrap = container.selectAll('g.nv-wrap.nv-linePlusBar').data([data]);
181
+ var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-linePlusBar').append('g');
182
+ var g = wrap.select('g');
183
+
184
+ gEnter.append('g').attr('class', 'nv-legendWrap');
185
+
186
+ var focusEnter = gEnter.append('g').attr('class', 'nv-focus');
187
+ focusEnter.append('g').attr('class', 'nv-x nv-axis');
188
+ focusEnter.append('g').attr('class', 'nv-y1 nv-axis');
189
+ focusEnter.append('g').attr('class', 'nv-y2 nv-axis');
190
+ focusEnter.append('g').attr('class', 'nv-barsWrap');
191
+ focusEnter.append('g').attr('class', 'nv-linesWrap');
192
+
193
+ var contextEnter = gEnter.append('g').attr('class', 'nv-context');
194
+ contextEnter.append('g').attr('class', 'nv-x nv-axis');
195
+ contextEnter.append('g').attr('class', 'nv-y1 nv-axis');
196
+ contextEnter.append('g').attr('class', 'nv-y2 nv-axis');
197
+ contextEnter.append('g').attr('class', 'nv-barsWrap');
198
+ contextEnter.append('g').attr('class', 'nv-linesWrap');
199
+ contextEnter.append('g').attr('class', 'nv-brushBackground');
200
+ contextEnter.append('g').attr('class', 'nv-x nv-brush');
201
+
202
+
203
+ //------------------------------------------------------------
204
+
205
+
206
+ //------------------------------------------------------------
207
+ // Legend
208
+
209
+ if (showLegend) {
210
+ legend.width( availableWidth / 2 );
211
+
212
+ g.select('.nv-legendWrap')
213
+ .datum(data.map(function(series) {
214
+ series.originalKey = series.originalKey === undefined ? series.key : series.originalKey;
215
+ series.key = series.originalKey + (series.bar ? ' (left axis)' : ' (right axis)');
216
+ return series;
217
+ }))
218
+ .call(legend);
219
+
220
+ if ( margin.top != legend.height()) {
221
+ margin.top = legend.height();
222
+ availableHeight1 = (height || parseInt(container.style('height')) || 400)
223
+ - margin.top - margin.bottom - height2;
224
+ }
225
+
226
+ g.select('.nv-legendWrap')
227
+ .attr('transform', 'translate(' + ( availableWidth / 2 ) + ',' + (-margin.top) +')');
228
+ }
229
+
230
+ //------------------------------------------------------------
231
+
232
+
233
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
234
+
235
+
236
+ //------------------------------------------------------------
237
+ // Context Components
238
+
239
+ bars2
240
+ .width(availableWidth)
241
+ .height(availableHeight2)
242
+ .color(data.map(function(d,i) {
243
+ return d.color || color(d, i);
244
+ }).filter(function(d,i) { return !data[i].disabled && data[i].bar }));
245
+
246
+ lines2
247
+ .width(availableWidth)
248
+ .height(availableHeight2)
249
+ .color(data.map(function(d,i) {
250
+ return d.color || color(d, i);
251
+ }).filter(function(d,i) { return !data[i].disabled && !data[i].bar }));
252
+
253
+ var bars2Wrap = g.select('.nv-context .nv-barsWrap')
254
+ .datum(dataBars.length ? dataBars : [{values:[]}]);
255
+
256
+ var lines2Wrap = g.select('.nv-context .nv-linesWrap')
257
+ .datum(!dataLines[0].disabled ? dataLines : [{values:[]}]);
258
+
259
+ g.select('.nv-context')
260
+ .attr('transform', 'translate(0,' + ( availableHeight1 + margin.bottom + margin2.top) + ')')
261
+
262
+ bars2Wrap.transition().call(bars2);
263
+ lines2Wrap.transition().call(lines2);
264
+
265
+ //------------------------------------------------------------
266
+
267
+
268
+
269
+ //------------------------------------------------------------
270
+ // Setup Brush
271
+
272
+ brush
273
+ .x(x2)
274
+ .on('brush', onBrush);
275
+
276
+ if (brushExtent) brush.extent(brushExtent);
277
+
278
+ var brushBG = g.select('.nv-brushBackground').selectAll('g')
279
+ .data([brushExtent || brush.extent()])
280
+
281
+ var brushBGenter = brushBG.enter()
282
+ .append('g');
283
+
284
+ brushBGenter.append('rect')
285
+ .attr('class', 'left')
286
+ .attr('x', 0)
287
+ .attr('y', 0)
288
+ .attr('height', availableHeight2);
289
+
290
+ brushBGenter.append('rect')
291
+ .attr('class', 'right')
292
+ .attr('x', 0)
293
+ .attr('y', 0)
294
+ .attr('height', availableHeight2);
295
+
296
+ var gBrush = g.select('.nv-x.nv-brush')
297
+ .call(brush);
298
+ gBrush.selectAll('rect')
299
+ //.attr('y', -5)
300
+ .attr('height', availableHeight2);
301
+ gBrush.selectAll('.resize').append('path').attr('d', resizePath);
302
+
303
+ //------------------------------------------------------------
304
+
305
+ //------------------------------------------------------------
306
+ // Setup Secondary (Context) Axes
307
+
308
+ x2Axis
309
+ .ticks( availableWidth / 100 )
310
+ .tickSize(-availableHeight2, 0);
311
+
312
+ g.select('.nv-context .nv-x.nv-axis')
313
+ .attr('transform', 'translate(0,' + y3.range()[0] + ')');
314
+ g.select('.nv-context .nv-x.nv-axis').transition()
315
+ .call(x2Axis);
316
+
317
+
318
+ y3Axis
319
+ .scale(y3)
320
+ .ticks( availableHeight2 / 36 )
321
+ .tickSize( -availableWidth, 0);
322
+
323
+ g.select('.nv-context .nv-y1.nv-axis')
324
+ .style('opacity', dataBars.length ? 1 : 0)
325
+ .attr('transform', 'translate(0,' + x2.range()[0] + ')');
326
+
327
+ g.select('.nv-context .nv-y1.nv-axis').transition()
328
+ .call(y3Axis);
329
+
330
+
331
+ y4Axis
332
+ .scale(y4)
333
+ .ticks( availableHeight2 / 36 )
334
+ .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if y1 has none
335
+
336
+ g.select('.nv-context .nv-y2.nv-axis')
337
+ .style('opacity', dataLines.length ? 1 : 0)
338
+ .attr('transform', 'translate(' + x2.range()[1] + ',0)');
339
+
340
+ g.select('.nv-context .nv-y2.nv-axis').transition()
341
+ .call(y4Axis);
342
+
343
+ //------------------------------------------------------------
344
+
345
+ //============================================================
346
+ // Event Handling/Dispatching (in chart's scope)
347
+ //------------------------------------------------------------
348
+
349
+ legend.dispatch.on('stateChange', function(newState) {
350
+ chart.update();
351
+ });
352
+
353
+ dispatch.on('tooltipShow', function(e) {
354
+ if (tooltips) showTooltip(e, that.parentNode);
355
+ });
356
+
357
+ //============================================================
358
+
359
+
360
+ //============================================================
361
+ // Functions
362
+ //------------------------------------------------------------
363
+
364
+ // Taken from crossfilter (http://square.github.com/crossfilter/)
365
+ function resizePath(d) {
366
+ var e = +(d == 'e'),
367
+ x = e ? 1 : -1,
368
+ y = availableHeight2 / 3;
369
+ return 'M' + (.5 * x) + ',' + y
370
+ + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6)
371
+ + 'V' + (2 * y - 6)
372
+ + 'A6,6 0 0 ' + e + ' ' + (.5 * x) + ',' + (2 * y)
373
+ + 'Z'
374
+ + 'M' + (2.5 * x) + ',' + (y + 8)
375
+ + 'V' + (2 * y - 8)
376
+ + 'M' + (4.5 * x) + ',' + (y + 8)
377
+ + 'V' + (2 * y - 8);
378
+ }
379
+
380
+
381
+ function updateBrushBG() {
382
+ if (!brush.empty()) brush.extent(brushExtent);
383
+ brushBG
384
+ .data([brush.empty() ? x2.domain() : brushExtent])
385
+ .each(function(d,i) {
386
+ var leftWidth = x2(d[0]) - x2.range()[0],
387
+ rightWidth = x2.range()[1] - x2(d[1]);
388
+ d3.select(this).select('.left')
389
+ .attr('width', leftWidth < 0 ? 0 : leftWidth);
390
+
391
+ d3.select(this).select('.right')
392
+ .attr('x', x2(d[1]))
393
+ .attr('width', rightWidth < 0 ? 0 : rightWidth);
394
+ });
395
+ }
396
+
397
+
398
+ function onBrush() {
399
+ brushExtent = brush.empty() ? null : brush.extent();
400
+ extent = brush.empty() ? x2.domain() : brush.extent();
401
+
402
+
403
+ dispatch.brush({extent: extent, brush: brush});
404
+
405
+ updateBrushBG();
406
+
407
+
408
+ //------------------------------------------------------------
409
+ // Prepare Main (Focus) Bars and Lines
410
+
411
+ bars
412
+ .width(availableWidth)
413
+ .height(availableHeight1)
414
+ .color(data.map(function(d,i) {
415
+ return d.color || color(d, i);
416
+ }).filter(function(d,i) { return !data[i].disabled && data[i].bar }));
417
+
418
+
419
+ lines
420
+ .width(availableWidth)
421
+ .height(availableHeight1)
422
+ .color(data.map(function(d,i) {
423
+ return d.color || color(d, i);
424
+ }).filter(function(d,i) { return !data[i].disabled && !data[i].bar }));
425
+
426
+ var focusBarsWrap = g.select('.nv-focus .nv-barsWrap')
427
+ .datum(!dataBars.length ? [{values:[]}] :
428
+ dataBars
429
+ .map(function(d,i) {
430
+ return {
431
+ key: d.key,
432
+ values: d.values.filter(function(d,i) {
433
+ return bars.x()(d,i) >= extent[0] && bars.x()(d,i) <= extent[1];
434
+ })
435
+ }
436
+ })
437
+ );
438
+
439
+ var focusLinesWrap = g.select('.nv-focus .nv-linesWrap')
440
+ .datum(dataLines[0].disabled ? [{values:[]}] :
441
+ dataLines
442
+ .map(function(d,i) {
443
+ return {
444
+ key: d.key,
445
+ values: d.values.filter(function(d,i) {
446
+ return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1];
447
+ })
448
+ }
449
+ })
450
+ );
451
+
452
+ //------------------------------------------------------------
453
+
454
+
455
+ //------------------------------------------------------------
456
+ // Update Main (Focus) X Axis
457
+
458
+ if (dataBars.length) {
459
+ x = bars.xScale();
460
+ } else {
461
+ x = lines.xScale();
462
+ }
463
+
464
+ xAxis
465
+ .scale(x)
466
+ .ticks( availableWidth / 100 )
467
+ .tickSize(-availableHeight1, 0);
468
+
469
+ xAxis.domain([Math.ceil(extent[0]), Math.floor(extent[1])]);
470
+
471
+ g.select('.nv-x.nv-axis').transition().duration(transitionDuration)
472
+ .call(xAxis);
473
+ //------------------------------------------------------------
474
+
475
+
476
+ //------------------------------------------------------------
477
+ // Update Main (Focus) Bars and Lines
478
+
479
+ focusBarsWrap.transition().duration(transitionDuration).call(bars);
480
+ focusLinesWrap.transition().duration(transitionDuration).call(lines);
481
+
482
+ //------------------------------------------------------------
483
+
484
+
485
+ //------------------------------------------------------------
486
+ // Setup and Update Main (Focus) Y Axes
487
+
488
+ g.select('.nv-focus .nv-x.nv-axis')
489
+ .attr('transform', 'translate(0,' + y1.range()[0] + ')');
490
+
491
+
492
+ y1Axis
493
+ .scale(y1)
494
+ .ticks( availableHeight1 / 36 )
495
+ .tickSize(-availableWidth, 0);
496
+
497
+ g.select('.nv-focus .nv-y1.nv-axis')
498
+ .style('opacity', dataBars.length ? 1 : 0);
499
+
500
+
501
+ y2Axis
502
+ .scale(y2)
503
+ .ticks( availableHeight1 / 36 )
504
+ .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if y1 has none
505
+
506
+ g.select('.nv-focus .nv-y2.nv-axis')
507
+ .style('opacity', dataLines.length ? 1 : 0)
508
+ .attr('transform', 'translate(' + x.range()[1] + ',0)');
509
+
510
+ g.select('.nv-focus .nv-y1.nv-axis').transition().duration(transitionDuration)
511
+ .call(y1Axis);
512
+ g.select('.nv-focus .nv-y2.nv-axis').transition().duration(transitionDuration)
513
+ .call(y2Axis);
514
+ }
515
+
516
+ //============================================================
517
+
518
+ onBrush();
519
+
520
+ });
521
+
522
+ return chart;
523
+ }
524
+
525
+
526
+ //============================================================
527
+ // Event Handling/Dispatching (out of chart's scope)
528
+ //------------------------------------------------------------
529
+
530
+ lines.dispatch.on('elementMouseover.tooltip', function(e) {
531
+ e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
532
+ dispatch.tooltipShow(e);
533
+ });
534
+
535
+ lines.dispatch.on('elementMouseout.tooltip', function(e) {
536
+ dispatch.tooltipHide(e);
537
+ });
538
+
539
+ bars.dispatch.on('elementMouseover.tooltip', function(e) {
540
+ e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
541
+ dispatch.tooltipShow(e);
542
+ });
543
+
544
+ bars.dispatch.on('elementMouseout.tooltip', function(e) {
545
+ dispatch.tooltipHide(e);
546
+ });
547
+
548
+ dispatch.on('tooltipHide', function() {
549
+ if (tooltips) nv.tooltip.cleanup();
550
+ });
551
+
552
+ //============================================================
553
+
554
+
555
+ //============================================================
556
+ // Expose Public Variables
557
+ //------------------------------------------------------------
558
+
559
+ // expose chart's sub-components
560
+ chart.dispatch = dispatch;
561
+ chart.legend = legend;
562
+ chart.lines = lines;
563
+ chart.lines2 = lines2;
564
+ chart.bars = bars;
565
+ chart.bars2 = bars2;
566
+ chart.xAxis = xAxis;
567
+ chart.x2Axis = x2Axis;
568
+ chart.y1Axis = y1Axis;
569
+ chart.y2Axis = y2Axis;
570
+ chart.y3Axis = y3Axis;
571
+ chart.y4Axis = y4Axis;
572
+
573
+ d3.rebind(chart, lines, 'defined', 'size', 'clipVoronoi', 'interpolate');
574
+ //TODO: consider rebinding x, y and some other stuff, and simply do soemthign lile bars.x(lines.x()), etc.
575
+ //d3.rebind(chart, lines, 'x', 'y', 'size', 'xDomain', 'yDomain', 'xRange', 'yRange', 'forceX', 'forceY', 'interactive', 'clipEdge', 'clipVoronoi', 'id');
576
+
577
+ chart.options = nv.utils.optionsFunc.bind(chart);
578
+
579
+ chart.x = function(_) {
580
+ if (!arguments.length) return getX;
581
+ getX = _;
582
+ lines.x(_);
583
+ bars.x(_);
584
+ return chart;
585
+ };
586
+
587
+ chart.y = function(_) {
588
+ if (!arguments.length) return getY;
589
+ getY = _;
590
+ lines.y(_);
591
+ bars.y(_);
592
+ return chart;
593
+ };
594
+
595
+ chart.margin = function(_) {
596
+ if (!arguments.length) return margin;
597
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
598
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
599
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
600
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
601
+ return chart;
602
+ };
603
+
604
+ chart.width = function(_) {
605
+ if (!arguments.length) return width;
606
+ width = _;
607
+ return chart;
608
+ };
609
+
610
+ chart.height = function(_) {
611
+ if (!arguments.length) return height;
612
+ height = _;
613
+ return chart;
614
+ };
615
+
616
+ chart.color = function(_) {
617
+ if (!arguments.length) return color;
618
+ color = nv.utils.getColor(_);
619
+ legend.color(color);
620
+ return chart;
621
+ };
622
+
623
+ chart.showLegend = function(_) {
624
+ if (!arguments.length) return showLegend;
625
+ showLegend = _;
626
+ return chart;
627
+ };
628
+
629
+ chart.tooltips = function(_) {
630
+ if (!arguments.length) return tooltips;
631
+ tooltips = _;
632
+ return chart;
633
+ };
634
+
635
+ chart.tooltipContent = function(_) {
636
+ if (!arguments.length) return tooltip;
637
+ tooltip = _;
638
+ return chart;
639
+ };
640
+
641
+ chart.noData = function(_) {
642
+ if (!arguments.length) return noData;
643
+ noData = _;
644
+ return chart;
645
+ };
646
+
647
+ chart.brushExtent = function(_) {
648
+ if (!arguments.length) return brushExtent;
649
+ brushExtent = _;
650
+ return chart;
651
+ };
652
+
653
+
654
+ //============================================================
655
+
656
+
657
+ return chart;
658
+ }