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,386 @@
1
+ nv.models.pie = function() {
2
+
3
+ //============================================================
4
+ // Public Variables with Default Settings
5
+ //------------------------------------------------------------
6
+
7
+ var margin = {top: 0, right: 0, bottom: 0, left: 0}
8
+ , width = 500
9
+ , height = 500
10
+ , getValues = function(d) { return d.values }
11
+ , getX = function(d) { return d.x }
12
+ , getY = function(d) { return d.y }
13
+ , getDescription = function(d) { return d.description }
14
+ , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one
15
+ , color = nv.utils.defaultColor()
16
+ , valueFormat = d3.format(',.2f')
17
+ , showLabels = true
18
+ , pieLabelsOutside = true
19
+ , donutLabelsOutside = false
20
+ , labelThreshold = .02 //if slice percentage is under this, don't show label
21
+ , donut = false
22
+ , labelSunbeamLayout = false
23
+ , startAngle = false
24
+ , endAngle = false
25
+ , donutRatio = 0.5
26
+ , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout')
27
+ ;
28
+
29
+ //============================================================
30
+
31
+
32
+ function chart(selection) {
33
+ selection.each(function(data) {
34
+ var availableWidth = width - margin.left - margin.right,
35
+ availableHeight = height - margin.top - margin.bottom,
36
+ radius = Math.min(availableWidth, availableHeight) / 2,
37
+ arcRadius = radius-(radius / 5),
38
+ container = d3.select(this);
39
+
40
+
41
+ //------------------------------------------------------------
42
+ // Setup containers and skeleton of chart
43
+
44
+ //var wrap = container.selectAll('.nv-wrap.nv-pie').data([data]);
45
+ var wrap = container.selectAll('.nv-wrap.nv-pie').data([getValues(data[0])]);
46
+ var wrapEnter = wrap.enter().append('g').attr('class','nvd3 nv-wrap nv-pie nv-chart-' + id);
47
+ var gEnter = wrapEnter.append('g');
48
+ var g = wrap.select('g');
49
+
50
+ gEnter.append('g').attr('class', 'nv-pie');
51
+
52
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
53
+ g.select('.nv-pie').attr('transform', 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')');
54
+
55
+ //------------------------------------------------------------
56
+
57
+
58
+ container
59
+ .on('click', function(d,i) {
60
+ dispatch.chartClick({
61
+ data: d,
62
+ index: i,
63
+ pos: d3.event,
64
+ id: id
65
+ });
66
+ });
67
+
68
+
69
+ var arc = d3.svg.arc()
70
+ .outerRadius(arcRadius);
71
+
72
+ if (startAngle) arc.startAngle(startAngle)
73
+ if (endAngle) arc.endAngle(endAngle);
74
+ if (donut) arc.innerRadius(radius * donutRatio);
75
+
76
+ // Setup the Pie chart and choose the data element
77
+ var pie = d3.layout.pie()
78
+ .sort(null)
79
+ .value(function(d) { return d.disabled ? 0 : getY(d) });
80
+
81
+ var slices = wrap.select('.nv-pie').selectAll('.nv-slice')
82
+ .data(pie);
83
+
84
+ slices.exit().remove();
85
+
86
+ var ae = slices.enter().append('g')
87
+ .attr('class', 'nv-slice')
88
+ .on('mouseover', function(d,i){
89
+ d3.select(this).classed('hover', true);
90
+ dispatch.elementMouseover({
91
+ label: getX(d.data),
92
+ value: getY(d.data),
93
+ point: d.data,
94
+ pointIndex: i,
95
+ pos: [d3.event.pageX, d3.event.pageY],
96
+ id: id
97
+ });
98
+ })
99
+ .on('mouseout', function(d,i){
100
+ d3.select(this).classed('hover', false);
101
+ dispatch.elementMouseout({
102
+ label: getX(d.data),
103
+ value: getY(d.data),
104
+ point: d.data,
105
+ index: i,
106
+ id: id
107
+ });
108
+ })
109
+ .on('click', function(d,i) {
110
+ dispatch.elementClick({
111
+ label: getX(d.data),
112
+ value: getY(d.data),
113
+ point: d.data,
114
+ index: i,
115
+ pos: d3.event,
116
+ id: id
117
+ });
118
+ d3.event.stopPropagation();
119
+ })
120
+ .on('dblclick', function(d,i) {
121
+ dispatch.elementDblClick({
122
+ label: getX(d.data),
123
+ value: getY(d.data),
124
+ point: d.data,
125
+ index: i,
126
+ pos: d3.event,
127
+ id: id
128
+ });
129
+ d3.event.stopPropagation();
130
+ });
131
+
132
+ slices
133
+ .attr('fill', function(d,i) { return color(d, i); })
134
+ .attr('stroke', function(d,i) { return color(d, i); });
135
+
136
+ var paths = ae.append('path')
137
+ .each(function(d) { this._current = d; });
138
+ //.attr('d', arc);
139
+
140
+ d3.transition(slices.select('path'))
141
+ .attr('d', arc)
142
+ .attrTween('d', arcTween);
143
+
144
+ if (showLabels) {
145
+ // This does the normal label
146
+ var labelsArc = d3.svg.arc().innerRadius(0);
147
+
148
+ if (pieLabelsOutside){ labelsArc = arc; }
149
+
150
+ if (donutLabelsOutside) { labelsArc = d3.svg.arc().outerRadius(arc.outerRadius()); }
151
+
152
+ ae.append("g").classed("nv-label", true)
153
+ .each(function(d, i) {
154
+ var group = d3.select(this);
155
+
156
+ group
157
+ .attr('transform', function(d) {
158
+ if (labelSunbeamLayout) {
159
+ d.outerRadius = arcRadius + 10; // Set Outer Coordinate
160
+ d.innerRadius = arcRadius + 15; // Set Inner Coordinate
161
+ var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 / Math.PI);
162
+ if ((d.startAngle+d.endAngle)/2 < Math.PI) {
163
+ rotateAngle -= 90;
164
+ } else {
165
+ rotateAngle += 90;
166
+ }
167
+ return 'translate(' + labelsArc.centroid(d) + ') rotate(' + rotateAngle + ')';
168
+ } else {
169
+ d.outerRadius = radius + 10; // Set Outer Coordinate
170
+ d.innerRadius = radius + 15; // Set Inner Coordinate
171
+ return 'translate(' + labelsArc.centroid(d) + ')'
172
+ }
173
+ });
174
+
175
+ group.append('rect')
176
+ .style('stroke', '#fff')
177
+ .style('fill', '#fff')
178
+ .attr("rx", 3)
179
+ .attr("ry", 3);
180
+
181
+ group.append('text')
182
+ .style('text-anchor', labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle') //center the text on it's origin or begin/end if orthogonal aligned
183
+ .style('fill', '#000')
184
+
185
+
186
+ });
187
+
188
+ slices.select(".nv-label").transition()
189
+ .attr('transform', function(d) {
190
+ if (labelSunbeamLayout) {
191
+ d.outerRadius = arcRadius + 10; // Set Outer Coordinate
192
+ d.innerRadius = arcRadius + 15; // Set Inner Coordinate
193
+ var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 / Math.PI);
194
+ if ((d.startAngle+d.endAngle)/2 < Math.PI) {
195
+ rotateAngle -= 90;
196
+ } else {
197
+ rotateAngle += 90;
198
+ }
199
+ return 'translate(' + labelsArc.centroid(d) + ') rotate(' + rotateAngle + ')';
200
+ } else {
201
+ d.outerRadius = radius + 10; // Set Outer Coordinate
202
+ d.innerRadius = radius + 15; // Set Inner Coordinate
203
+ return 'translate(' + labelsArc.centroid(d) + ')'
204
+ }
205
+ });
206
+
207
+ slices.each(function(d, i) {
208
+ var slice = d3.select(this);
209
+
210
+ slice
211
+ .select(".nv-label text")
212
+ .style('text-anchor', labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle') //center the text on it's origin or begin/end if orthogonal aligned
213
+ .text(function(d, i) {
214
+ var percent = (d.endAngle - d.startAngle) / (2 * Math.PI);
215
+ return (d.value && percent > labelThreshold) ? getX(d.data) : '';
216
+ });
217
+
218
+ var textBox = slice.select('text').node().getBBox();
219
+ slice.select(".nv-label rect")
220
+ .attr("width", textBox.width + 10)
221
+ .attr("height", textBox.height + 10)
222
+ .attr("transform", function() {
223
+ return "translate(" + [textBox.x - 5, textBox.y - 5] + ")";
224
+ });
225
+ });
226
+ }
227
+
228
+
229
+ // Computes the angle of an arc, converting from radians to degrees.
230
+ function angle(d) {
231
+ var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
232
+ return a > 90 ? a - 180 : a;
233
+ }
234
+
235
+ function arcTween(a) {
236
+ a.endAngle = isNaN(a.endAngle) ? 0 : a.endAngle;
237
+ a.startAngle = isNaN(a.startAngle) ? 0 : a.startAngle;
238
+ if (!donut) a.innerRadius = 0;
239
+ var i = d3.interpolate(this._current, a);
240
+ this._current = i(0);
241
+ return function(t) {
242
+ return arc(i(t));
243
+ };
244
+ }
245
+
246
+ function tweenPie(b) {
247
+ b.innerRadius = 0;
248
+ var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
249
+ return function(t) {
250
+ return arc(i(t));
251
+ };
252
+ }
253
+
254
+ });
255
+
256
+ return chart;
257
+ }
258
+
259
+
260
+ //============================================================
261
+ // Expose Public Variables
262
+ //------------------------------------------------------------
263
+
264
+ chart.dispatch = dispatch;
265
+
266
+ chart.margin = function(_) {
267
+ if (!arguments.length) return margin;
268
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
269
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
270
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
271
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
272
+ return chart;
273
+ };
274
+
275
+ chart.width = function(_) {
276
+ if (!arguments.length) return width;
277
+ width = _;
278
+ return chart;
279
+ };
280
+
281
+ chart.height = function(_) {
282
+ if (!arguments.length) return height;
283
+ height = _;
284
+ return chart;
285
+ };
286
+
287
+ chart.values = function(_) {
288
+ if (!arguments.length) return getValues;
289
+ getValues = _;
290
+ return chart;
291
+ };
292
+
293
+ chart.x = function(_) {
294
+ if (!arguments.length) return getX;
295
+ getX = _;
296
+ return chart;
297
+ };
298
+
299
+ chart.y = function(_) {
300
+ if (!arguments.length) return getY;
301
+ getY = d3.functor(_);
302
+ return chart;
303
+ };
304
+
305
+ chart.description = function(_) {
306
+ if (!arguments.length) return getDescription;
307
+ getDescription = _;
308
+ return chart;
309
+ };
310
+
311
+ chart.showLabels = function(_) {
312
+ if (!arguments.length) return showLabels;
313
+ showLabels = _;
314
+ return chart;
315
+ };
316
+
317
+ chart.labelSunbeamLayout = function(_) {
318
+ if (!arguments.length) return labelSunbeamLayout;
319
+ labelSunbeamLayout = _;
320
+ return chart;
321
+ };
322
+
323
+ chart.donutLabelsOutside = function(_) {
324
+ if (!arguments.length) return donutLabelsOutside;
325
+ donutLabelsOutside = _;
326
+ return chart;
327
+ };
328
+
329
+ chart.pieLabelsOutside = function(_) {
330
+ if (!arguments.length) return pieLabelsOutside;
331
+ pieLabelsOutside = _;
332
+ return chart;
333
+ };
334
+
335
+ chart.donut = function(_) {
336
+ if (!arguments.length) return donut;
337
+ donut = _;
338
+ return chart;
339
+ };
340
+
341
+ chart.donutRatio = function(_) {
342
+ if (!arguments.length) return donutRatio;
343
+ donutRatio = _;
344
+ return chart;
345
+ };
346
+
347
+ chart.startAngle = function(_) {
348
+ if (!arguments.length) return startAngle;
349
+ startAngle = _;
350
+ return chart;
351
+ };
352
+
353
+ chart.endAngle = function(_) {
354
+ if (!arguments.length) return endAngle;
355
+ endAngle = _;
356
+ return chart;
357
+ };
358
+
359
+ chart.id = function(_) {
360
+ if (!arguments.length) return id;
361
+ id = _;
362
+ return chart;
363
+ };
364
+
365
+ chart.color = function(_) {
366
+ if (!arguments.length) return color;
367
+ color = nv.utils.getColor(_);
368
+ return chart;
369
+ };
370
+
371
+ chart.valueFormat = function(_) {
372
+ if (!arguments.length) return valueFormat;
373
+ valueFormat = _;
374
+ return chart;
375
+ };
376
+
377
+ chart.labelThreshold = function(_) {
378
+ if (!arguments.length) return labelThreshold;
379
+ labelThreshold = _;
380
+ return chart;
381
+ };
382
+ //============================================================
383
+
384
+
385
+ return chart;
386
+ }
@@ -0,0 +1,302 @@
1
+ nv.models.pieChart = function() {
2
+
3
+ //============================================================
4
+ // Public Variables with Default Settings
5
+ //------------------------------------------------------------
6
+
7
+ var pie = nv.models.pie()
8
+ , legend = nv.models.legend()
9
+ ;
10
+
11
+ var margin = {top: 30, right: 20, bottom: 20, left: 20}
12
+ , width = null
13
+ , height = null
14
+ , showLegend = true
15
+ , color = nv.utils.defaultColor()
16
+ , tooltips = true
17
+ , tooltip = function(key, y, e, graph) {
18
+ return '<h3>' + key + '</h3>' +
19
+ '<p>' + y + '</p>'
20
+ }
21
+ , state = {}
22
+ , defaultState = null
23
+ , noData = "No Data Available."
24
+ , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState')
25
+ ;
26
+
27
+ //============================================================
28
+
29
+
30
+ //============================================================
31
+ // Private Variables
32
+ //------------------------------------------------------------
33
+
34
+ var showTooltip = function(e, offsetElement) {
35
+ var tooltipLabel = pie.description()(e.point) || pie.x()(e.point)
36
+ var left = e.pos[0] + ( (offsetElement && offsetElement.offsetLeft) || 0 ),
37
+ top = e.pos[1] + ( (offsetElement && offsetElement.offsetTop) || 0),
38
+ y = pie.valueFormat()(pie.y()(e.point)),
39
+ content = tooltip(tooltipLabel, y, e, chart);
40
+
41
+ nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's', null, offsetElement);
42
+ };
43
+
44
+ //============================================================
45
+
46
+
47
+ function chart(selection) {
48
+ selection.each(function(data) {
49
+ var container = d3.select(this),
50
+ that = this;
51
+
52
+ var availableWidth = (width || parseInt(container.style('width')) || 960)
53
+ - margin.left - margin.right,
54
+ availableHeight = (height || parseInt(container.style('height')) || 400)
55
+ - margin.top - margin.bottom;
56
+
57
+ chart.update = function() { container.transition().call(chart); };
58
+ chart.container = this;
59
+
60
+ //set state.disabled
61
+ state.disabled = data[0].map(function(d) { return !!d.disabled });
62
+
63
+ if (!defaultState) {
64
+ var key;
65
+ defaultState = {};
66
+ for (key in state) {
67
+ if (state[key] instanceof Array)
68
+ defaultState[key] = state[key].slice(0);
69
+ else
70
+ defaultState[key] = state[key];
71
+ }
72
+ }
73
+
74
+ //------------------------------------------------------------
75
+ // Display No Data message if there's nothing to show.
76
+
77
+ if (!data[0] || !data[0].length) {
78
+ var noDataText = container.selectAll('.nv-noData').data([noData]);
79
+
80
+ noDataText.enter().append('text')
81
+ .attr('class', 'nvd3 nv-noData')
82
+ .attr('dy', '-.7em')
83
+ .style('text-anchor', 'middle');
84
+
85
+ noDataText
86
+ .attr('x', margin.left + availableWidth / 2)
87
+ .attr('y', margin.top + availableHeight / 2)
88
+ .text(function(d) { return d });
89
+
90
+ return chart;
91
+ } else {
92
+ container.selectAll('.nv-noData').remove();
93
+ }
94
+
95
+ //------------------------------------------------------------
96
+
97
+
98
+ //------------------------------------------------------------
99
+ // Setup containers and skeleton of chart
100
+
101
+ var wrap = container.selectAll('g.nv-wrap.nv-pieChart').data([data]);
102
+ var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-pieChart').append('g');
103
+ var g = wrap.select('g');
104
+
105
+ gEnter.append('g').attr('class', 'nv-pieWrap');
106
+ gEnter.append('g').attr('class', 'nv-legendWrap');
107
+
108
+ //------------------------------------------------------------
109
+
110
+
111
+ //------------------------------------------------------------
112
+ // Legend
113
+
114
+ if (showLegend) {
115
+ legend
116
+ .width( availableWidth )
117
+ .key(pie.x());
118
+
119
+ wrap.select('.nv-legendWrap')
120
+ .datum(pie.values()(data[0]))
121
+ .call(legend);
122
+
123
+ if ( margin.top != legend.height()) {
124
+ margin.top = legend.height();
125
+ availableHeight = (height || parseInt(container.style('height')) || 400)
126
+ - margin.top - margin.bottom;
127
+ }
128
+
129
+ wrap.select('.nv-legendWrap')
130
+ .attr('transform', 'translate(0,' + (-margin.top) +')');
131
+ }
132
+
133
+ //------------------------------------------------------------
134
+
135
+
136
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
137
+
138
+
139
+ //------------------------------------------------------------
140
+ // Main Chart Component(s)
141
+
142
+ pie
143
+ .width(availableWidth)
144
+ .height(availableHeight);
145
+
146
+
147
+ var pieWrap = g.select('.nv-pieWrap')
148
+ .datum(data);
149
+
150
+ d3.transition(pieWrap).call(pie);
151
+
152
+ //------------------------------------------------------------
153
+
154
+
155
+ //============================================================
156
+ // Event Handling/Dispatching (in chart's scope)
157
+ //------------------------------------------------------------
158
+
159
+ legend.dispatch.on('legendClick', function(d,i, that) {
160
+ d.disabled = !d.disabled;
161
+
162
+ if (!pie.values()(data[0]).filter(function(d) { return !d.disabled }).length) {
163
+ pie.values()(data[0]).map(function(d) {
164
+ d.disabled = false;
165
+ wrap.selectAll('.nv-series').classed('disabled', false);
166
+ return d;
167
+ });
168
+ }
169
+
170
+ state.disabled = data[0].map(function(d) { return !!d.disabled });
171
+ dispatch.stateChange(state);
172
+
173
+ chart.update();
174
+ });
175
+
176
+ pie.dispatch.on('elementMouseout.tooltip', function(e) {
177
+ dispatch.tooltipHide(e);
178
+ });
179
+
180
+ // Update chart from a state object passed to event handler
181
+ dispatch.on('changeState', function(e) {
182
+
183
+ if (typeof e.disabled !== 'undefined') {
184
+ data[0].forEach(function(series,i) {
185
+ series.disabled = e.disabled[i];
186
+ });
187
+
188
+ state.disabled = e.disabled;
189
+ }
190
+
191
+ chart.update();
192
+ });
193
+
194
+ //============================================================
195
+
196
+
197
+ });
198
+
199
+ return chart;
200
+ }
201
+
202
+ //============================================================
203
+ // Event Handling/Dispatching (out of chart's scope)
204
+ //------------------------------------------------------------
205
+
206
+ pie.dispatch.on('elementMouseover.tooltip', function(e) {
207
+ e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
208
+ dispatch.tooltipShow(e);
209
+ });
210
+
211
+ dispatch.on('tooltipShow', function(e) {
212
+ if (tooltips) showTooltip(e);
213
+ });
214
+
215
+ dispatch.on('tooltipHide', function() {
216
+ if (tooltips) nv.tooltip.cleanup();
217
+ });
218
+
219
+ //============================================================
220
+
221
+
222
+ //============================================================
223
+ // Expose Public Variables
224
+ //------------------------------------------------------------
225
+
226
+ // expose chart's sub-components
227
+ chart.legend = legend;
228
+ chart.dispatch = dispatch;
229
+ chart.pie = pie;
230
+
231
+ d3.rebind(chart, pie, 'valueFormat', 'values', 'x', 'y', 'description', 'id', 'showLabels', 'donutLabelsOutside', 'pieLabelsOutside', 'donut', 'donutRatio', 'labelThreshold');
232
+
233
+ chart.margin = function(_) {
234
+ if (!arguments.length) return margin;
235
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
236
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
237
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
238
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
239
+ return chart;
240
+ };
241
+
242
+ chart.width = function(_) {
243
+ if (!arguments.length) return width;
244
+ width = _;
245
+ return chart;
246
+ };
247
+
248
+ chart.height = function(_) {
249
+ if (!arguments.length) return height;
250
+ height = _;
251
+ return chart;
252
+ };
253
+
254
+ chart.color = function(_) {
255
+ if (!arguments.length) return color;
256
+ color = nv.utils.getColor(_);
257
+ legend.color(color);
258
+ pie.color(color);
259
+ return chart;
260
+ };
261
+
262
+ chart.showLegend = function(_) {
263
+ if (!arguments.length) return showLegend;
264
+ showLegend = _;
265
+ return chart;
266
+ };
267
+
268
+ chart.tooltips = function(_) {
269
+ if (!arguments.length) return tooltips;
270
+ tooltips = _;
271
+ return chart;
272
+ };
273
+
274
+ chart.tooltipContent = function(_) {
275
+ if (!arguments.length) return tooltip;
276
+ tooltip = _;
277
+ return chart;
278
+ };
279
+
280
+ chart.state = function(_) {
281
+ if (!arguments.length) return state;
282
+ state = _;
283
+ return chart;
284
+ };
285
+
286
+ chart.defaultState = function(_) {
287
+ if (!arguments.length) return defaultState;
288
+ defaultState = _;
289
+ return chart;
290
+ };
291
+
292
+ chart.noData = function(_) {
293
+ if (!arguments.length) return noData;
294
+ noData = _;
295
+ return chart;
296
+ };
297
+
298
+ //============================================================
299
+
300
+
301
+ return chart;
302
+ }