chartx 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/.gitignore +17 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +145 -0
  6. data/Rakefile +1 -0
  7. data/chartx.gemspec +40 -0
  8. data/lib/chartx/engine.rb +11 -0
  9. data/lib/chartx/helper.rb +184 -0
  10. data/lib/chartx/version.rb +3 -0
  11. data/lib/chartx.rb +3 -0
  12. data/screenshots/barchart.png +0 -0
  13. data/screenshots/bulletchart.png +0 -0
  14. data/screenshots/horizontalbarchart.png +0 -0
  15. data/screenshots/linechart.png +0 -0
  16. data/screenshots/linewithfocuschart.png +0 -0
  17. data/screenshots/multibarchart2.png +0 -0
  18. data/screenshots/piechart.png +0 -0
  19. data/screenshots/scatterchart.png +0 -0
  20. data/screenshots/stackedareachart.png +0 -0
  21. data/screenshots/stackedareachart3.png +0 -0
  22. data/vendor/assets/javascripts/chartx-core.js +9 -0
  23. data/vendor/assets/javascripts/chartx-models.js +2 -0
  24. data/vendor/assets/javascripts/nvd3/.gitignore +27 -0
  25. data/vendor/assets/javascripts/nvd3/.jshintrc +3 -0
  26. data/vendor/assets/javascripts/nvd3/LICENSE.md +49 -0
  27. data/vendor/assets/javascripts/nvd3/README.md +1 -0
  28. data/vendor/assets/javascripts/nvd3/lib/cie.js +155 -0
  29. data/vendor/assets/javascripts/nvd3/lib/crossfilter.js +1180 -0
  30. data/vendor/assets/javascripts/nvd3/lib/crossfilter.min.js +1 -0
  31. data/vendor/assets/javascripts/nvd3/lib/d3.js +8798 -0
  32. data/vendor/assets/javascripts/nvd3/lib/d3.min.js +5 -0
  33. data/vendor/assets/javascripts/nvd3/lib/fisheye.js +86 -0
  34. data/vendor/assets/javascripts/nvd3/lib/hive.js +80 -0
  35. data/vendor/assets/javascripts/nvd3/lib/horizon.js +192 -0
  36. data/vendor/assets/javascripts/nvd3/lib/sankey.js +292 -0
  37. data/vendor/assets/javascripts/nvd3/nv.d3.js +13048 -0
  38. data/vendor/assets/javascripts/nvd3/nv.d3.min.js +6 -0
  39. data/vendor/assets/javascripts/nvd3/src/core.js +118 -0
  40. data/vendor/assets/javascripts/nvd3/src/intro.js +1 -0
  41. data/vendor/assets/javascripts/nvd3/src/models/axis.js +398 -0
  42. data/vendor/assets/javascripts/nvd3/src/models/boilerplate.js +102 -0
  43. data/vendor/assets/javascripts/nvd3/src/models/bullet.js +377 -0
  44. data/vendor/assets/javascripts/nvd3/src/models/bulletChart.js +341 -0
  45. data/vendor/assets/javascripts/nvd3/src/models/cumulativeLineChart.js +685 -0
  46. data/vendor/assets/javascripts/nvd3/src/models/discreteBar.js +327 -0
  47. data/vendor/assets/javascripts/nvd3/src/models/discreteBarChart.js +290 -0
  48. data/vendor/assets/javascripts/nvd3/src/models/distribution.js +146 -0
  49. data/vendor/assets/javascripts/nvd3/src/models/historicalBar.js +289 -0
  50. data/vendor/assets/javascripts/nvd3/src/models/historicalBarChart.js +421 -0
  51. data/vendor/assets/javascripts/nvd3/src/models/indentedTree.js +317 -0
  52. data/vendor/assets/javascripts/nvd3/src/models/legend.js +207 -0
  53. data/vendor/assets/javascripts/nvd3/src/models/line.js +284 -0
  54. data/vendor/assets/javascripts/nvd3/src/models/lineChart.js +421 -0
  55. data/vendor/assets/javascripts/nvd3/src/models/linePlusBarChart.js +455 -0
  56. data/vendor/assets/javascripts/nvd3/src/models/linePlusBarWithFocusChart.js +665 -0
  57. data/vendor/assets/javascripts/nvd3/src/models/lineWithFisheye.js +197 -0
  58. data/vendor/assets/javascripts/nvd3/src/models/lineWithFisheyeChart.js +319 -0
  59. data/vendor/assets/javascripts/nvd3/src/models/lineWithFocusChart.js +560 -0
  60. data/vendor/assets/javascripts/nvd3/src/models/multiBar.js +442 -0
  61. data/vendor/assets/javascripts/nvd3/src/models/multiBarChart.js +506 -0
  62. data/vendor/assets/javascripts/nvd3/src/models/multiBarHorizontal.js +420 -0
  63. data/vendor/assets/javascripts/nvd3/src/models/multiBarHorizontalChart.js +448 -0
  64. data/vendor/assets/javascripts/nvd3/src/models/multiBarTimeSeries.js +371 -0
  65. data/vendor/assets/javascripts/nvd3/src/models/multiBarTimeSeriesChart.js +403 -0
  66. data/vendor/assets/javascripts/nvd3/src/models/multiChart.js +444 -0
  67. data/vendor/assets/javascripts/nvd3/src/models/ohlcBar.js +365 -0
  68. data/vendor/assets/javascripts/nvd3/src/models/parallelCoordinates.js +238 -0
  69. data/vendor/assets/javascripts/nvd3/src/models/pie.js +386 -0
  70. data/vendor/assets/javascripts/nvd3/src/models/pieChart.js +302 -0
  71. data/vendor/assets/javascripts/nvd3/src/models/scatter.js +660 -0
  72. data/vendor/assets/javascripts/nvd3/src/models/scatterChart.js +614 -0
  73. data/vendor/assets/javascripts/nvd3/src/models/scatterPlusLineChart.js +610 -0
  74. data/vendor/assets/javascripts/nvd3/src/models/sparkline.js +179 -0
  75. data/vendor/assets/javascripts/nvd3/src/models/sparklinePlus.js +293 -0
  76. data/vendor/assets/javascripts/nvd3/src/models/stackedArea.js +336 -0
  77. data/vendor/assets/javascripts/nvd3/src/models/stackedAreaChart.js +490 -0
  78. data/vendor/assets/javascripts/nvd3/src/nv.d3.css +704 -0
  79. data/vendor/assets/javascripts/nvd3/src/outro.js +1 -0
  80. data/vendor/assets/javascripts/nvd3/src/tooltip.js +133 -0
  81. data/vendor/assets/javascripts/nvd3/src/utils.js +118 -0
  82. data/vendor/assets/javascripts/set-env.js.erb +1 -0
  83. data/vendor/assets/stylesheets/chartx.css +3 -0
  84. metadata +189 -0
@@ -0,0 +1,490 @@
1
+
2
+ nv.models.stackedAreaChart = function() {
3
+
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
+ ;
14
+
15
+ var margin = {top: 30, right: 25, bottom: 50, left: 60}
16
+ , width = null
17
+ , height = null
18
+ , color = nv.utils.defaultColor() // a function that takes in d, i and returns color
19
+ , showControls = true
20
+ , showLegend = true
21
+ , tooltips = true
22
+ , tooltip = function(key, x, y, e, graph) {
23
+ return '<h3>' + key + '</h3>' +
24
+ '<p>' + y + ' on ' + x + '</p>'
25
+ }
26
+ , x //can be accessed via chart.xScale()
27
+ , y //can be accessed via chart.yScale()
28
+ , yAxisTickFormat = d3.format(',.2f')
29
+ , state = { style: stacked.style() }
30
+ , defaultState = null
31
+ , noData = 'No Data Available.'
32
+ , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState')
33
+ , controlWidth = 250
34
+ ;
35
+
36
+ xAxis
37
+ .orient('bottom')
38
+ .tickPadding(7)
39
+ ;
40
+ yAxis
41
+ .orient('left')
42
+ ;
43
+ stacked.scatter
44
+ .pointActive(function(d) {
45
+ //console.log(stacked.y()(d), !!Math.round(stacked.y()(d) * 100));
46
+ return !!Math.round(stacked.y()(d) * 100);
47
+ })
48
+ ;
49
+
50
+ //============================================================
51
+
52
+
53
+ //============================================================
54
+ // Private Variables
55
+ //------------------------------------------------------------
56
+
57
+ var showTooltip = function(e, offsetElement) {
58
+ var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
59
+ top = e.pos[1] + ( offsetElement.offsetTop || 0),
60
+ x = xAxis.tickFormat()(stacked.x()(e.point, e.pointIndex)),
61
+ y = yAxis.tickFormat()(stacked.y()(e.point, e.pointIndex)),
62
+ content = tooltip(e.series.key, x, y, e, chart);
63
+
64
+ nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's', null, offsetElement);
65
+ };
66
+
67
+ //============================================================
68
+
69
+
70
+ function chart(selection) {
71
+ selection.each(function(data) {
72
+ var container = d3.select(this),
73
+ that = this;
74
+
75
+ var availableWidth = (width || parseInt(container.style('width')) || 960)
76
+ - margin.left - margin.right,
77
+ availableHeight = (height || parseInt(container.style('height')) || 400)
78
+ - margin.top - margin.bottom;
79
+
80
+ chart.update = function() { container.transition().call(chart); };
81
+ chart.container = this;
82
+
83
+ //set state.disabled
84
+ state.disabled = data.map(function(d) { return !!d.disabled });
85
+
86
+ if (!defaultState) {
87
+ var key;
88
+ defaultState = {};
89
+ for (key in state) {
90
+ if (state[key] instanceof Array)
91
+ defaultState[key] = state[key].slice(0);
92
+ else
93
+ defaultState[key] = state[key];
94
+ }
95
+ }
96
+
97
+ //------------------------------------------------------------
98
+ // Display No Data message if there's nothing to show.
99
+
100
+ if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {
101
+ var noDataText = container.selectAll('.nv-noData').data([noData]);
102
+
103
+ noDataText.enter().append('text')
104
+ .attr('class', 'nvd3 nv-noData')
105
+ .attr('dy', '-.7em')
106
+ .style('text-anchor', 'middle');
107
+
108
+ noDataText
109
+ .attr('x', margin.left + availableWidth / 2)
110
+ .attr('y', margin.top + availableHeight / 2)
111
+ .text(function(d) { return d });
112
+
113
+ return chart;
114
+ } else {
115
+ container.selectAll('.nv-noData').remove();
116
+ }
117
+
118
+ //------------------------------------------------------------
119
+
120
+
121
+ //------------------------------------------------------------
122
+ // Setup Scales
123
+
124
+ x = stacked.xScale();
125
+ y = stacked.yScale();
126
+
127
+ //------------------------------------------------------------
128
+
129
+
130
+ //------------------------------------------------------------
131
+ // Setup containers and skeleton of chart
132
+
133
+ var wrap = container.selectAll('g.nv-wrap.nv-stackedAreaChart').data([data]);
134
+ var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-stackedAreaChart').append('g');
135
+ var g = wrap.select('g');
136
+
137
+ gEnter.append('g').attr('class', 'nv-x nv-axis');
138
+ gEnter.append('g').attr('class', 'nv-y nv-axis');
139
+ gEnter.append('g').attr('class', 'nv-stackedWrap');
140
+ gEnter.append('g').attr('class', 'nv-legendWrap');
141
+ gEnter.append('g').attr('class', 'nv-controlsWrap');
142
+
143
+ //------------------------------------------------------------
144
+
145
+
146
+ //------------------------------------------------------------
147
+ // Legend
148
+
149
+ if (showLegend) {
150
+ legend
151
+ .width( availableWidth - controlWidth );
152
+
153
+ g.select('.nv-legendWrap')
154
+ .datum(data)
155
+ .call(legend);
156
+
157
+ if ( margin.top != legend.height()) {
158
+ margin.top = legend.height();
159
+ availableHeight = (height || parseInt(container.style('height')) || 400)
160
+ - margin.top - margin.bottom;
161
+ }
162
+
163
+ g.select('.nv-legendWrap')
164
+ .attr('transform', 'translate(' + controlWidth + ',' + (-margin.top) +')');
165
+ }
166
+
167
+ //------------------------------------------------------------
168
+
169
+
170
+ //------------------------------------------------------------
171
+ // Controls
172
+
173
+ if (showControls) {
174
+ var controlsData = [
175
+ { key: 'Stacked', disabled: stacked.offset() != 'zero' },
176
+ { key: 'Stream', disabled: stacked.offset() != 'wiggle' },
177
+ { key: 'Expanded', disabled: stacked.offset() != 'expand' }
178
+ ];
179
+
180
+ controls
181
+ .width( controlWidth )
182
+ .color(['#444', '#444', '#444']);
183
+
184
+ g.select('.nv-controlsWrap')
185
+ .datum(controlsData)
186
+ .call(controls);
187
+
188
+
189
+ if ( margin.top != Math.max(controls.height(), legend.height()) ) {
190
+ margin.top = Math.max(controls.height(), legend.height());
191
+ availableHeight = (height || parseInt(container.style('height')) || 400)
192
+ - margin.top - margin.bottom;
193
+ }
194
+
195
+
196
+ g.select('.nv-controlsWrap')
197
+ .attr('transform', 'translate(0,' + (-margin.top) +')');
198
+ }
199
+
200
+ //------------------------------------------------------------
201
+
202
+
203
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
204
+
205
+
206
+ //------------------------------------------------------------
207
+ // Main Chart Component(s)
208
+
209
+ stacked
210
+ .width(availableWidth)
211
+ .height(availableHeight)
212
+
213
+ var stackedWrap = g.select('.nv-stackedWrap')
214
+ .datum(data);
215
+ //d3.transition(stackedWrap).call(stacked);
216
+ stackedWrap.call(stacked);
217
+
218
+ //------------------------------------------------------------
219
+
220
+
221
+ //------------------------------------------------------------
222
+ // Setup Axes
223
+
224
+ xAxis
225
+ .scale(x)
226
+ .ticks( availableWidth / 100 )
227
+ .tickSize( -availableHeight, 0);
228
+
229
+ g.select('.nv-x.nv-axis')
230
+ .attr('transform', 'translate(0,' + availableHeight + ')');
231
+ //d3.transition(g.select('.nv-x.nv-axis'))
232
+ g.select('.nv-x.nv-axis')
233
+ .transition().duration(0)
234
+ .call(xAxis);
235
+
236
+ yAxis
237
+ .scale(y)
238
+ .ticks(stacked.offset() == 'wiggle' ? 0 : availableHeight / 36)
239
+ .tickSize(-availableWidth, 0)
240
+ .setTickFormat(stacked.offset() == 'expand' ? d3.format('%') : yAxisTickFormat);
241
+
242
+ //d3.transition(g.select('.nv-y.nv-axis'))
243
+ g.select('.nv-y.nv-axis')
244
+ .transition().duration(0)
245
+ .call(yAxis);
246
+
247
+ //------------------------------------------------------------
248
+
249
+
250
+ //============================================================
251
+ // Event Handling/Dispatching (in chart's scope)
252
+ //------------------------------------------------------------
253
+
254
+ stacked.dispatch.on('areaClick.toggle', function(e) {
255
+ if (data.filter(function(d) { return !d.disabled }).length === 1)
256
+ data = data.map(function(d) {
257
+ d.disabled = false;
258
+ return d
259
+ });
260
+ else
261
+ data = data.map(function(d,i) {
262
+ d.disabled = (i != e.seriesIndex);
263
+ return d
264
+ });
265
+
266
+ state.disabled = data.map(function(d) { return !!d.disabled });
267
+ dispatch.stateChange(state);
268
+
269
+ //selection.transition().call(chart);
270
+ chart.update();
271
+ });
272
+
273
+ legend.dispatch.on('legendClick', function(d,i) {
274
+ d.disabled = !d.disabled;
275
+
276
+ if (!data.filter(function(d) { return !d.disabled }).length) {
277
+ data.map(function(d) {
278
+ d.disabled = false;
279
+ return d;
280
+ });
281
+ }
282
+
283
+ state.disabled = data.map(function(d) { return !!d.disabled });
284
+ dispatch.stateChange(state);
285
+
286
+ //selection.transition().call(chart);
287
+ chart.update();
288
+ });
289
+
290
+ legend.dispatch.on('legendDblclick', function(d) {
291
+ //Double clicking should always enable current series, and disabled all others.
292
+ data.forEach(function(d) {
293
+ d.disabled = true;
294
+ });
295
+ d.disabled = false;
296
+
297
+ state.disabled = data.map(function(d) { return !!d.disabled });
298
+ dispatch.stateChange(state);
299
+ chart.update();
300
+ });
301
+
302
+ controls.dispatch.on('legendClick', function(d,i) {
303
+ if (!d.disabled) return;
304
+
305
+ controlsData = controlsData.map(function(s) {
306
+ s.disabled = true;
307
+ return s;
308
+ });
309
+ d.disabled = false;
310
+
311
+ switch (d.key) {
312
+ case 'Stacked':
313
+ stacked.style('stack');
314
+ break;
315
+ case 'Stream':
316
+ stacked.style('stream');
317
+ break;
318
+ case 'Expanded':
319
+ stacked.style('expand');
320
+ break;
321
+ }
322
+
323
+ state.style = stacked.style();
324
+ dispatch.stateChange(state);
325
+
326
+ //selection.transition().call(chart);
327
+ chart.update();
328
+ });
329
+
330
+ dispatch.on('tooltipShow', function(e) {
331
+ if (tooltips) showTooltip(e, that.parentNode);
332
+ });
333
+
334
+ // Update chart from a state object passed to event handler
335
+ dispatch.on('changeState', function(e) {
336
+
337
+ if (typeof e.disabled !== 'undefined') {
338
+ data.forEach(function(series,i) {
339
+ series.disabled = e.disabled[i];
340
+ });
341
+
342
+ state.disabled = e.disabled;
343
+ }
344
+
345
+ if (typeof e.style !== 'undefined') {
346
+ stacked.style(e.style);
347
+ }
348
+
349
+ chart.update();
350
+ });
351
+
352
+ });
353
+
354
+
355
+ return chart;
356
+ }
357
+
358
+
359
+ //============================================================
360
+ // Event Handling/Dispatching (out of chart's scope)
361
+ //------------------------------------------------------------
362
+
363
+ stacked.dispatch.on('tooltipShow', function(e) {
364
+ //disable tooltips when value ~= 0
365
+ //// TODO: consider removing points from voronoi that have 0 value instead of this hack
366
+ /*
367
+ 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
368
+ setTimeout(function() { d3.selectAll('.point.hover').classed('hover', false) }, 0);
369
+ return false;
370
+ }
371
+ */
372
+
373
+ e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top],
374
+ dispatch.tooltipShow(e);
375
+ });
376
+
377
+ stacked.dispatch.on('tooltipHide', function(e) {
378
+ dispatch.tooltipHide(e);
379
+ });
380
+
381
+ dispatch.on('tooltipHide', function() {
382
+ if (tooltips) nv.tooltip.cleanup();
383
+ });
384
+
385
+ //============================================================
386
+
387
+
388
+ //============================================================
389
+ // Expose Public Variables
390
+ //------------------------------------------------------------
391
+
392
+ // expose chart's sub-components
393
+ chart.dispatch = dispatch;
394
+ chart.stacked = stacked;
395
+ chart.legend = legend;
396
+ chart.controls = controls;
397
+ chart.xAxis = xAxis;
398
+ chart.yAxis = yAxis;
399
+
400
+ d3.rebind(chart, stacked, 'x', 'y', 'size', 'xScale', 'yScale', 'xDomain', 'yDomain', 'sizeDomain', 'interactive', 'offset', 'order', 'style', 'clipEdge', 'forceX', 'forceY', 'forceSize', 'interpolate');
401
+
402
+ chart.margin = function(_) {
403
+ if (!arguments.length) return margin;
404
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
405
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
406
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
407
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
408
+ return chart;
409
+ };
410
+
411
+ chart.width = function(_) {
412
+ if (!arguments.length) return getWidth;
413
+ width = _;
414
+ return chart;
415
+ };
416
+
417
+ chart.height = function(_) {
418
+ if (!arguments.length) return getHeight;
419
+ height = _;
420
+ return chart;
421
+ };
422
+
423
+ chart.color = function(_) {
424
+ if (!arguments.length) return color;
425
+ color = nv.utils.getColor(_);
426
+ legend.color(color);
427
+ stacked.color(color);
428
+ return chart;
429
+ };
430
+
431
+ chart.showControls = function(_) {
432
+ if (!arguments.length) return showControls;
433
+ showControls = _;
434
+ return chart;
435
+ };
436
+
437
+ chart.showLegend = function(_) {
438
+ if (!arguments.length) return showLegend;
439
+ showLegend = _;
440
+ return chart;
441
+ };
442
+
443
+ chart.tooltip = function(_) {
444
+ if (!arguments.length) return tooltip;
445
+ tooltip = _;
446
+ return chart;
447
+ };
448
+
449
+ chart.tooltips = function(_) {
450
+ if (!arguments.length) return tooltips;
451
+ tooltips = _;
452
+ return chart;
453
+ };
454
+
455
+ chart.tooltipContent = function(_) {
456
+ if (!arguments.length) return tooltip;
457
+ tooltip = _;
458
+ return chart;
459
+ };
460
+
461
+ chart.state = function(_) {
462
+ if (!arguments.length) return state;
463
+ state = _;
464
+ return chart;
465
+ };
466
+
467
+ chart.defaultState = function(_) {
468
+ if (!arguments.length) return defaultState;
469
+ defaultState = _;
470
+ return chart;
471
+ };
472
+
473
+ chart.noData = function(_) {
474
+ if (!arguments.length) return noData;
475
+ noData = _;
476
+ return chart;
477
+ };
478
+
479
+ yAxis.setTickFormat = yAxis.tickFormat;
480
+
481
+ yAxis.tickFormat = function(_) {
482
+ if (!arguments.length) return yAxisTickFormat;
483
+ yAxisTickFormat = _;
484
+ return yAxis;
485
+ };
486
+
487
+ //============================================================
488
+
489
+ return chart;
490
+ }