chartx 0.0.1

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 (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,317 @@
1
+ nv.models.indentedTree = function() {
2
+
3
+ //============================================================
4
+ // Public Variables with Default Settings
5
+ //------------------------------------------------------------
6
+
7
+ var margin = {top: 0, right: 0, bottom: 0, left: 0} //TODO: implement, maybe as margin on the containing div
8
+ , width = 960
9
+ , height = 500
10
+ , color = nv.utils.defaultColor()
11
+ , id = Math.floor(Math.random() * 10000)
12
+ , header = true
13
+ , filterZero = false
14
+ , noData = "No Data Available."
15
+ , childIndent = 20
16
+ , columns = [{key:'key', label: 'Name', type:'text'}] //TODO: consider functions like chart.addColumn, chart.removeColumn, instead of a block like this
17
+ , tableClass = null
18
+ , iconOpen = 'images/grey-plus.png' //TODO: consider removing this and replacing with a '+' or '-' unless user defines images
19
+ , iconClose = 'images/grey-minus.png'
20
+ , dispatch = d3.dispatch('elementClick', 'elementDblclick', 'elementMouseover', 'elementMouseout')
21
+ ;
22
+
23
+ //============================================================
24
+
25
+ var idx = 0;
26
+
27
+ function chart(selection) {
28
+ selection.each(function(data) {
29
+ var depth = 1,
30
+ container = d3.select(this);
31
+
32
+ var tree = d3.layout.tree()
33
+ .children(function(d) { return d.values })
34
+ .size([height, childIndent]); //Not sure if this is needed now that the result is HTML
35
+
36
+ chart.update = function() { container.transition().duration(600).call(chart) };
37
+
38
+
39
+ //------------------------------------------------------------
40
+ // Display No Data message if there's nothing to show.
41
+ if (!data[0]) data[0] = {key: noData};
42
+
43
+ //------------------------------------------------------------
44
+
45
+
46
+ var nodes = tree.nodes(data[0]);
47
+
48
+ // nodes.map(function(d) {
49
+ // d.id = i++;
50
+ // })
51
+
52
+ //------------------------------------------------------------
53
+ // Setup containers and skeleton of chart
54
+
55
+ var wrap = d3.select(this).selectAll('div').data([[nodes]]);
56
+ var wrapEnter = wrap.enter().append('div').attr('class', 'nvd3 nv-wrap nv-indentedtree');
57
+ var tableEnter = wrapEnter.append('table');
58
+ var table = wrap.select('table').attr('width', '100%').attr('class', tableClass);
59
+
60
+ //------------------------------------------------------------
61
+
62
+
63
+ if (header) {
64
+ var thead = tableEnter.append('thead');
65
+
66
+ var theadRow1 = thead.append('tr');
67
+
68
+ columns.forEach(function(column) {
69
+ theadRow1
70
+ .append('th')
71
+ .attr('width', column.width ? column.width : '10%')
72
+ .style('text-align', column.type == 'numeric' ? 'right' : 'left')
73
+ .append('span')
74
+ .text(column.label);
75
+ });
76
+ }
77
+
78
+
79
+ var tbody = table.selectAll('tbody')
80
+ .data(function(d) { return d });
81
+ tbody.enter().append('tbody');
82
+
83
+
84
+
85
+ //compute max generations
86
+ depth = d3.max(nodes, function(node) { return node.depth });
87
+ tree.size([height, depth * childIndent]); //TODO: see if this is necessary at all
88
+
89
+
90
+ // Update the nodes…
91
+ var node = tbody.selectAll('tr')
92
+ // .data(function(d) { return d; }, function(d) { return d.id || (d.id == ++i)});
93
+ .data(function(d) { return d.filter(function(d) { return (filterZero && !d.children) ? filterZero(d) : true; } )}, function(d,i) { return d.id || (d.id || ++idx)});
94
+ //.style('display', 'table-row'); //TODO: see if this does anything
95
+
96
+ node.exit().remove();
97
+
98
+ node.select('img.nv-treeicon')
99
+ .attr('src', icon)
100
+ .classed('folded', folded);
101
+
102
+ var nodeEnter = node.enter().append('tr');
103
+
104
+
105
+ columns.forEach(function(column, index) {
106
+
107
+ var nodeName = nodeEnter.append('td')
108
+ .style('padding-left', function(d) { return (index ? 0 : d.depth * childIndent + 12 + (icon(d) ? 0 : 16)) + 'px' }, 'important') //TODO: check why I did the ternary here
109
+ .style('text-align', column.type == 'numeric' ? 'right' : 'left');
110
+
111
+
112
+ if (index == 0) {
113
+ nodeName.append('img')
114
+ .classed('nv-treeicon', true)
115
+ .classed('nv-folded', folded)
116
+ .attr('src', icon)
117
+ .style('width', '14px')
118
+ .style('height', '14px')
119
+ .style('padding', '0 1px')
120
+ .style('display', function(d) { return icon(d) ? 'inline-block' : 'none'; })
121
+ .on('click', click);
122
+ }
123
+
124
+
125
+ nodeName.append('span')
126
+ .attr('class', d3.functor(column.classes) )
127
+ .text(function(d) { return column.format ? column.format(d) :
128
+ (d[column.key] || '-') });
129
+
130
+ if (column.showCount) {
131
+ nodeName.append('span')
132
+ .attr('class', 'nv-childrenCount');
133
+
134
+ node.selectAll('span.nv-childrenCount').text(function(d) {
135
+ return ((d.values && d.values.length) || (d._values && d._values.length)) ? //If this is a parent
136
+ '(' + ((d.values && (d.values.filter(function(d) { return filterZero ? filterZero(d) : true; }).length)) //If children are in values check its children and filter
137
+ || (d._values && d._values.filter(function(d) { return filterZero ? filterZero(d) : true; }).length) //Otherwise, do the same, but with the other name, _values...
138
+ || 0) + ')' //This is the catch-all in case there are no children after a filter
139
+ : '' //If this is not a parent, just give an empty string
140
+ });
141
+ }
142
+
143
+ if (column.click)
144
+ nodeName.select('span').on('click', column.click);
145
+
146
+ });
147
+
148
+ node
149
+ .order()
150
+ .on('click', function(d) {
151
+ dispatch.elementClick({
152
+ row: this, //TODO: decide whether or not this should be consistent with scatter/line events or should be an html link (a href)
153
+ data: d,
154
+ pos: [d.x, d.y]
155
+ });
156
+ })
157
+ .on('dblclick', function(d) {
158
+ dispatch.elementDblclick({
159
+ row: this,
160
+ data: d,
161
+ pos: [d.x, d.y]
162
+ });
163
+ })
164
+ .on('mouseover', function(d) {
165
+ dispatch.elementMouseover({
166
+ row: this,
167
+ data: d,
168
+ pos: [d.x, d.y]
169
+ });
170
+ })
171
+ .on('mouseout', function(d) {
172
+ dispatch.elementMouseout({
173
+ row: this,
174
+ data: d,
175
+ pos: [d.x, d.y]
176
+ });
177
+ });
178
+
179
+
180
+
181
+
182
+ // Toggle children on click.
183
+ function click(d, _, unshift) {
184
+ d3.event.stopPropagation();
185
+
186
+ if(d3.event.shiftKey && !unshift) {
187
+ //If you shift-click, it'll toggle fold all the children, instead of itself
188
+ d3.event.shiftKey = false;
189
+ d.values && d.values.forEach(function(node){
190
+ if (node.values || node._values) {
191
+ click(node, 0, true);
192
+ }
193
+ });
194
+ return true;
195
+ }
196
+ if(!hasChildren(d)) {
197
+ //download file
198
+ //window.location.href = d.url;
199
+ return true;
200
+ }
201
+ if (d.values) {
202
+ d._values = d.values;
203
+ d.values = null;
204
+ } else {
205
+ d.values = d._values;
206
+ d._values = null;
207
+ }
208
+ chart.update();
209
+ }
210
+
211
+
212
+ function icon(d) {
213
+ return (d._values && d._values.length) ? iconOpen : (d.values && d.values.length) ? iconClose : '';
214
+ }
215
+
216
+ function folded(d) {
217
+ return (d._values && d._values.length);
218
+ }
219
+
220
+ function hasChildren(d) {
221
+ var values = d.values || d._values;
222
+
223
+ return (values && values.length);
224
+ }
225
+
226
+
227
+ });
228
+
229
+ return chart;
230
+ }
231
+
232
+
233
+ //============================================================
234
+ // Expose Public Variables
235
+ //------------------------------------------------------------
236
+
237
+ chart.margin = function(_) {
238
+ if (!arguments.length) return margin;
239
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
240
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
241
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
242
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
243
+ return chart;
244
+ };
245
+
246
+ chart.width = function(_) {
247
+ if (!arguments.length) return width;
248
+ width = _;
249
+ return chart;
250
+ };
251
+
252
+ chart.height = function(_) {
253
+ if (!arguments.length) return height;
254
+ height = _;
255
+ return chart;
256
+ };
257
+
258
+ chart.color = function(_) {
259
+ if (!arguments.length) return color;
260
+ color = nv.utils.getColor(_);
261
+ scatter.color(color);
262
+ return chart;
263
+ };
264
+
265
+ chart.id = function(_) {
266
+ if (!arguments.length) return id;
267
+ id = _;
268
+ return chart;
269
+ };
270
+
271
+ chart.header = function(_) {
272
+ if (!arguments.length) return header;
273
+ header = _;
274
+ return chart;
275
+ };
276
+
277
+ chart.noData = function(_) {
278
+ if (!arguments.length) return noData;
279
+ noData = _;
280
+ return chart;
281
+ };
282
+
283
+ chart.filterZero = function(_) {
284
+ if (!arguments.length) return filterZero;
285
+ filterZero = _;
286
+ return chart;
287
+ };
288
+
289
+ chart.columns = function(_) {
290
+ if (!arguments.length) return columns;
291
+ columns = _;
292
+ return chart;
293
+ };
294
+
295
+ chart.tableClass = function(_) {
296
+ if (!arguments.length) return tableClass;
297
+ tableClass = _;
298
+ return chart;
299
+ };
300
+
301
+ chart.iconOpen = function(_){
302
+ if (!arguments.length) return iconOpen;
303
+ iconOpen = _;
304
+ return chart;
305
+ }
306
+
307
+ chart.iconClose = function(_){
308
+ if (!arguments.length) return iconClose;
309
+ iconClose = _;
310
+ return chart;
311
+ }
312
+
313
+ //============================================================
314
+
315
+
316
+ return chart;
317
+ };
@@ -0,0 +1,207 @@
1
+ nv.models.legend = function() {
2
+
3
+ //============================================================
4
+ // Public Variables with Default Settings
5
+ //------------------------------------------------------------
6
+
7
+ var margin = {top: 5, right: 0, bottom: 5, left: 0}
8
+ , width = 400
9
+ , height = 20
10
+ , getKey = function(d) { return d.key }
11
+ , color = nv.utils.defaultColor()
12
+ , align = true
13
+ , dispatch = d3.dispatch('legendClick', 'legendDblclick', 'legendMouseover', 'legendMouseout')
14
+ ;
15
+
16
+ //============================================================
17
+
18
+
19
+ function chart(selection) {
20
+ selection.each(function(data) {
21
+ var availableWidth = width - margin.left - margin.right,
22
+ container = d3.select(this);
23
+
24
+
25
+ //------------------------------------------------------------
26
+ // Setup containers and skeleton of chart
27
+
28
+ var wrap = container.selectAll('g.nv-legend').data([data]);
29
+ var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-legend').append('g');
30
+ var g = wrap.select('g');
31
+
32
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
33
+
34
+ //------------------------------------------------------------
35
+
36
+
37
+ var series = g.selectAll('.nv-series')
38
+ .data(function(d) { return d });
39
+ var seriesEnter = series.enter().append('g').attr('class', 'nv-series')
40
+ .on('mouseover', function(d,i) {
41
+ dispatch.legendMouseover(d,i); //TODO: Make consistent with other event objects
42
+ })
43
+ .on('mouseout', function(d,i) {
44
+ dispatch.legendMouseout(d,i);
45
+ })
46
+ .on('click', function(d,i) {
47
+ dispatch.legendClick(d,i);
48
+ })
49
+ .on('dblclick', function(d,i) {
50
+ dispatch.legendDblclick(d,i);
51
+ });
52
+ seriesEnter.append('circle')
53
+ .style('stroke-width', 2)
54
+ .attr('r', 5);
55
+ seriesEnter.append('text')
56
+ .attr('text-anchor', 'start')
57
+ .attr('dy', '.32em')
58
+ .attr('dx', '8');
59
+ series.classed('disabled', function(d) { return d.disabled });
60
+ series.exit().remove();
61
+ series.select('circle')
62
+ .style('fill', function(d,i) { return d.color || color(d,i)})
63
+ .style('stroke', function(d,i) { return d.color || color(d, i) });
64
+ series.select('text').text(getKey);
65
+
66
+
67
+ //TODO: implement fixed-width and max-width options (max-width is especially useful with the align option)
68
+
69
+ // NEW ALIGNING CODE, TODO: clean up
70
+ if (align) {
71
+
72
+ var seriesWidths = [];
73
+ series.each(function(d,i) {
74
+ var legendText = d3.select(this).select('text');
75
+ var svgComputedTextLength = legendText.node().getComputedTextLength()
76
+ || nv.utils.calcApproxTextWidth(legendText);
77
+ seriesWidths.push(svgComputedTextLength + 28); // 28 is ~ the width of the circle plus some padding
78
+ });
79
+
80
+ //nv.log('Series Widths: ', JSON.stringify(seriesWidths));
81
+
82
+ var seriesPerRow = 0;
83
+ var legendWidth = 0;
84
+ var columnWidths = [];
85
+
86
+ while ( legendWidth < availableWidth && seriesPerRow < seriesWidths.length) {
87
+ columnWidths[seriesPerRow] = seriesWidths[seriesPerRow];
88
+ legendWidth += seriesWidths[seriesPerRow++];
89
+ }
90
+
91
+
92
+ while ( legendWidth > availableWidth && seriesPerRow > 1 ) {
93
+ columnWidths = [];
94
+ seriesPerRow--;
95
+
96
+ for (k = 0; k < seriesWidths.length; k++) {
97
+ if (seriesWidths[k] > (columnWidths[k % seriesPerRow] || 0) )
98
+ columnWidths[k % seriesPerRow] = seriesWidths[k];
99
+ }
100
+
101
+ legendWidth = columnWidths.reduce(function(prev, cur, index, array) {
102
+ return prev + cur;
103
+ });
104
+ }
105
+ //console.log(columnWidths, legendWidth, seriesPerRow);
106
+
107
+ var xPositions = [];
108
+ for (var i = 0, curX = 0; i < seriesPerRow; i++) {
109
+ xPositions[i] = curX;
110
+ curX += columnWidths[i];
111
+ }
112
+
113
+ series
114
+ .attr('transform', function(d, i) {
115
+ return 'translate(' + xPositions[i % seriesPerRow] + ',' + (5 + Math.floor(i / seriesPerRow) * 20) + ')';
116
+ });
117
+
118
+ //position legend as far right as possible within the total width
119
+ g.attr('transform', 'translate(' + (width - margin.right - legendWidth) + ',' + margin.top + ')');
120
+
121
+ height = margin.top + margin.bottom + (Math.ceil(seriesWidths.length / seriesPerRow) * 20);
122
+
123
+ } else {
124
+
125
+ var ypos = 5,
126
+ newxpos = 5,
127
+ maxwidth = 0,
128
+ xpos;
129
+ series
130
+ .attr('transform', function(d, i) {
131
+ var length = d3.select(this).select('text').node().getComputedTextLength() + 28;
132
+ xpos = newxpos;
133
+
134
+ if (width < margin.left + margin.right + xpos + length) {
135
+ newxpos = xpos = 5;
136
+ ypos += 20;
137
+ }
138
+
139
+ newxpos += length;
140
+ if (newxpos > maxwidth) maxwidth = newxpos;
141
+
142
+ return 'translate(' + xpos + ',' + ypos + ')';
143
+ });
144
+
145
+ //position legend as far right as possible within the total width
146
+ g.attr('transform', 'translate(' + (width - margin.right - maxwidth) + ',' + margin.top + ')');
147
+
148
+ height = margin.top + margin.bottom + ypos + 15;
149
+
150
+ }
151
+
152
+ });
153
+
154
+ return chart;
155
+ }
156
+
157
+
158
+ //============================================================
159
+ // Expose Public Variables
160
+ //------------------------------------------------------------
161
+
162
+ chart.dispatch = dispatch;
163
+
164
+ chart.margin = function(_) {
165
+ if (!arguments.length) return margin;
166
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
167
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
168
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
169
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
170
+ return chart;
171
+ };
172
+
173
+ chart.width = function(_) {
174
+ if (!arguments.length) return width;
175
+ width = _;
176
+ return chart;
177
+ };
178
+
179
+ chart.height = function(_) {
180
+ if (!arguments.length) return height;
181
+ height = _;
182
+ return chart;
183
+ };
184
+
185
+ chart.key = function(_) {
186
+ if (!arguments.length) return getKey;
187
+ getKey = _;
188
+ return chart;
189
+ };
190
+
191
+ chart.color = function(_) {
192
+ if (!arguments.length) return color;
193
+ color = nv.utils.getColor(_);
194
+ return chart;
195
+ };
196
+
197
+ chart.align = function(_) {
198
+ if (!arguments.length) return align;
199
+ align = _;
200
+ return chart;
201
+ };
202
+
203
+ //============================================================
204
+
205
+
206
+ return chart;
207
+ }