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,420 @@
1
+
2
+ nv.models.multiBarHorizontal = function() {
3
+
4
+ //============================================================
5
+ // Public Variables with Default Settings
6
+ //------------------------------------------------------------
7
+
8
+ var margin = {top: 0, right: 0, bottom: 0, left: 0}
9
+ , width = 960
10
+ , height = 500
11
+ , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one
12
+ , x = d3.scale.ordinal()
13
+ , y = d3.scale.linear()
14
+ , getX = function(d) { return d.x }
15
+ , getY = function(d) { return d.y }
16
+ , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar graphs... user can always do chart.forceY([]) to remove
17
+ , color = nv.utils.defaultColor()
18
+ , barColor = null // adding the ability to set the color for each rather than the whole group
19
+ , disabled // used in conjunction with barColor to communicate from multiBarHorizontalChart what series are disabled
20
+ , stacked = false
21
+ , showValues = false
22
+ , valuePadding = 60
23
+ , valueFormat = d3.format(',.2f')
24
+ , delay = 1200
25
+ , xDomain
26
+ , yDomain
27
+ , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout')
28
+ ;
29
+
30
+ //============================================================
31
+
32
+
33
+ //============================================================
34
+ // Private Variables
35
+ //------------------------------------------------------------
36
+
37
+ var x0, y0 //used to store previous scales
38
+ ;
39
+
40
+ //============================================================
41
+
42
+
43
+ function chart(selection) {
44
+ selection.each(function(data) {
45
+ var availableWidth = width - margin.left - margin.right,
46
+ availableHeight = height - margin.top - margin.bottom,
47
+ container = d3.select(this);
48
+
49
+
50
+ if (stacked)
51
+ data = d3.layout.stack()
52
+ .offset('zero')
53
+ .values(function(d){ return d.values })
54
+ .y(getY)
55
+ (data);
56
+
57
+
58
+ //add series index to each data point for reference
59
+ data = data.map(function(series, i) {
60
+ series.values = series.values.map(function(point) {
61
+ point.series = i;
62
+ return point;
63
+ });
64
+ return series;
65
+ });
66
+
67
+
68
+
69
+ //------------------------------------------------------------
70
+ // HACK for negative value stacking
71
+ if (stacked)
72
+ data[0].values.map(function(d,i) {
73
+ var posBase = 0, negBase = 0;
74
+ data.map(function(d) {
75
+ var f = d.values[i]
76
+ f.size = Math.abs(f.y);
77
+ if (f.y<0) {
78
+ f.y1 = negBase - f.size;
79
+ negBase = negBase - f.size;
80
+ } else
81
+ {
82
+ f.y1 = posBase;
83
+ posBase = posBase + f.size;
84
+ }
85
+ });
86
+ });
87
+
88
+
89
+
90
+ //------------------------------------------------------------
91
+ // Setup Scales
92
+
93
+ // remap and flatten the data for use in calculating the scales' domains
94
+ var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate
95
+ data.map(function(d) {
96
+ return d.values.map(function(d,i) {
97
+ return { x: getX(d,i), y: getY(d,i), y0: d.y0, y1: d.y1 }
98
+ })
99
+ });
100
+
101
+ x .domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))
102
+ .rangeBands([0, availableHeight], .1);
103
+
104
+ //y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return d.y + (stacked ? d.y0 : 0) }).concat(forceY)))
105
+ y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return stacked ? (d.y > 0 ? d.y1 + d.y : d.y1 ) : d.y }).concat(forceY)))
106
+
107
+ if (showValues && !stacked)
108
+ y.range([(y.domain()[0] < 0 ? valuePadding : 0), availableWidth - (y.domain()[1] > 0 ? valuePadding : 0) ]);
109
+ else
110
+ y.range([0, availableWidth]);
111
+
112
+ x0 = x0 || x;
113
+ y0 = y0 || d3.scale.linear().domain(y.domain()).range([y(0),y(0)]);
114
+
115
+ //------------------------------------------------------------
116
+
117
+
118
+ //------------------------------------------------------------
119
+ // Setup containers and skeleton of chart
120
+
121
+ var wrap = d3.select(this).selectAll('g.nv-wrap.nv-multibarHorizontal').data([data]);
122
+ var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multibarHorizontal');
123
+ var defsEnter = wrapEnter.append('defs');
124
+ var gEnter = wrapEnter.append('g');
125
+ var g = wrap.select('g');
126
+
127
+ gEnter.append('g').attr('class', 'nv-groups');
128
+
129
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
130
+
131
+ //------------------------------------------------------------
132
+
133
+
134
+
135
+ var groups = wrap.select('.nv-groups').selectAll('.nv-group')
136
+ .data(function(d) { return d }, function(d) { return d.key });
137
+ groups.enter().append('g')
138
+ .style('stroke-opacity', 1e-6)
139
+ .style('fill-opacity', 1e-6);
140
+ d3.transition(groups.exit())
141
+ .style('stroke-opacity', 1e-6)
142
+ .style('fill-opacity', 1e-6)
143
+ .remove();
144
+ groups
145
+ .attr('class', function(d,i) { return 'nv-group nv-series-' + i })
146
+ .classed('hover', function(d) { return d.hover })
147
+ .style('fill', function(d,i){ return color(d, i) })
148
+ .style('stroke', function(d,i){ return color(d, i) });
149
+ d3.transition(groups)
150
+ .style('stroke-opacity', 1)
151
+ .style('fill-opacity', .75);
152
+
153
+
154
+ var bars = groups.selectAll('g.nv-bar')
155
+ .data(function(d) { return d.values });
156
+
157
+ bars.exit().remove();
158
+
159
+
160
+ var barsEnter = bars.enter().append('g')
161
+ .attr('transform', function(d,i,j) {
162
+ return 'translate(' + y0(stacked ? d.y0 : 0) + ',' + (stacked ? 0 : (j * x.rangeBand() / data.length ) + x(getX(d,i))) + ')'
163
+ });
164
+
165
+ barsEnter.append('rect')
166
+ .attr('width', 0)
167
+ .attr('height', x.rangeBand() / (stacked ? 1 : data.length) )
168
+
169
+ bars
170
+ .on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here
171
+ d3.select(this).classed('hover', true);
172
+ dispatch.elementMouseover({
173
+ value: getY(d,i),
174
+ point: d,
175
+ series: data[d.series],
176
+ pos: [ y(getY(d,i) + (stacked ? d.y0 : 0)), x(getX(d,i)) + (x.rangeBand() * (stacked ? data.length / 2 : d.series + .5) / data.length) ],
177
+ pointIndex: i,
178
+ seriesIndex: d.series,
179
+ e: d3.event
180
+ });
181
+ })
182
+ .on('mouseout', function(d,i) {
183
+ d3.select(this).classed('hover', false);
184
+ dispatch.elementMouseout({
185
+ value: getY(d,i),
186
+ point: d,
187
+ series: data[d.series],
188
+ pointIndex: i,
189
+ seriesIndex: d.series,
190
+ e: d3.event
191
+ });
192
+ })
193
+ .on('click', function(d,i) {
194
+ dispatch.elementClick({
195
+ value: getY(d,i),
196
+ point: d,
197
+ series: data[d.series],
198
+ pos: [x(getX(d,i)) + (x.rangeBand() * (stacked ? data.length / 2 : d.series + .5) / data.length), y(getY(d,i) + (stacked ? d.y0 : 0))], // TODO: Figure out why the value appears to be shifted
199
+ pointIndex: i,
200
+ seriesIndex: d.series,
201
+ e: d3.event
202
+ });
203
+ d3.event.stopPropagation();
204
+ })
205
+ .on('dblclick', function(d,i) {
206
+ dispatch.elementDblClick({
207
+ value: getY(d,i),
208
+ point: d,
209
+ series: data[d.series],
210
+ pos: [x(getX(d,i)) + (x.rangeBand() * (stacked ? data.length / 2 : d.series + .5) / data.length), y(getY(d,i) + (stacked ? d.y0 : 0))], // TODO: Figure out why the value appears to be shifted
211
+ pointIndex: i,
212
+ seriesIndex: d.series,
213
+ e: d3.event
214
+ });
215
+ d3.event.stopPropagation();
216
+ });
217
+
218
+
219
+ barsEnter.append('text');
220
+
221
+ if (showValues && !stacked) {
222
+ bars.select('text')
223
+ .attr('text-anchor', function(d,i) { return getY(d,i) < 0 ? 'end' : 'start' })
224
+ .attr('y', x.rangeBand() / (data.length * 2))
225
+ .attr('dy', '.32em')
226
+ .text(function(d,i) { return valueFormat(getY(d,i)) })
227
+ d3.transition(bars)
228
+ //.delay(function(d,i) { return i * delay / data[0].values.length })
229
+ .select('text')
230
+ .attr('x', function(d,i) { return getY(d,i) < 0 ? -4 : y(getY(d,i)) - y(0) + 4 })
231
+ } else {
232
+ //bars.selectAll('text').remove();
233
+ bars.selectAll('text').text('');
234
+ }
235
+
236
+ bars
237
+ .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'})
238
+
239
+ if (barColor) {
240
+ if (!disabled) disabled = data.map(function() { return true });
241
+ bars
242
+ //.style('fill', barColor)
243
+ //.style('stroke', barColor)
244
+ //.style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(j).toString(); })
245
+ //.style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(j).toString(); })
246
+ .style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker( disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j] ).toString(); })
247
+ .style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker( disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j] ).toString(); });
248
+ }
249
+
250
+ if (stacked)
251
+ d3.transition(bars)
252
+ //.delay(function(d,i) { return i * delay / data[0].values.length })
253
+ .attr('transform', function(d,i) {
254
+ //return 'translate(' + y(d.y0) + ',0)'
255
+ //return 'translate(' + y(d.y0) + ',' + x(getX(d,i)) + ')'
256
+ return 'translate(' + y(d.y1) + ',' + x(getX(d,i)) + ')'
257
+ })
258
+ .select('rect')
259
+ .attr('width', function(d,i) {
260
+ return Math.abs(y(getY(d,i) + d.y0) - y(d.y0))
261
+ })
262
+ .attr('height', x.rangeBand() );
263
+ else
264
+ d3.transition(bars)
265
+ //.delay(function(d,i) { return i * delay / data[0].values.length })
266
+ .attr('transform', function(d,i) {
267
+ //TODO: stacked must be all positive or all negative, not both?
268
+ return 'translate(' +
269
+ (getY(d,i) < 0 ? y(getY(d,i)) : y(0))
270
+ + ',' +
271
+ (d.series * x.rangeBand() / data.length
272
+ +
273
+ x(getX(d,i)) )
274
+ + ')'
275
+ })
276
+ .select('rect')
277
+ .attr('height', x.rangeBand() / data.length )
278
+ .attr('width', function(d,i) {
279
+ return Math.max(Math.abs(y(getY(d,i)) - y(0)),1)
280
+ });
281
+
282
+
283
+ //store old scales for use in transitions on update
284
+ x0 = x.copy();
285
+ y0 = y.copy();
286
+
287
+ });
288
+
289
+ return chart;
290
+ }
291
+
292
+
293
+ //============================================================
294
+ // Expose Public Variables
295
+ //------------------------------------------------------------
296
+
297
+ chart.dispatch = dispatch;
298
+
299
+ chart.x = function(_) {
300
+ if (!arguments.length) return getX;
301
+ getX = _;
302
+ return chart;
303
+ };
304
+
305
+ chart.y = function(_) {
306
+ if (!arguments.length) return getY;
307
+ getY = _;
308
+ return chart;
309
+ };
310
+
311
+ chart.margin = function(_) {
312
+ if (!arguments.length) return margin;
313
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
314
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
315
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
316
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
317
+ return chart;
318
+ };
319
+
320
+ chart.width = function(_) {
321
+ if (!arguments.length) return width;
322
+ width = _;
323
+ return chart;
324
+ };
325
+
326
+ chart.height = function(_) {
327
+ if (!arguments.length) return height;
328
+ height = _;
329
+ return chart;
330
+ };
331
+
332
+ chart.xScale = function(_) {
333
+ if (!arguments.length) return x;
334
+ x = _;
335
+ return chart;
336
+ };
337
+
338
+ chart.yScale = function(_) {
339
+ if (!arguments.length) return y;
340
+ y = _;
341
+ return chart;
342
+ };
343
+
344
+ chart.xDomain = function(_) {
345
+ if (!arguments.length) return xDomain;
346
+ xDomain = _;
347
+ return chart;
348
+ };
349
+
350
+ chart.yDomain = function(_) {
351
+ if (!arguments.length) return yDomain;
352
+ yDomain = _;
353
+ return chart;
354
+ };
355
+
356
+ chart.forceY = function(_) {
357
+ if (!arguments.length) return forceY;
358
+ forceY = _;
359
+ return chart;
360
+ };
361
+
362
+ chart.stacked = function(_) {
363
+ if (!arguments.length) return stacked;
364
+ stacked = _;
365
+ return chart;
366
+ };
367
+
368
+ chart.color = function(_) {
369
+ if (!arguments.length) return color;
370
+ color = nv.utils.getColor(_);
371
+ return chart;
372
+ };
373
+
374
+ chart.barColor = function(_) {
375
+ if (!arguments.length) return barColor;
376
+ barColor = nv.utils.getColor(_);
377
+ return chart;
378
+ };
379
+
380
+ chart.disabled = function(_) {
381
+ if (!arguments.length) return disabled;
382
+ disabled = _;
383
+ return chart;
384
+ };
385
+
386
+ chart.id = function(_) {
387
+ if (!arguments.length) return id;
388
+ id = _;
389
+ return chart;
390
+ };
391
+
392
+ chart.delay = function(_) {
393
+ if (!arguments.length) return delay;
394
+ delay = _;
395
+ return chart;
396
+ };
397
+
398
+ chart.showValues = function(_) {
399
+ if (!arguments.length) return showValues;
400
+ showValues = _;
401
+ return chart;
402
+ };
403
+
404
+ chart.valueFormat= function(_) {
405
+ if (!arguments.length) return valueFormat;
406
+ valueFormat = _;
407
+ return chart;
408
+ };
409
+
410
+ chart.valuePadding = function(_) {
411
+ if (!arguments.length) return valuePadding;
412
+ valuePadding = _;
413
+ return chart;
414
+ };
415
+
416
+ //============================================================
417
+
418
+
419
+ return chart;
420
+ }