pyk 0.2.6 → 0.2.7

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 (68) hide show
  1. checksums.yaml +8 -8
  2. data/app/assets/javascripts/lib/chardinjs.min.js +2 -0
  3. data/app/assets/javascripts/lib/crossfilter.js +1383 -1
  4. data/app/assets/javascripts/lib/{d3.js → d3.v3.js} +0 -0
  5. data/app/assets/javascripts/lib/dc.js +3492 -757
  6. data/app/assets/javascripts/lib/jquery.gridster.js +2 -3621
  7. data/app/assets/javascripts/lib/markermanager.js +2 -980
  8. data/app/assets/javascripts/lib/underscore.js +1276 -0
  9. data/app/assets/javascripts/nvd3/lib/colorbrewer.js +302 -0
  10. data/app/assets/javascripts/nvd3/lib/crossfilter.js +1180 -0
  11. data/app/assets/javascripts/nvd3/lib/crossfilter.min.js +1 -0
  12. data/app/assets/javascripts/nvd3/lib/d3.v2.js +7033 -0
  13. data/app/assets/javascripts/nvd3/lib/d3.v2.min.js +4 -0
  14. data/app/assets/javascripts/nvd3/lib/d3.v3.js +8436 -0
  15. data/app/assets/javascripts/nvd3/lib/fisheye.js +86 -0
  16. data/app/assets/javascripts/nvd3/lib/hive.js +80 -0
  17. data/app/assets/javascripts/nvd3/lib/horizon.js +192 -0
  18. data/app/assets/javascripts/nvd3/lib/sankey.js +292 -0
  19. data/app/assets/javascripts/nvd3/nv.d3.js +14312 -0
  20. data/app/assets/javascripts/nvd3/nv.d3.min.js +6 -0
  21. data/app/assets/javascripts/nvd3/src/core.js +122 -0
  22. data/app/assets/javascripts/nvd3/src/interactiveLayer.js +251 -0
  23. data/app/assets/javascripts/nvd3/src/models/axis.js +405 -0
  24. data/app/assets/javascripts/nvd3/src/models/backup/bullet.js +250 -0
  25. data/app/assets/javascripts/nvd3/src/models/backup/bulletChart.js +349 -0
  26. data/app/assets/javascripts/nvd3/src/models/boilerplate.js +104 -0
  27. data/app/assets/javascripts/nvd3/src/models/bullet.js +385 -0
  28. data/app/assets/javascripts/nvd3/src/models/bulletChart.js +343 -0
  29. data/app/assets/javascripts/nvd3/src/models/cumulativeLineChart.js +782 -0
  30. data/app/assets/javascripts/nvd3/src/models/discreteBar.js +349 -0
  31. data/app/assets/javascripts/nvd3/src/models/discreteBarChart.js +333 -0
  32. data/app/assets/javascripts/nvd3/src/models/distribution.js +148 -0
  33. data/app/assets/javascripts/nvd3/src/models/historicalBar.js +331 -0
  34. data/app/assets/javascripts/nvd3/src/models/historicalBarChart.js +419 -0
  35. data/app/assets/javascripts/nvd3/src/models/indentedTree.js +337 -0
  36. data/app/assets/javascripts/nvd3/src/models/legend.js +270 -0
  37. data/app/assets/javascripts/nvd3/src/models/line.js +284 -0
  38. data/app/assets/javascripts/nvd3/src/models/lineChart.js +465 -0
  39. data/app/assets/javascripts/nvd3/src/models/linePlusBarChart.js +433 -0
  40. data/app/assets/javascripts/nvd3/src/models/linePlusBarWithFocusChart.js +658 -0
  41. data/app/assets/javascripts/nvd3/src/models/lineWithFisheye.js +200 -0
  42. data/app/assets/javascripts/nvd3/src/models/lineWithFisheyeChart.js +297 -0
  43. data/app/assets/javascripts/nvd3/src/models/lineWithFocusChart.js +574 -0
  44. data/app/assets/javascripts/nvd3/src/models/multiBar.js +461 -0
  45. data/app/assets/javascripts/nvd3/src/models/multiBarChart.js +524 -0
  46. data/app/assets/javascripts/nvd3/src/models/multiBarHorizontal.js +424 -0
  47. data/app/assets/javascripts/nvd3/src/models/multiBarHorizontalChart.js +434 -0
  48. data/app/assets/javascripts/nvd3/src/models/multiBarTimeSeries.js +384 -0
  49. data/app/assets/javascripts/nvd3/src/models/multiBarTimeSeriesChart.js +405 -0
  50. data/app/assets/javascripts/nvd3/src/models/multiChart.js +452 -0
  51. data/app/assets/javascripts/nvd3/src/models/ohlcBar.js +380 -0
  52. data/app/assets/javascripts/nvd3/src/models/parallelCoordinates.js +239 -0
  53. data/app/assets/javascripts/nvd3/src/models/pie.js +398 -0
  54. data/app/assets/javascripts/nvd3/src/models/pieChart.js +292 -0
  55. data/app/assets/javascripts/nvd3/src/models/scatter.js +674 -0
  56. data/app/assets/javascripts/nvd3/src/models/scatterChart.js +628 -0
  57. data/app/assets/javascripts/nvd3/src/models/scatterPlusLineChart.js +620 -0
  58. data/app/assets/javascripts/nvd3/src/models/sparkline.js +194 -0
  59. data/app/assets/javascripts/nvd3/src/models/sparklinePlus.js +295 -0
  60. data/app/assets/javascripts/nvd3/src/models/stackedArea.js +368 -0
  61. data/app/assets/javascripts/nvd3/src/models/stackedAreaChart.js +629 -0
  62. data/app/assets/javascripts/nvd3/src/tooltip.js +490 -0
  63. data/app/assets/javascripts/nvd3/src/utils.js +152 -0
  64. data/app/assets/javascripts/pyk.js +1 -0
  65. data/app/assets/stylesheets/lib/chardinjs.css +82 -0
  66. data/app/assets/stylesheets/nvd3/nv.d3.css +769 -0
  67. data/app/assets/stylesheets/pyk.css.scss +1 -0
  68. metadata +61 -2
@@ -0,0 +1,292 @@
1
+ nv.models.pieChart = function() {
2
+ "use strict";
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.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 || !data.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(data)
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('stateChange', function(newState) {
160
+ state = newState;
161
+ dispatch.stateChange(state);
162
+ chart.update();
163
+ });
164
+
165
+ pie.dispatch.on('elementMouseout.tooltip', function(e) {
166
+ dispatch.tooltipHide(e);
167
+ });
168
+
169
+ // Update chart from a state object passed to event handler
170
+ dispatch.on('changeState', function(e) {
171
+
172
+ if (typeof e.disabled !== 'undefined') {
173
+ data.forEach(function(series,i) {
174
+ series.disabled = e.disabled[i];
175
+ });
176
+
177
+ state.disabled = e.disabled;
178
+ }
179
+
180
+ chart.update();
181
+ });
182
+
183
+ //============================================================
184
+
185
+
186
+ });
187
+
188
+ return chart;
189
+ }
190
+
191
+ //============================================================
192
+ // Event Handling/Dispatching (out of chart's scope)
193
+ //------------------------------------------------------------
194
+
195
+ pie.dispatch.on('elementMouseover.tooltip', function(e) {
196
+ e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
197
+ dispatch.tooltipShow(e);
198
+ });
199
+
200
+ dispatch.on('tooltipShow', function(e) {
201
+ if (tooltips) showTooltip(e);
202
+ });
203
+
204
+ dispatch.on('tooltipHide', function() {
205
+ if (tooltips) nv.tooltip.cleanup();
206
+ });
207
+
208
+ //============================================================
209
+
210
+
211
+ //============================================================
212
+ // Expose Public Variables
213
+ //------------------------------------------------------------
214
+
215
+ // expose chart's sub-components
216
+ chart.legend = legend;
217
+ chart.dispatch = dispatch;
218
+ chart.pie = pie;
219
+
220
+ d3.rebind(chart, pie, 'valueFormat', 'values', 'x', 'y', 'description', 'id', 'showLabels', 'donutLabelsOutside', 'pieLabelsOutside', 'labelType', 'donut', 'donutRatio', 'labelThreshold');
221
+ chart.options = nv.utils.optionsFunc.bind(chart);
222
+
223
+ chart.margin = function(_) {
224
+ if (!arguments.length) return margin;
225
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
226
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
227
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
228
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
229
+ return chart;
230
+ };
231
+
232
+ chart.width = function(_) {
233
+ if (!arguments.length) return width;
234
+ width = _;
235
+ return chart;
236
+ };
237
+
238
+ chart.height = function(_) {
239
+ if (!arguments.length) return height;
240
+ height = _;
241
+ return chart;
242
+ };
243
+
244
+ chart.color = function(_) {
245
+ if (!arguments.length) return color;
246
+ color = nv.utils.getColor(_);
247
+ legend.color(color);
248
+ pie.color(color);
249
+ return chart;
250
+ };
251
+
252
+ chart.showLegend = function(_) {
253
+ if (!arguments.length) return showLegend;
254
+ showLegend = _;
255
+ return chart;
256
+ };
257
+
258
+ chart.tooltips = function(_) {
259
+ if (!arguments.length) return tooltips;
260
+ tooltips = _;
261
+ return chart;
262
+ };
263
+
264
+ chart.tooltipContent = function(_) {
265
+ if (!arguments.length) return tooltip;
266
+ tooltip = _;
267
+ return chart;
268
+ };
269
+
270
+ chart.state = function(_) {
271
+ if (!arguments.length) return state;
272
+ state = _;
273
+ return chart;
274
+ };
275
+
276
+ chart.defaultState = function(_) {
277
+ if (!arguments.length) return defaultState;
278
+ defaultState = _;
279
+ return chart;
280
+ };
281
+
282
+ chart.noData = function(_) {
283
+ if (!arguments.length) return noData;
284
+ noData = _;
285
+ return chart;
286
+ };
287
+
288
+ //============================================================
289
+
290
+
291
+ return chart;
292
+ }
@@ -0,0 +1,674 @@
1
+
2
+ nv.models.scatter = function() {
3
+ "use strict";
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
+ , color = nv.utils.defaultColor() // chooses color
12
+ , id = Math.floor(Math.random() * 100000) //Create semi-unique ID incase user doesn't select one
13
+ , x = d3.scale.linear()
14
+ , y = d3.scale.linear()
15
+ , z = d3.scale.linear() //linear because d3.svg.shape.size is treated as area
16
+ , getX = function(d) { return d.x } // accessor to get the x value
17
+ , getY = function(d) { return d.y } // accessor to get the y value
18
+ , getSize = function(d) { return d.size || 1} // accessor to get the point size
19
+ , getShape = function(d) { return d.shape || 'circle' } // accessor to get point shape
20
+ , onlyCircles = true // Set to false to use shapes
21
+ , forceX = [] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.)
22
+ , forceY = [] // List of numbers to Force into the Y scale
23
+ , forceSize = [] // List of numbers to Force into the Size scale
24
+ , interactive = true // If true, plots a voronoi overlay for advanced point intersection
25
+ , pointKey = null
26
+ , pointActive = function(d) { return !d.notActive } // any points that return false will be filtered out
27
+ , padData = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart
28
+ , padDataOuter = .1 //outerPadding to imitate ordinal scale outer padding
29
+ , clipEdge = false // if true, masks points within x and y scale
30
+ , clipVoronoi = true // if true, masks each point with a circle... can turn off to slightly increase performance
31
+ , clipRadius = function() { return 25 } // function to get the radius for voronoi point clips
32
+ , xDomain = null // Override x domain (skips the calculation from data)
33
+ , yDomain = null // Override y domain
34
+ , xRange = null // Override x range
35
+ , yRange = null // Override y range
36
+ , sizeDomain = null // Override point size domain
37
+ , sizeRange = null
38
+ , singlePoint = false
39
+ , dispatch = d3.dispatch('elementClick', 'elementMouseover', 'elementMouseout')
40
+ , useVoronoi = true
41
+ ;
42
+
43
+ //============================================================
44
+
45
+
46
+ //============================================================
47
+ // Private Variables
48
+ //------------------------------------------------------------
49
+
50
+ var x0, y0, z0 // used to store previous scales
51
+ , timeoutID
52
+ , needsUpdate = false // Flag for when the points are visually updating, but the interactive layer is behind, to disable tooltips
53
+ ;
54
+
55
+ //============================================================
56
+
57
+
58
+ function chart(selection) {
59
+ selection.each(function(data) {
60
+ var availableWidth = width - margin.left - margin.right,
61
+ availableHeight = height - margin.top - margin.bottom,
62
+ container = d3.select(this);
63
+
64
+ //add series index to each data point for reference
65
+ data.forEach(function(series, i) {
66
+ series.values.forEach(function(point) {
67
+ point.series = i;
68
+ });
69
+ });
70
+
71
+ //------------------------------------------------------------
72
+ // Setup Scales
73
+
74
+ // remap and flatten the data for use in calculating the scales' domains
75
+ var seriesData = (xDomain && yDomain && sizeDomain) ? [] : // if we know xDomain and yDomain and sizeDomain, no need to calculate.... if Size is constant remember to set sizeDomain to speed up performance
76
+ d3.merge(
77
+ data.map(function(d) {
78
+ return d.values.map(function(d,i) {
79
+ return { x: getX(d,i), y: getY(d,i), size: getSize(d,i) }
80
+ })
81
+ })
82
+ );
83
+
84
+ x .domain(xDomain || d3.extent(seriesData.map(function(d) { return d.x; }).concat(forceX)))
85
+
86
+ if (padData && data[0])
87
+ x.range(xRange || [(availableWidth * padDataOuter + availableWidth) / (2 *data[0].values.length), availableWidth - availableWidth * (1 + padDataOuter) / (2 * data[0].values.length) ]);
88
+ //x.range([availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5) / data[0].values.length ]);
89
+ else
90
+ x.range(xRange || [0, availableWidth]);
91
+
92
+ y .domain(yDomain || d3.extent(seriesData.map(function(d) { return d.y }).concat(forceY)))
93
+ .range(yRange || [availableHeight, 0]);
94
+
95
+ z .domain(sizeDomain || d3.extent(seriesData.map(function(d) { return d.size }).concat(forceSize)))
96
+ .range(sizeRange || [16, 256]);
97
+
98
+ // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point
99
+ if (x.domain()[0] === x.domain()[1] || y.domain()[0] === y.domain()[1]) singlePoint = true;
100
+ if (x.domain()[0] === x.domain()[1])
101
+ x.domain()[0] ?
102
+ x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])
103
+ : x.domain([-1,1]);
104
+
105
+ if (y.domain()[0] === y.domain()[1])
106
+ y.domain()[0] ?
107
+ y.domain([y.domain()[0] - y.domain()[0] * 0.01, y.domain()[1] + y.domain()[1] * 0.01])
108
+ : y.domain([-1,1]);
109
+
110
+ if ( isNaN(x.domain()[0])) {
111
+ x.domain([-1,1]);
112
+ }
113
+
114
+ if ( isNaN(y.domain()[0])) {
115
+ y.domain([-1,1]);
116
+ }
117
+
118
+
119
+ x0 = x0 || x;
120
+ y0 = y0 || y;
121
+ z0 = z0 || z;
122
+
123
+ //------------------------------------------------------------
124
+
125
+
126
+ //------------------------------------------------------------
127
+ // Setup containers and skeleton of chart
128
+
129
+ var wrap = container.selectAll('g.nv-wrap.nv-scatter').data([data]);
130
+ var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-scatter nv-chart-' + id + (singlePoint ? ' nv-single-point' : ''));
131
+ var defsEnter = wrapEnter.append('defs');
132
+ var gEnter = wrapEnter.append('g');
133
+ var g = wrap.select('g');
134
+
135
+ gEnter.append('g').attr('class', 'nv-groups');
136
+ gEnter.append('g').attr('class', 'nv-point-paths');
137
+
138
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
139
+
140
+ //------------------------------------------------------------
141
+
142
+
143
+ defsEnter.append('clipPath')
144
+ .attr('id', 'nv-edge-clip-' + id)
145
+ .append('rect');
146
+
147
+ wrap.select('#nv-edge-clip-' + id + ' rect')
148
+ .attr('width', availableWidth)
149
+ .attr('height', availableHeight);
150
+
151
+ g .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : '');
152
+
153
+
154
+ function updateInteractiveLayer() {
155
+
156
+ if (!interactive) return false;
157
+
158
+ var eventElements;
159
+
160
+ var vertices = d3.merge(data.map(function(group, groupIndex) {
161
+ return group.values
162
+ .map(function(point, pointIndex) {
163
+ // *Adding noise to make duplicates very unlikely
164
+ // *Injecting series and point index for reference
165
+ /* *Adding a 'jitter' to the points, because there's an issue in d3.geom.voronoi.
166
+ */
167
+ var pX = getX(point,pointIndex);
168
+ var pY = getY(point,pointIndex);
169
+
170
+ return [x(pX)+ Math.random() * 1e-7,
171
+ y(pY)+ Math.random() * 1e-7,
172
+ groupIndex,
173
+ pointIndex, point]; //temp hack to add noise untill I think of a better way so there are no duplicates
174
+ })
175
+ .filter(function(pointArray, pointIndex) {
176
+ return pointActive(pointArray[4], pointIndex); // Issue #237.. move filter to after map, so pointIndex is correct!
177
+ })
178
+ })
179
+ );
180
+
181
+
182
+
183
+ //inject series and point index for reference into voronoi
184
+ if (useVoronoi === true) {
185
+
186
+ if (clipVoronoi) {
187
+ var pointClipsEnter = wrap.select('defs').selectAll('.nv-point-clips')
188
+ .data([id])
189
+ .enter();
190
+
191
+ pointClipsEnter.append('clipPath')
192
+ .attr('class', 'nv-point-clips')
193
+ .attr('id', 'nv-points-clip-' + id);
194
+
195
+ var pointClips = wrap.select('#nv-points-clip-' + id).selectAll('circle')
196
+ .data(vertices);
197
+ pointClips.enter().append('circle')
198
+ .attr('r', clipRadius);
199
+ pointClips.exit().remove();
200
+ pointClips
201
+ .attr('cx', function(d) { return d[0] })
202
+ .attr('cy', function(d) { return d[1] });
203
+
204
+ wrap.select('.nv-point-paths')
205
+ .attr('clip-path', 'url(#nv-points-clip-' + id + ')');
206
+ }
207
+
208
+
209
+ if(vertices.length) {
210
+ // Issue #283 - Adding 2 dummy points to the voronoi b/c voronoi requires min 3 points to work
211
+ vertices.push([x.range()[0] - 20, y.range()[0] - 20, null, null]);
212
+ vertices.push([x.range()[1] + 20, y.range()[1] + 20, null, null]);
213
+ vertices.push([x.range()[0] - 20, y.range()[0] + 20, null, null]);
214
+ vertices.push([x.range()[1] + 20, y.range()[1] - 20, null, null]);
215
+ }
216
+
217
+ var bounds = d3.geom.polygon([
218
+ [-10,-10],
219
+ [-10,height + 10],
220
+ [width + 10,height + 10],
221
+ [width + 10,-10]
222
+ ]);
223
+
224
+ var voronoi = d3.geom.voronoi(vertices).map(function(d, i) {
225
+ return {
226
+ 'data': bounds.clip(d),
227
+ 'series': vertices[i][2],
228
+ 'point': vertices[i][3]
229
+ }
230
+ });
231
+
232
+
233
+ var pointPaths = wrap.select('.nv-point-paths').selectAll('path')
234
+ .data(voronoi);
235
+ pointPaths.enter().append('path')
236
+ .attr('class', function(d,i) { return 'nv-path-'+i; });
237
+ pointPaths.exit().remove();
238
+ pointPaths
239
+ .attr('d', function(d) {
240
+ if (d.data.length === 0)
241
+ return 'M 0 0'
242
+ else
243
+ return 'M' + d.data.join('L') + 'Z';
244
+ });
245
+
246
+ var mouseEventCallback = function(d,mDispatch) {
247
+ if (needsUpdate) return 0;
248
+ var series = data[d.series];
249
+ if (typeof series === 'undefined') return;
250
+
251
+ var point = series.values[d.point];
252
+
253
+ mDispatch({
254
+ point: point,
255
+ series: series,
256
+ pos: [x(getX(point, d.point)) + margin.left, y(getY(point, d.point)) + margin.top],
257
+ seriesIndex: d.series,
258
+ pointIndex: d.point
259
+ });
260
+ };
261
+
262
+ pointPaths
263
+ .on('click', function(d) {
264
+ mouseEventCallback(d, dispatch.elementClick);
265
+ })
266
+ .on('mouseover', function(d) {
267
+ mouseEventCallback(d, dispatch.elementMouseover);
268
+ })
269
+ .on('mouseout', function(d, i) {
270
+ mouseEventCallback(d, dispatch.elementMouseout);
271
+ });
272
+
273
+
274
+ } else {
275
+ /*
276
+ // bring data in form needed for click handlers
277
+ var dataWithPoints = vertices.map(function(d, i) {
278
+ return {
279
+ 'data': d,
280
+ 'series': vertices[i][2],
281
+ 'point': vertices[i][3]
282
+ }
283
+ });
284
+ */
285
+
286
+ // add event handlers to points instead voronoi paths
287
+ wrap.select('.nv-groups').selectAll('.nv-group')
288
+ .selectAll('.nv-point')
289
+ //.data(dataWithPoints)
290
+ //.style('pointer-events', 'auto') // recativate events, disabled by css
291
+ .on('click', function(d,i) {
292
+ //nv.log('test', d, i);
293
+ if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy point
294
+ var series = data[d.series],
295
+ point = series.values[i];
296
+
297
+ dispatch.elementClick({
298
+ point: point,
299
+ series: series,
300
+ pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],
301
+ seriesIndex: d.series,
302
+ pointIndex: i
303
+ });
304
+ })
305
+ .on('mouseover', function(d,i) {
306
+ if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy point
307
+ var series = data[d.series],
308
+ point = series.values[i];
309
+
310
+ dispatch.elementMouseover({
311
+ point: point,
312
+ series: series,
313
+ pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],
314
+ seriesIndex: d.series,
315
+ pointIndex: i
316
+ });
317
+ })
318
+ .on('mouseout', function(d,i) {
319
+ if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy point
320
+ var series = data[d.series],
321
+ point = series.values[i];
322
+
323
+ dispatch.elementMouseout({
324
+ point: point,
325
+ series: series,
326
+ seriesIndex: d.series,
327
+ pointIndex: i
328
+ });
329
+ });
330
+ }
331
+
332
+ needsUpdate = false;
333
+ }
334
+
335
+ needsUpdate = true;
336
+
337
+ var groups = wrap.select('.nv-groups').selectAll('.nv-group')
338
+ .data(function(d) { return d }, function(d) { return d.key });
339
+ groups.enter().append('g')
340
+ .style('stroke-opacity', 1e-6)
341
+ .style('fill-opacity', 1e-6);
342
+ groups.exit()
343
+ .remove();
344
+ groups
345
+ .attr('class', function(d,i) { return 'nv-group nv-series-' + i })
346
+ .classed('hover', function(d) { return d.hover });
347
+ groups
348
+ .transition()
349
+ .style('fill', function(d,i) { return color(d, i) })
350
+ .style('stroke', function(d,i) { return color(d, i) })
351
+ .style('stroke-opacity', 1)
352
+ .style('fill-opacity', .5);
353
+
354
+
355
+ if (onlyCircles) {
356
+
357
+ var points = groups.selectAll('circle.nv-point')
358
+ .data(function(d) { return d.values }, pointKey);
359
+ points.enter().append('circle')
360
+ .style('fill', function (d,i) { return d.color })
361
+ .style('stroke', function (d,i) { return d.color })
362
+ .attr('cx', function(d,i) { return nv.utils.NaNtoZero(x0(getX(d,i))) })
363
+ .attr('cy', function(d,i) { return nv.utils.NaNtoZero(y0(getY(d,i))) })
364
+ .attr('r', function(d,i) { return Math.sqrt(z(getSize(d,i))/Math.PI) });
365
+ points.exit().remove();
366
+ groups.exit().selectAll('path.nv-point').transition()
367
+ .attr('cx', function(d,i) { return nv.utils.NaNtoZero(x(getX(d,i))) })
368
+ .attr('cy', function(d,i) { return nv.utils.NaNtoZero(y(getY(d,i))) })
369
+ .remove();
370
+ points.each(function(d,i) {
371
+ d3.select(this)
372
+ .classed('nv-point', true)
373
+ .classed('nv-point-' + i, true)
374
+ .classed('hover',false)
375
+ ;
376
+ });
377
+ points.transition()
378
+ .attr('cx', function(d,i) { return nv.utils.NaNtoZero(x(getX(d,i))) })
379
+ .attr('cy', function(d,i) { return nv.utils.NaNtoZero(y(getY(d,i))) })
380
+ .attr('r', function(d,i) { return Math.sqrt(z(getSize(d,i))/Math.PI) });
381
+
382
+ } else {
383
+
384
+ var points = groups.selectAll('path.nv-point')
385
+ .data(function(d) { return d.values });
386
+ points.enter().append('path')
387
+ .style('fill', function (d,i) { return d.color })
388
+ .style('stroke', function (d,i) { return d.color })
389
+ .attr('transform', function(d,i) {
390
+ return 'translate(' + x0(getX(d,i)) + ',' + y0(getY(d,i)) + ')'
391
+ })
392
+ .attr('d',
393
+ d3.svg.symbol()
394
+ .type(getShape)
395
+ .size(function(d,i) { return z(getSize(d,i)) })
396
+ );
397
+ points.exit().remove();
398
+ groups.exit().selectAll('path.nv-point')
399
+ .transition()
400
+ .attr('transform', function(d,i) {
401
+ return 'translate(' + x(getX(d,i)) + ',' + y(getY(d,i)) + ')'
402
+ })
403
+ .remove();
404
+ points.each(function(d,i) {
405
+ d3.select(this)
406
+ .classed('nv-point', true)
407
+ .classed('nv-point-' + i, true)
408
+ .classed('hover',false)
409
+ ;
410
+ });
411
+ points.transition()
412
+ .attr('transform', function(d,i) {
413
+ //nv.log(d,i,getX(d,i), x(getX(d,i)));
414
+ return 'translate(' + x(getX(d,i)) + ',' + y(getY(d,i)) + ')'
415
+ })
416
+ .attr('d',
417
+ d3.svg.symbol()
418
+ .type(getShape)
419
+ .size(function(d,i) { return z(getSize(d,i)) })
420
+ );
421
+ }
422
+
423
+
424
+ // Delay updating the invisible interactive layer for smoother animation
425
+ clearTimeout(timeoutID); // stop repeat calls to updateInteractiveLayer
426
+ timeoutID = setTimeout(updateInteractiveLayer, 300);
427
+ //updateInteractiveLayer();
428
+
429
+ //store old scales for use in transitions on update
430
+ x0 = x.copy();
431
+ y0 = y.copy();
432
+ z0 = z.copy();
433
+
434
+ });
435
+
436
+ return chart;
437
+ }
438
+
439
+
440
+ //============================================================
441
+ // Event Handling/Dispatching (out of chart's scope)
442
+ //------------------------------------------------------------
443
+ chart.clearHighlights = function() {
444
+ //Remove the 'hover' class from all highlighted points.
445
+ d3.selectAll(".nv-chart-" + id + " .nv-point.hover").classed("hover",false);
446
+ };
447
+
448
+ chart.highlightPoint = function(seriesIndex,pointIndex,isHoverOver) {
449
+ d3.select(".nv-chart-" + id + " .nv-series-" + seriesIndex + " .nv-point-" + pointIndex)
450
+ .classed("hover",isHoverOver);
451
+ };
452
+
453
+
454
+ dispatch.on('elementMouseover.point', function(d) {
455
+ if (interactive) chart.highlightPoint(d.seriesIndex,d.pointIndex,true);
456
+ });
457
+
458
+ dispatch.on('elementMouseout.point', function(d) {
459
+ if (interactive) chart.highlightPoint(d.seriesIndex,d.pointIndex,false);
460
+ });
461
+
462
+ //============================================================
463
+
464
+
465
+ //============================================================
466
+ // Expose Public Variables
467
+ //------------------------------------------------------------
468
+
469
+ chart.dispatch = dispatch;
470
+ chart.options = nv.utils.optionsFunc.bind(chart);
471
+
472
+ chart.x = function(_) {
473
+ if (!arguments.length) return getX;
474
+ getX = d3.functor(_);
475
+ return chart;
476
+ };
477
+
478
+ chart.y = function(_) {
479
+ if (!arguments.length) return getY;
480
+ getY = d3.functor(_);
481
+ return chart;
482
+ };
483
+
484
+ chart.size = function(_) {
485
+ if (!arguments.length) return getSize;
486
+ getSize = d3.functor(_);
487
+ return chart;
488
+ };
489
+
490
+ chart.margin = function(_) {
491
+ if (!arguments.length) return margin;
492
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
493
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
494
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
495
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
496
+ return chart;
497
+ };
498
+
499
+ chart.width = function(_) {
500
+ if (!arguments.length) return width;
501
+ width = _;
502
+ return chart;
503
+ };
504
+
505
+ chart.height = function(_) {
506
+ if (!arguments.length) return height;
507
+ height = _;
508
+ return chart;
509
+ };
510
+
511
+ chart.xScale = function(_) {
512
+ if (!arguments.length) return x;
513
+ x = _;
514
+ return chart;
515
+ };
516
+
517
+ chart.yScale = function(_) {
518
+ if (!arguments.length) return y;
519
+ y = _;
520
+ return chart;
521
+ };
522
+
523
+ chart.zScale = function(_) {
524
+ if (!arguments.length) return z;
525
+ z = _;
526
+ return chart;
527
+ };
528
+
529
+ chart.xDomain = function(_) {
530
+ if (!arguments.length) return xDomain;
531
+ xDomain = _;
532
+ return chart;
533
+ };
534
+
535
+ chart.yDomain = function(_) {
536
+ if (!arguments.length) return yDomain;
537
+ yDomain = _;
538
+ return chart;
539
+ };
540
+
541
+ chart.sizeDomain = function(_) {
542
+ if (!arguments.length) return sizeDomain;
543
+ sizeDomain = _;
544
+ return chart;
545
+ };
546
+
547
+ chart.xRange = function(_) {
548
+ if (!arguments.length) return xRange;
549
+ xRange = _;
550
+ return chart;
551
+ };
552
+
553
+ chart.yRange = function(_) {
554
+ if (!arguments.length) return yRange;
555
+ yRange = _;
556
+ return chart;
557
+ };
558
+
559
+ chart.sizeRange = function(_) {
560
+ if (!arguments.length) return sizeRange;
561
+ sizeRange = _;
562
+ return chart;
563
+ };
564
+
565
+ chart.forceX = function(_) {
566
+ if (!arguments.length) return forceX;
567
+ forceX = _;
568
+ return chart;
569
+ };
570
+
571
+ chart.forceY = function(_) {
572
+ if (!arguments.length) return forceY;
573
+ forceY = _;
574
+ return chart;
575
+ };
576
+
577
+ chart.forceSize = function(_) {
578
+ if (!arguments.length) return forceSize;
579
+ forceSize = _;
580
+ return chart;
581
+ };
582
+
583
+ chart.interactive = function(_) {
584
+ if (!arguments.length) return interactive;
585
+ interactive = _;
586
+ return chart;
587
+ };
588
+
589
+ chart.pointKey = function(_) {
590
+ if (!arguments.length) return pointKey;
591
+ pointKey = _;
592
+ return chart;
593
+ };
594
+
595
+ chart.pointActive = function(_) {
596
+ if (!arguments.length) return pointActive;
597
+ pointActive = _;
598
+ return chart;
599
+ };
600
+
601
+ chart.padData = function(_) {
602
+ if (!arguments.length) return padData;
603
+ padData = _;
604
+ return chart;
605
+ };
606
+
607
+ chart.padDataOuter = function(_) {
608
+ if (!arguments.length) return padDataOuter;
609
+ padDataOuter = _;
610
+ return chart;
611
+ };
612
+
613
+ chart.clipEdge = function(_) {
614
+ if (!arguments.length) return clipEdge;
615
+ clipEdge = _;
616
+ return chart;
617
+ };
618
+
619
+ chart.clipVoronoi= function(_) {
620
+ if (!arguments.length) return clipVoronoi;
621
+ clipVoronoi = _;
622
+ return chart;
623
+ };
624
+
625
+ chart.useVoronoi= function(_) {
626
+ if (!arguments.length) return useVoronoi;
627
+ useVoronoi = _;
628
+ if (useVoronoi === false) {
629
+ clipVoronoi = false;
630
+ }
631
+ return chart;
632
+ };
633
+
634
+ chart.clipRadius = function(_) {
635
+ if (!arguments.length) return clipRadius;
636
+ clipRadius = _;
637
+ return chart;
638
+ };
639
+
640
+ chart.color = function(_) {
641
+ if (!arguments.length) return color;
642
+ color = nv.utils.getColor(_);
643
+ return chart;
644
+ };
645
+
646
+ chart.shape = function(_) {
647
+ if (!arguments.length) return getShape;
648
+ getShape = _;
649
+ return chart;
650
+ };
651
+
652
+ chart.onlyCircles = function(_) {
653
+ if (!arguments.length) return onlyCircles;
654
+ onlyCircles = _;
655
+ return chart;
656
+ };
657
+
658
+ chart.id = function(_) {
659
+ if (!arguments.length) return id;
660
+ id = _;
661
+ return chart;
662
+ };
663
+
664
+ chart.singlePoint = function(_) {
665
+ if (!arguments.length) return singlePoint;
666
+ singlePoint = _;
667
+ return chart;
668
+ };
669
+
670
+ //============================================================
671
+
672
+
673
+ return chart;
674
+ }