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,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
+ }