pyk 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
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,302 @@
1
+ // This product includes color specifications and designs developed by Cynthia Brewer (http://colorbrewer.org/).
2
+ var colorbrewer = {YlGn: {
3
+ 3: ["#f7fcb9","#addd8e","#31a354"],
4
+ 4: ["#ffffcc","#c2e699","#78c679","#238443"],
5
+ 5: ["#ffffcc","#c2e699","#78c679","#31a354","#006837"],
6
+ 6: ["#ffffcc","#d9f0a3","#addd8e","#78c679","#31a354","#006837"],
7
+ 7: ["#ffffcc","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#005a32"],
8
+ 8: ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#005a32"],
9
+ 9: ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"]
10
+ },YlGnBu: {
11
+ 3: ["#edf8b1","#7fcdbb","#2c7fb8"],
12
+ 4: ["#ffffcc","#a1dab4","#41b6c4","#225ea8"],
13
+ 5: ["#ffffcc","#a1dab4","#41b6c4","#2c7fb8","#253494"],
14
+ 6: ["#ffffcc","#c7e9b4","#7fcdbb","#41b6c4","#2c7fb8","#253494"],
15
+ 7: ["#ffffcc","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#0c2c84"],
16
+ 8: ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#0c2c84"],
17
+ 9: ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"]
18
+ },GnBu: {
19
+ 3: ["#e0f3db","#a8ddb5","#43a2ca"],
20
+ 4: ["#f0f9e8","#bae4bc","#7bccc4","#2b8cbe"],
21
+ 5: ["#f0f9e8","#bae4bc","#7bccc4","#43a2ca","#0868ac"],
22
+ 6: ["#f0f9e8","#ccebc5","#a8ddb5","#7bccc4","#43a2ca","#0868ac"],
23
+ 7: ["#f0f9e8","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#08589e"],
24
+ 8: ["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#08589e"],
25
+ 9: ["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"]
26
+ },BuGn: {
27
+ 3: ["#e5f5f9","#99d8c9","#2ca25f"],
28
+ 4: ["#edf8fb","#b2e2e2","#66c2a4","#238b45"],
29
+ 5: ["#edf8fb","#b2e2e2","#66c2a4","#2ca25f","#006d2c"],
30
+ 6: ["#edf8fb","#ccece6","#99d8c9","#66c2a4","#2ca25f","#006d2c"],
31
+ 7: ["#edf8fb","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#005824"],
32
+ 8: ["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#005824"],
33
+ 9: ["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"]
34
+ },PuBuGn: {
35
+ 3: ["#ece2f0","#a6bddb","#1c9099"],
36
+ 4: ["#f6eff7","#bdc9e1","#67a9cf","#02818a"],
37
+ 5: ["#f6eff7","#bdc9e1","#67a9cf","#1c9099","#016c59"],
38
+ 6: ["#f6eff7","#d0d1e6","#a6bddb","#67a9cf","#1c9099","#016c59"],
39
+ 7: ["#f6eff7","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016450"],
40
+ 8: ["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016450"],
41
+ 9: ["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"]
42
+ },PuBu: {
43
+ 3: ["#ece7f2","#a6bddb","#2b8cbe"],
44
+ 4: ["#f1eef6","#bdc9e1","#74a9cf","#0570b0"],
45
+ 5: ["#f1eef6","#bdc9e1","#74a9cf","#2b8cbe","#045a8d"],
46
+ 6: ["#f1eef6","#d0d1e6","#a6bddb","#74a9cf","#2b8cbe","#045a8d"],
47
+ 7: ["#f1eef6","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#034e7b"],
48
+ 8: ["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#034e7b"],
49
+ 9: ["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"]
50
+ },BuPu: {
51
+ 3: ["#e0ecf4","#9ebcda","#8856a7"],
52
+ 4: ["#edf8fb","#b3cde3","#8c96c6","#88419d"],
53
+ 5: ["#edf8fb","#b3cde3","#8c96c6","#8856a7","#810f7c"],
54
+ 6: ["#edf8fb","#bfd3e6","#9ebcda","#8c96c6","#8856a7","#810f7c"],
55
+ 7: ["#edf8fb","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#6e016b"],
56
+ 8: ["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#6e016b"],
57
+ 9: ["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"]
58
+ },RdPu: {
59
+ 3: ["#fde0dd","#fa9fb5","#c51b8a"],
60
+ 4: ["#feebe2","#fbb4b9","#f768a1","#ae017e"],
61
+ 5: ["#feebe2","#fbb4b9","#f768a1","#c51b8a","#7a0177"],
62
+ 6: ["#feebe2","#fcc5c0","#fa9fb5","#f768a1","#c51b8a","#7a0177"],
63
+ 7: ["#feebe2","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177"],
64
+ 8: ["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177"],
65
+ 9: ["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"]
66
+ },PuRd: {
67
+ 3: ["#e7e1ef","#c994c7","#dd1c77"],
68
+ 4: ["#f1eef6","#d7b5d8","#df65b0","#ce1256"],
69
+ 5: ["#f1eef6","#d7b5d8","#df65b0","#dd1c77","#980043"],
70
+ 6: ["#f1eef6","#d4b9da","#c994c7","#df65b0","#dd1c77","#980043"],
71
+ 7: ["#f1eef6","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#91003f"],
72
+ 8: ["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#91003f"],
73
+ 9: ["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"]
74
+ },OrRd: {
75
+ 3: ["#fee8c8","#fdbb84","#e34a33"],
76
+ 4: ["#fef0d9","#fdcc8a","#fc8d59","#d7301f"],
77
+ 5: ["#fef0d9","#fdcc8a","#fc8d59","#e34a33","#b30000"],
78
+ 6: ["#fef0d9","#fdd49e","#fdbb84","#fc8d59","#e34a33","#b30000"],
79
+ 7: ["#fef0d9","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#990000"],
80
+ 8: ["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#990000"],
81
+ 9: ["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"]
82
+ },YlOrRd: {
83
+ 3: ["#ffeda0","#feb24c","#f03b20"],
84
+ 4: ["#ffffb2","#fecc5c","#fd8d3c","#e31a1c"],
85
+ 5: ["#ffffb2","#fecc5c","#fd8d3c","#f03b20","#bd0026"],
86
+ 6: ["#ffffb2","#fed976","#feb24c","#fd8d3c","#f03b20","#bd0026"],
87
+ 7: ["#ffffb2","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#b10026"],
88
+ 8: ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#b10026"],
89
+ 9: ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"]
90
+ },YlOrBr: {
91
+ 3: ["#fff7bc","#fec44f","#d95f0e"],
92
+ 4: ["#ffffd4","#fed98e","#fe9929","#cc4c02"],
93
+ 5: ["#ffffd4","#fed98e","#fe9929","#d95f0e","#993404"],
94
+ 6: ["#ffffd4","#fee391","#fec44f","#fe9929","#d95f0e","#993404"],
95
+ 7: ["#ffffd4","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#8c2d04"],
96
+ 8: ["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#8c2d04"],
97
+ 9: ["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"]
98
+ },Purples: {
99
+ 3: ["#efedf5","#bcbddc","#756bb1"],
100
+ 4: ["#f2f0f7","#cbc9e2","#9e9ac8","#6a51a3"],
101
+ 5: ["#f2f0f7","#cbc9e2","#9e9ac8","#756bb1","#54278f"],
102
+ 6: ["#f2f0f7","#dadaeb","#bcbddc","#9e9ac8","#756bb1","#54278f"],
103
+ 7: ["#f2f0f7","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#4a1486"],
104
+ 8: ["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#4a1486"],
105
+ 9: ["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"]
106
+ },Blues: {
107
+ 3: ["#deebf7","#9ecae1","#3182bd"],
108
+ 4: ["#eff3ff","#bdd7e7","#6baed6","#2171b5"],
109
+ 5: ["#eff3ff","#bdd7e7","#6baed6","#3182bd","#08519c"],
110
+ 6: ["#eff3ff","#c6dbef","#9ecae1","#6baed6","#3182bd","#08519c"],
111
+ 7: ["#eff3ff","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#084594"],
112
+ 8: ["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#084594"],
113
+ 9: ["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"]
114
+ },Greens: {
115
+ 3: ["#e5f5e0","#a1d99b","#31a354"],
116
+ 4: ["#edf8e9","#bae4b3","#74c476","#238b45"],
117
+ 5: ["#edf8e9","#bae4b3","#74c476","#31a354","#006d2c"],
118
+ 6: ["#edf8e9","#c7e9c0","#a1d99b","#74c476","#31a354","#006d2c"],
119
+ 7: ["#edf8e9","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#005a32"],
120
+ 8: ["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#005a32"],
121
+ 9: ["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"]
122
+ },Oranges: {
123
+ 3: ["#fee6ce","#fdae6b","#e6550d"],
124
+ 4: ["#feedde","#fdbe85","#fd8d3c","#d94701"],
125
+ 5: ["#feedde","#fdbe85","#fd8d3c","#e6550d","#a63603"],
126
+ 6: ["#feedde","#fdd0a2","#fdae6b","#fd8d3c","#e6550d","#a63603"],
127
+ 7: ["#feedde","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#8c2d04"],
128
+ 8: ["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#8c2d04"],
129
+ 9: ["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"]
130
+ },Reds: {
131
+ 3: ["#fee0d2","#fc9272","#de2d26"],
132
+ 4: ["#fee5d9","#fcae91","#fb6a4a","#cb181d"],
133
+ 5: ["#fee5d9","#fcae91","#fb6a4a","#de2d26","#a50f15"],
134
+ 6: ["#fee5d9","#fcbba1","#fc9272","#fb6a4a","#de2d26","#a50f15"],
135
+ 7: ["#fee5d9","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#99000d"],
136
+ 8: ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#99000d"],
137
+ 9: ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"]
138
+ },Greys: {
139
+ 3: ["#f0f0f0","#bdbdbd","#636363"],
140
+ 4: ["#f7f7f7","#cccccc","#969696","#525252"],
141
+ 5: ["#f7f7f7","#cccccc","#969696","#636363","#252525"],
142
+ 6: ["#f7f7f7","#d9d9d9","#bdbdbd","#969696","#636363","#252525"],
143
+ 7: ["#f7f7f7","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525"],
144
+ 8: ["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525"],
145
+ 9: ["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"]
146
+ },PuOr: {
147
+ 3: ["#f1a340","#f7f7f7","#998ec3"],
148
+ 4: ["#e66101","#fdb863","#b2abd2","#5e3c99"],
149
+ 5: ["#e66101","#fdb863","#f7f7f7","#b2abd2","#5e3c99"],
150
+ 6: ["#b35806","#f1a340","#fee0b6","#d8daeb","#998ec3","#542788"],
151
+ 7: ["#b35806","#f1a340","#fee0b6","#f7f7f7","#d8daeb","#998ec3","#542788"],
152
+ 8: ["#b35806","#e08214","#fdb863","#fee0b6","#d8daeb","#b2abd2","#8073ac","#542788"],
153
+ 9: ["#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788"],
154
+ 10: ["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],
155
+ 11: ["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"]
156
+ },BrBG: {
157
+ 3: ["#d8b365","#f5f5f5","#5ab4ac"],
158
+ 4: ["#a6611a","#dfc27d","#80cdc1","#018571"],
159
+ 5: ["#a6611a","#dfc27d","#f5f5f5","#80cdc1","#018571"],
160
+ 6: ["#8c510a","#d8b365","#f6e8c3","#c7eae5","#5ab4ac","#01665e"],
161
+ 7: ["#8c510a","#d8b365","#f6e8c3","#f5f5f5","#c7eae5","#5ab4ac","#01665e"],
162
+ 8: ["#8c510a","#bf812d","#dfc27d","#f6e8c3","#c7eae5","#80cdc1","#35978f","#01665e"],
163
+ 9: ["#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e"],
164
+ 10: ["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],
165
+ 11: ["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"]
166
+ },PRGn: {
167
+ 3: ["#af8dc3","#f7f7f7","#7fbf7b"],
168
+ 4: ["#7b3294","#c2a5cf","#a6dba0","#008837"],
169
+ 5: ["#7b3294","#c2a5cf","#f7f7f7","#a6dba0","#008837"],
170
+ 6: ["#762a83","#af8dc3","#e7d4e8","#d9f0d3","#7fbf7b","#1b7837"],
171
+ 7: ["#762a83","#af8dc3","#e7d4e8","#f7f7f7","#d9f0d3","#7fbf7b","#1b7837"],
172
+ 8: ["#762a83","#9970ab","#c2a5cf","#e7d4e8","#d9f0d3","#a6dba0","#5aae61","#1b7837"],
173
+ 9: ["#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837"],
174
+ 10: ["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],
175
+ 11: ["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"]
176
+ },PiYG: {
177
+ 3: ["#e9a3c9","#f7f7f7","#a1d76a"],
178
+ 4: ["#d01c8b","#f1b6da","#b8e186","#4dac26"],
179
+ 5: ["#d01c8b","#f1b6da","#f7f7f7","#b8e186","#4dac26"],
180
+ 6: ["#c51b7d","#e9a3c9","#fde0ef","#e6f5d0","#a1d76a","#4d9221"],
181
+ 7: ["#c51b7d","#e9a3c9","#fde0ef","#f7f7f7","#e6f5d0","#a1d76a","#4d9221"],
182
+ 8: ["#c51b7d","#de77ae","#f1b6da","#fde0ef","#e6f5d0","#b8e186","#7fbc41","#4d9221"],
183
+ 9: ["#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221"],
184
+ 10: ["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],
185
+ 11: ["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"]
186
+ },RdBu: {
187
+ 3: ["#ef8a62","#f7f7f7","#67a9cf"],
188
+ 4: ["#ca0020","#f4a582","#92c5de","#0571b0"],
189
+ 5: ["#ca0020","#f4a582","#f7f7f7","#92c5de","#0571b0"],
190
+ 6: ["#b2182b","#ef8a62","#fddbc7","#d1e5f0","#67a9cf","#2166ac"],
191
+ 7: ["#b2182b","#ef8a62","#fddbc7","#f7f7f7","#d1e5f0","#67a9cf","#2166ac"],
192
+ 8: ["#b2182b","#d6604d","#f4a582","#fddbc7","#d1e5f0","#92c5de","#4393c3","#2166ac"],
193
+ 9: ["#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac"],
194
+ 10: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],
195
+ 11: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"]
196
+ },RdGy: {
197
+ 3: ["#ef8a62","#ffffff","#999999"],
198
+ 4: ["#ca0020","#f4a582","#bababa","#404040"],
199
+ 5: ["#ca0020","#f4a582","#ffffff","#bababa","#404040"],
200
+ 6: ["#b2182b","#ef8a62","#fddbc7","#e0e0e0","#999999","#4d4d4d"],
201
+ 7: ["#b2182b","#ef8a62","#fddbc7","#ffffff","#e0e0e0","#999999","#4d4d4d"],
202
+ 8: ["#b2182b","#d6604d","#f4a582","#fddbc7","#e0e0e0","#bababa","#878787","#4d4d4d"],
203
+ 9: ["#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d"],
204
+ 10: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],
205
+ 11: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"]
206
+ },RdYlBu: {
207
+ 3: ["#fc8d59","#ffffbf","#91bfdb"],
208
+ 4: ["#d7191c","#fdae61","#abd9e9","#2c7bb6"],
209
+ 5: ["#d7191c","#fdae61","#ffffbf","#abd9e9","#2c7bb6"],
210
+ 6: ["#d73027","#fc8d59","#fee090","#e0f3f8","#91bfdb","#4575b4"],
211
+ 7: ["#d73027","#fc8d59","#fee090","#ffffbf","#e0f3f8","#91bfdb","#4575b4"],
212
+ 8: ["#d73027","#f46d43","#fdae61","#fee090","#e0f3f8","#abd9e9","#74add1","#4575b4"],
213
+ 9: ["#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4"],
214
+ 10: ["#a50026","#d73027","#f46d43","#fdae61","#fee090","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],
215
+ 11: ["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"]
216
+ },Spectral: {
217
+ 3: ["#fc8d59","#ffffbf","#99d594"],
218
+ 4: ["#d7191c","#fdae61","#abdda4","#2b83ba"],
219
+ 5: ["#d7191c","#fdae61","#ffffbf","#abdda4","#2b83ba"],
220
+ 6: ["#d53e4f","#fc8d59","#fee08b","#e6f598","#99d594","#3288bd"],
221
+ 7: ["#d53e4f","#fc8d59","#fee08b","#ffffbf","#e6f598","#99d594","#3288bd"],
222
+ 8: ["#d53e4f","#f46d43","#fdae61","#fee08b","#e6f598","#abdda4","#66c2a5","#3288bd"],
223
+ 9: ["#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd"],
224
+ 10: ["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],
225
+ 11: ["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"]
226
+ },RdYlGn: {
227
+ 3: ["#fc8d59","#ffffbf","#91cf60"],
228
+ 4: ["#d7191c","#fdae61","#a6d96a","#1a9641"],
229
+ 5: ["#d7191c","#fdae61","#ffffbf","#a6d96a","#1a9641"],
230
+ 6: ["#d73027","#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"],
231
+ 7: ["#d73027","#fc8d59","#fee08b","#ffffbf","#d9ef8b","#91cf60","#1a9850"],
232
+ 8: ["#d73027","#f46d43","#fdae61","#fee08b","#d9ef8b","#a6d96a","#66bd63","#1a9850"],
233
+ 9: ["#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850"],
234
+ 10: ["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],
235
+ 11: ["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"]
236
+ },Accent: {
237
+ 3: ["#7fc97f","#beaed4","#fdc086"],
238
+ 4: ["#7fc97f","#beaed4","#fdc086","#ffff99"],
239
+ 5: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0"],
240
+ 6: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f"],
241
+ 7: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17"],
242
+ 8: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"]
243
+ },Dark2: {
244
+ 3: ["#1b9e77","#d95f02","#7570b3"],
245
+ 4: ["#1b9e77","#d95f02","#7570b3","#e7298a"],
246
+ 5: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e"],
247
+ 6: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02"],
248
+ 7: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d"],
249
+ 8: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"]
250
+ },Paired: {
251
+ 3: ["#a6cee3","#1f78b4","#b2df8a"],
252
+ 4: ["#a6cee3","#1f78b4","#b2df8a","#33a02c"],
253
+ 5: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99"],
254
+ 6: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c"],
255
+ 7: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f"],
256
+ 8: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00"],
257
+ 9: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6"],
258
+ 10: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a"],
259
+ 11: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99"],
260
+ 12: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"]
261
+ },Pastel1: {
262
+ 3: ["#fbb4ae","#b3cde3","#ccebc5"],
263
+ 4: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4"],
264
+ 5: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6"],
265
+ 6: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc"],
266
+ 7: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd"],
267
+ 8: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec"],
268
+ 9: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]
269
+ },Pastel2: {
270
+ 3: ["#b3e2cd","#fdcdac","#cbd5e8"],
271
+ 4: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4"],
272
+ 5: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9"],
273
+ 6: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae"],
274
+ 7: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc"],
275
+ 8: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"]
276
+ },Set1: {
277
+ 3: ["#e41a1c","#377eb8","#4daf4a"],
278
+ 4: ["#e41a1c","#377eb8","#4daf4a","#984ea3"],
279
+ 5: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00"],
280
+ 6: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33"],
281
+ 7: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628"],
282
+ 8: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf"],
283
+ 9: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"]
284
+ },Set2: {
285
+ 3: ["#66c2a5","#fc8d62","#8da0cb"],
286
+ 4: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3"],
287
+ 5: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854"],
288
+ 6: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f"],
289
+ 7: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494"],
290
+ 8: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"]
291
+ },Set3: {
292
+ 3: ["#8dd3c7","#ffffb3","#bebada"],
293
+ 4: ["#8dd3c7","#ffffb3","#bebada","#fb8072"],
294
+ 5: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3"],
295
+ 6: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462"],
296
+ 7: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69"],
297
+ 8: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5"],
298
+ 9: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9"],
299
+ 10: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd"],
300
+ 11: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5"],
301
+ 12: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"]
302
+ }};
@@ -0,0 +1,1180 @@
1
+ (function(exports){
2
+ crossfilter.version = "1.0.3";
3
+ function crossfilter_identity(d) {
4
+ return d;
5
+ }
6
+ crossfilter.permute = permute;
7
+
8
+ function permute(array, index) {
9
+ for (var i = 0, n = index.length, copy = new Array(n); i < n; ++i) {
10
+ copy[i] = array[index[i]];
11
+ }
12
+ return copy;
13
+ }
14
+ var bisect = crossfilter.bisect = bisect_by(crossfilter_identity);
15
+
16
+ bisect.by = bisect_by;
17
+
18
+ function bisect_by(f) {
19
+
20
+ // Locate the insertion point for x in a to maintain sorted order. The
21
+ // arguments lo and hi may be used to specify a subset of the array which
22
+ // should be considered; by default the entire array is used. If x is already
23
+ // present in a, the insertion point will be before (to the left of) any
24
+ // existing entries. The return value is suitable for use as the first
25
+ // argument to `array.splice` assuming that a is already sorted.
26
+ //
27
+ // The returned insertion point i partitions the array a into two halves so
28
+ // that all v < x for v in a[lo:i] for the left side and all v >= x for v in
29
+ // a[i:hi] for the right side.
30
+ function bisectLeft(a, x, lo, hi) {
31
+ while (lo < hi) {
32
+ var mid = lo + hi >> 1;
33
+ if (f(a[mid]) < x) lo = mid + 1;
34
+ else hi = mid;
35
+ }
36
+ return lo;
37
+ }
38
+
39
+ // Similar to bisectLeft, but returns an insertion point which comes after (to
40
+ // the right of) any existing entries of x in a.
41
+ //
42
+ // The returned insertion point i partitions the array into two halves so that
43
+ // all v <= x for v in a[lo:i] for the left side and all v > x for v in
44
+ // a[i:hi] for the right side.
45
+ function bisectRight(a, x, lo, hi) {
46
+ while (lo < hi) {
47
+ var mid = lo + hi >> 1;
48
+ if (x < f(a[mid])) hi = mid;
49
+ else lo = mid + 1;
50
+ }
51
+ return lo;
52
+ }
53
+
54
+ bisectRight.right = bisectRight;
55
+ bisectRight.left = bisectLeft;
56
+ return bisectRight;
57
+ }
58
+ var heap = crossfilter.heap = heap_by(crossfilter_identity);
59
+
60
+ heap.by = heap_by;
61
+
62
+ function heap_by(f) {
63
+
64
+ // Builds a binary heap within the specified array a[lo:hi]. The heap has the
65
+ // property such that the parent a[lo+i] is always less than or equal to its
66
+ // two children: a[lo+2*i+1] and a[lo+2*i+2].
67
+ function heap(a, lo, hi) {
68
+ var n = hi - lo,
69
+ i = (n >>> 1) + 1;
70
+ while (--i > 0) sift(a, i, n, lo);
71
+ return a;
72
+ }
73
+
74
+ // Sorts the specified array a[lo:hi] in descending order, assuming it is
75
+ // already a heap.
76
+ function sort(a, lo, hi) {
77
+ var n = hi - lo,
78
+ t;
79
+ while (--n > 0) t = a[lo], a[lo] = a[lo + n], a[lo + n] = t, sift(a, 1, n, lo);
80
+ return a;
81
+ }
82
+
83
+ // Sifts the element a[lo+i-1] down the heap, where the heap is the contiguous
84
+ // slice of array a[lo:lo+n]. This method can also be used to update the heap
85
+ // incrementally, without incurring the full cost of reconstructing the heap.
86
+ function sift(a, i, n, lo) {
87
+ var d = a[--lo + i],
88
+ x = f(d),
89
+ child;
90
+ while ((child = i << 1) <= n) {
91
+ if (child < n && f(a[lo + child]) > f(a[lo + child + 1])) child++;
92
+ if (x <= f(a[lo + child])) break;
93
+ a[lo + i] = a[lo + child];
94
+ i = child;
95
+ }
96
+ a[lo + i] = d;
97
+ }
98
+
99
+ heap.sort = sort;
100
+ return heap;
101
+ }
102
+ var heapselect = crossfilter.heapselect = heapselect_by(crossfilter_identity);
103
+
104
+ heapselect.by = heapselect_by;
105
+
106
+ function heapselect_by(f) {
107
+ var heap = heap_by(f);
108
+
109
+ // Returns a new array containing the top k elements in the array a[lo:hi].
110
+ // The returned array is not sorted, but maintains the heap property. If k is
111
+ // greater than hi - lo, then fewer than k elements will be returned. The
112
+ // order of elements in a is unchanged by this operation.
113
+ function heapselect(a, lo, hi, k) {
114
+ var queue = new Array(k = Math.min(hi - lo, k)),
115
+ min,
116
+ i,
117
+ x,
118
+ d;
119
+
120
+ for (i = 0; i < k; ++i) queue[i] = a[lo++];
121
+ heap(queue, 0, k);
122
+
123
+ if (lo < hi) {
124
+ min = f(queue[0]);
125
+ do {
126
+ if (x = f(d = a[lo]) > min) {
127
+ queue[0] = d;
128
+ min = f(heap(queue, 0, k)[0]);
129
+ }
130
+ } while (++lo < hi);
131
+ }
132
+
133
+ return queue;
134
+ }
135
+
136
+ return heapselect;
137
+ }
138
+ var insertionsort = crossfilter.insertionsort = insertionsort_by(crossfilter_identity);
139
+
140
+ insertionsort.by = insertionsort_by;
141
+
142
+ function insertionsort_by(f) {
143
+
144
+ function insertionsort(a, lo, hi) {
145
+ for (var i = lo + 1; i < hi; ++i) {
146
+ for (var j = i, t = a[i], x = f(t); j > lo && f(a[j - 1]) > x; --j) {
147
+ a[j] = a[j - 1];
148
+ }
149
+ a[j] = t;
150
+ }
151
+ return a;
152
+ }
153
+
154
+ return insertionsort;
155
+ }
156
+ // Algorithm designed by Vladimir Yaroslavskiy.
157
+ // Implementation based on the Dart project; see lib/dart/LICENSE for details.
158
+
159
+ var quicksort = crossfilter.quicksort = quicksort_by(crossfilter_identity);
160
+
161
+ quicksort.by = quicksort_by;
162
+
163
+ function quicksort_by(f) {
164
+ var insertionsort = insertionsort_by(f);
165
+
166
+ function sort(a, lo, hi) {
167
+ return (hi - lo < quicksort_sizeThreshold
168
+ ? insertionsort
169
+ : quicksort)(a, lo, hi);
170
+ }
171
+
172
+ function quicksort(a, lo, hi) {
173
+
174
+ // Compute the two pivots by looking at 5 elements.
175
+ var sixth = (hi - lo) / 6 | 0,
176
+ i1 = lo + sixth,
177
+ i5 = hi - 1 - sixth,
178
+ i3 = lo + hi - 1 >> 1, // The midpoint.
179
+ i2 = i3 - sixth,
180
+ i4 = i3 + sixth;
181
+
182
+ var e1 = a[i1], x1 = f(e1),
183
+ e2 = a[i2], x2 = f(e2),
184
+ e3 = a[i3], x3 = f(e3),
185
+ e4 = a[i4], x4 = f(e4),
186
+ e5 = a[i5], x5 = f(e5);
187
+
188
+ var t;
189
+
190
+ // Sort the selected 5 elements using a sorting network.
191
+ if (x1 > x2) t = e1, e1 = e2, e2 = t, t = x1, x1 = x2, x2 = t;
192
+ if (x4 > x5) t = e4, e4 = e5, e5 = t, t = x4, x4 = x5, x5 = t;
193
+ if (x1 > x3) t = e1, e1 = e3, e3 = t, t = x1, x1 = x3, x3 = t;
194
+ if (x2 > x3) t = e2, e2 = e3, e3 = t, t = x2, x2 = x3, x3 = t;
195
+ if (x1 > x4) t = e1, e1 = e4, e4 = t, t = x1, x1 = x4, x4 = t;
196
+ if (x3 > x4) t = e3, e3 = e4, e4 = t, t = x3, x3 = x4, x4 = t;
197
+ if (x2 > x5) t = e2, e2 = e5, e5 = t, t = x2, x2 = x5, x5 = t;
198
+ if (x2 > x3) t = e2, e2 = e3, e3 = t, t = x2, x2 = x3, x3 = t;
199
+ if (x4 > x5) t = e4, e4 = e5, e5 = t, t = x4, x4 = x5, x5 = t;
200
+
201
+ var pivot1 = e2, pivotValue1 = x2,
202
+ pivot2 = e4, pivotValue2 = x4;
203
+
204
+ // e2 and e4 have been saved in the pivot variables. They will be written
205
+ // back, once the partitioning is finished.
206
+ a[i1] = e1;
207
+ a[i2] = a[lo];
208
+ a[i3] = e3;
209
+ a[i4] = a[hi - 1];
210
+ a[i5] = e5;
211
+
212
+ var less = lo + 1, // First element in the middle partition.
213
+ great = hi - 2; // Last element in the middle partition.
214
+
215
+ // Note that for value comparison, <, <=, >= and > coerce to a primitive via
216
+ // Object.prototype.valueOf; == and === do not, so in order to be consistent
217
+ // with natural order (such as for Date objects), we must do two compares.
218
+ var pivotsEqual = pivotValue1 <= pivotValue2 && pivotValue1 >= pivotValue2;
219
+ if (pivotsEqual) {
220
+
221
+ // Degenerated case where the partitioning becomes a dutch national flag
222
+ // problem.
223
+ //
224
+ // [ | < pivot | == pivot | unpartitioned | > pivot | ]
225
+ // ^ ^ ^ ^ ^
226
+ // left less k great right
227
+ //
228
+ // a[left] and a[right] are undefined and are filled after the
229
+ // partitioning.
230
+ //
231
+ // Invariants:
232
+ // 1) for x in ]left, less[ : x < pivot.
233
+ // 2) for x in [less, k[ : x == pivot.
234
+ // 3) for x in ]great, right[ : x > pivot.
235
+ for (var k = less; k <= great; ++k) {
236
+ var ek = a[k], xk = f(ek);
237
+ if (xk < pivotValue1) {
238
+ if (k !== less) {
239
+ a[k] = a[less];
240
+ a[less] = ek;
241
+ }
242
+ ++less;
243
+ } else if (xk > pivotValue1) {
244
+
245
+ // Find the first element <= pivot in the range [k - 1, great] and
246
+ // put [:ek:] there. We know that such an element must exist:
247
+ // When k == less, then el3 (which is equal to pivot) lies in the
248
+ // interval. Otherwise a[k - 1] == pivot and the search stops at k-1.
249
+ // Note that in the latter case invariant 2 will be violated for a
250
+ // short amount of time. The invariant will be restored when the
251
+ // pivots are put into their final positions.
252
+ while (true) {
253
+ var greatValue = f(a[great]);
254
+ if (greatValue > pivotValue1) {
255
+ great--;
256
+ // This is the only location in the while-loop where a new
257
+ // iteration is started.
258
+ continue;
259
+ } else if (greatValue < pivotValue1) {
260
+ // Triple exchange.
261
+ a[k] = a[less];
262
+ a[less++] = a[great];
263
+ a[great--] = ek;
264
+ break;
265
+ } else {
266
+ a[k] = a[great];
267
+ a[great--] = ek;
268
+ // Note: if great < k then we will exit the outer loop and fix
269
+ // invariant 2 (which we just violated).
270
+ break;
271
+ }
272
+ }
273
+ }
274
+ }
275
+ } else {
276
+
277
+ // We partition the list into three parts:
278
+ // 1. < pivot1
279
+ // 2. >= pivot1 && <= pivot2
280
+ // 3. > pivot2
281
+ //
282
+ // During the loop we have:
283
+ // [ | < pivot1 | >= pivot1 && <= pivot2 | unpartitioned | > pivot2 | ]
284
+ // ^ ^ ^ ^ ^
285
+ // left less k great right
286
+ //
287
+ // a[left] and a[right] are undefined and are filled after the
288
+ // partitioning.
289
+ //
290
+ // Invariants:
291
+ // 1. for x in ]left, less[ : x < pivot1
292
+ // 2. for x in [less, k[ : pivot1 <= x && x <= pivot2
293
+ // 3. for x in ]great, right[ : x > pivot2
294
+ for (var k = less; k <= great; k++) {
295
+ var ek = a[k], xk = f(ek);
296
+ if (xk < pivotValue1) {
297
+ if (k !== less) {
298
+ a[k] = a[less];
299
+ a[less] = ek;
300
+ }
301
+ ++less;
302
+ } else {
303
+ if (xk > pivotValue2) {
304
+ while (true) {
305
+ var greatValue = f(a[great]);
306
+ if (greatValue > pivotValue2) {
307
+ great--;
308
+ if (great < k) break;
309
+ // This is the only location inside the loop where a new
310
+ // iteration is started.
311
+ continue;
312
+ } else {
313
+ // a[great] <= pivot2.
314
+ if (greatValue < pivotValue1) {
315
+ // Triple exchange.
316
+ a[k] = a[less];
317
+ a[less++] = a[great];
318
+ a[great--] = ek;
319
+ } else {
320
+ // a[great] >= pivot1.
321
+ a[k] = a[great];
322
+ a[great--] = ek;
323
+ }
324
+ break;
325
+ }
326
+ }
327
+ }
328
+ }
329
+ }
330
+ }
331
+
332
+ // Move pivots into their final positions.
333
+ // We shrunk the list from both sides (a[left] and a[right] have
334
+ // meaningless values in them) and now we move elements from the first
335
+ // and third partition into these locations so that we can store the
336
+ // pivots.
337
+ a[lo] = a[less - 1];
338
+ a[less - 1] = pivot1;
339
+ a[hi - 1] = a[great + 1];
340
+ a[great + 1] = pivot2;
341
+
342
+ // The list is now partitioned into three partitions:
343
+ // [ < pivot1 | >= pivot1 && <= pivot2 | > pivot2 ]
344
+ // ^ ^ ^ ^
345
+ // left less great right
346
+
347
+ // Recursive descent. (Don't include the pivot values.)
348
+ sort(a, lo, less - 1);
349
+ sort(a, great + 2, hi);
350
+
351
+ if (pivotsEqual) {
352
+ // All elements in the second partition are equal to the pivot. No
353
+ // need to sort them.
354
+ return a;
355
+ }
356
+
357
+ // In theory it should be enough to call _doSort recursively on the second
358
+ // partition.
359
+ // The Android source however removes the pivot elements from the recursive
360
+ // call if the second partition is too large (more than 2/3 of the list).
361
+ if (less < i1 && great > i5) {
362
+ var lessValue, greatValue;
363
+ while ((lessValue = f(a[less])) <= pivotValue1 && lessValue >= pivotValue1) ++less;
364
+ while ((greatValue = f(a[great])) <= pivotValue2 && greatValue >= pivotValue2) --great;
365
+
366
+ // Copy paste of the previous 3-way partitioning with adaptions.
367
+ //
368
+ // We partition the list into three parts:
369
+ // 1. == pivot1
370
+ // 2. > pivot1 && < pivot2
371
+ // 3. == pivot2
372
+ //
373
+ // During the loop we have:
374
+ // [ == pivot1 | > pivot1 && < pivot2 | unpartitioned | == pivot2 ]
375
+ // ^ ^ ^
376
+ // less k great
377
+ //
378
+ // Invariants:
379
+ // 1. for x in [ *, less[ : x == pivot1
380
+ // 2. for x in [less, k[ : pivot1 < x && x < pivot2
381
+ // 3. for x in ]great, * ] : x == pivot2
382
+ for (var k = less; k <= great; k++) {
383
+ var ek = a[k], xk = f(ek);
384
+ if (xk <= pivotValue1 && xk >= pivotValue1) {
385
+ if (k !== less) {
386
+ a[k] = a[less];
387
+ a[less] = ek;
388
+ }
389
+ less++;
390
+ } else {
391
+ if (xk <= pivotValue2 && xk >= pivotValue2) {
392
+ while (true) {
393
+ var greatValue = f(a[great]);
394
+ if (greatValue <= pivotValue2 && greatValue >= pivotValue2) {
395
+ great--;
396
+ if (great < k) break;
397
+ // This is the only location inside the loop where a new
398
+ // iteration is started.
399
+ continue;
400
+ } else {
401
+ // a[great] < pivot2.
402
+ if (greatValue < pivotValue1) {
403
+ // Triple exchange.
404
+ a[k] = a[less];
405
+ a[less++] = a[great];
406
+ a[great--] = ek;
407
+ } else {
408
+ // a[great] == pivot1.
409
+ a[k] = a[great];
410
+ a[great--] = ek;
411
+ }
412
+ break;
413
+ }
414
+ }
415
+ }
416
+ }
417
+ }
418
+ }
419
+
420
+ // The second partition has now been cleared of pivot elements and looks
421
+ // as follows:
422
+ // [ * | > pivot1 && < pivot2 | * ]
423
+ // ^ ^
424
+ // less great
425
+ // Sort the second partition using recursive descent.
426
+
427
+ // The second partition looks as follows:
428
+ // [ * | >= pivot1 && <= pivot2 | * ]
429
+ // ^ ^
430
+ // less great
431
+ // Simply sort it by recursive descent.
432
+
433
+ return sort(a, less, great + 1);
434
+ }
435
+
436
+ return sort;
437
+ }
438
+
439
+ var quicksort_sizeThreshold = 32;
440
+ var crossfilter_array8 = crossfilter_arrayUntyped,
441
+ crossfilter_array16 = crossfilter_arrayUntyped,
442
+ crossfilter_array32 = crossfilter_arrayUntyped,
443
+ crossfilter_arrayLengthen = crossfilter_identity,
444
+ crossfilter_arrayWiden = crossfilter_identity;
445
+
446
+ if (typeof Uint8Array !== "undefined") {
447
+ crossfilter_array8 = function(n) { return new Uint8Array(n); };
448
+ crossfilter_array16 = function(n) { return new Uint16Array(n); };
449
+ crossfilter_array32 = function(n) { return new Uint32Array(n); };
450
+
451
+ crossfilter_arrayLengthen = function(array, length) {
452
+ var copy = new array.constructor(length);
453
+ copy.set(array);
454
+ return copy;
455
+ };
456
+
457
+ crossfilter_arrayWiden = function(array, width) {
458
+ var copy;
459
+ switch (width) {
460
+ case 16: copy = crossfilter_array16(array.length); break;
461
+ case 32: copy = crossfilter_array32(array.length); break;
462
+ default: throw new Error("invalid array width!");
463
+ }
464
+ copy.set(array);
465
+ return copy;
466
+ };
467
+ }
468
+
469
+ function crossfilter_arrayUntyped(n) {
470
+ return new Array(n);
471
+ }
472
+ function crossfilter_filterExact(bisect, value) {
473
+ return function(values) {
474
+ var n = values.length;
475
+ return [bisect.left(values, value, 0, n), bisect.right(values, value, 0, n)];
476
+ };
477
+ }
478
+
479
+ function crossfilter_filterRange(bisect, range) {
480
+ var min = range[0],
481
+ max = range[1];
482
+ return function(values) {
483
+ var n = values.length;
484
+ return [bisect.left(values, min, 0, n), bisect.left(values, max, 0, n)];
485
+ };
486
+ }
487
+
488
+ function crossfilter_filterAll(values) {
489
+ return [0, values.length];
490
+ }
491
+ function crossfilter_null() {
492
+ return null;
493
+ }
494
+ function crossfilter_zero() {
495
+ return 0;
496
+ }
497
+ function crossfilter_reduceIncrement(p) {
498
+ return p + 1;
499
+ }
500
+
501
+ function crossfilter_reduceDecrement(p) {
502
+ return p - 1;
503
+ }
504
+
505
+ function crossfilter_reduceAdd(f) {
506
+ return function(p, v) {
507
+ return p + +f(v);
508
+ };
509
+ }
510
+
511
+ function crossfilter_reduceSubtract(f) {
512
+ return function(p, v) {
513
+ return p - f(v);
514
+ };
515
+ }
516
+ exports.crossfilter = crossfilter;
517
+
518
+ function crossfilter() {
519
+ var crossfilter = {
520
+ add: add,
521
+ dimension: dimension,
522
+ groupAll: groupAll,
523
+ size: size
524
+ };
525
+
526
+ var data = [], // the records
527
+ n = 0, // the number of records; data.length
528
+ m = 0, // number of dimensions in use
529
+ M = 8, // number of dimensions that can fit in `filters`
530
+ filters = crossfilter_array8(0), // M bits per record; 1 is filtered out
531
+ filterListeners = [], // when the filters change
532
+ dataListeners = []; // when data is added
533
+
534
+ // Adds the specified new records to this crossfilter.
535
+ function add(newData) {
536
+ var n0 = n,
537
+ n1 = newData.length;
538
+
539
+ // If there's actually new data to add…
540
+ // Merge the new data into the existing data.
541
+ // Lengthen the filter bitset to handle the new records.
542
+ // Notify listeners (dimensions and groups) that new data is available.
543
+ if (n1) {
544
+ data = data.concat(newData);
545
+ filters = crossfilter_arrayLengthen(filters, n += n1);
546
+ dataListeners.forEach(function(l) { l(newData, n0, n1); });
547
+ }
548
+
549
+ return crossfilter;
550
+ }
551
+
552
+ // Adds a new dimension with the specified value accessor function.
553
+ function dimension(value) {
554
+ var dimension = {
555
+ filter: filter,
556
+ filterExact: filterExact,
557
+ filterRange: filterRange,
558
+ filterAll: filterAll,
559
+ top: top,
560
+ group: group,
561
+ groupAll: groupAll
562
+ };
563
+
564
+ var one = 1 << m++, // bit mask, e.g., 00001000
565
+ zero = ~one, // inverted one, e.g., 11110111
566
+ values, // sorted, cached array
567
+ index, // value rank ↦ object id
568
+ newValues, // temporary array storing newly-added values
569
+ newIndex, // temporary array storing newly-added index
570
+ sort = quicksort_by(function(i) { return newValues[i]; }),
571
+ refilter = crossfilter_filterAll, // for recomputing filter
572
+ indexListeners = [], // when data is added
573
+ lo0 = 0,
574
+ hi0 = 0;
575
+
576
+ // Updating a dimension is a two-stage process. First, we must update the
577
+ // associated filters for the newly-added records. Once all dimensions have
578
+ // updated their filters, the groups are notified to update.
579
+ dataListeners.unshift(preAdd);
580
+ dataListeners.push(postAdd);
581
+
582
+ // Incorporate any existing data into this dimension, and make sure that the
583
+ // filter bitset is wide enough to handle the new dimension.
584
+ if (m > M) filters = crossfilter_arrayWiden(filters, M <<= 1);
585
+ preAdd(data, 0, n);
586
+ postAdd(data, 0, n);
587
+
588
+ // Incorporates the specified new records into this dimension.
589
+ // This function is responsible for updating filters, values, and index.
590
+ function preAdd(newData, n0, n1) {
591
+
592
+ // Permute new values into natural order using a sorted index.
593
+ newValues = newData.map(value);
594
+ newIndex = sort(crossfilter_range(n1), 0, n1);
595
+ newValues = permute(newValues, newIndex);
596
+
597
+ // Bisect newValues to determine which new records are selected.
598
+ var bounds = refilter(newValues), lo1 = bounds[0], hi1 = bounds[1], i;
599
+ for (i = 0; i < lo1; ++i) filters[newIndex[i] + n0] |= one;
600
+ for (i = hi1; i < n1; ++i) filters[newIndex[i] + n0] |= one;
601
+
602
+ // If this dimension previously had no data, then we don't need to do the
603
+ // more expensive merge operation; use the new values and index as-is.
604
+ if (!n0) {
605
+ values = newValues;
606
+ index = newIndex;
607
+ lo0 = lo1;
608
+ hi0 = hi1;
609
+ return;
610
+ }
611
+
612
+ var oldValues = values,
613
+ oldIndex = index,
614
+ i0 = 0,
615
+ i1 = 0;
616
+
617
+ // Otherwise, create new arrays into which to merge new and old.
618
+ values = new Array(n);
619
+ index = crossfilter_index(n, n);
620
+
621
+ // Merge the old and new sorted values, and old and new index.
622
+ for (i = 0; i0 < n0 && i1 < n1; ++i) {
623
+ if (oldValues[i0] < newValues[i1]) {
624
+ values[i] = oldValues[i0];
625
+ index[i] = oldIndex[i0++];
626
+ } else {
627
+ values[i] = newValues[i1];
628
+ index[i] = newIndex[i1++] + n0;
629
+ }
630
+ }
631
+
632
+ // Add any remaining old values.
633
+ for (; i0 < n0; ++i0, ++i) {
634
+ values[i] = oldValues[i0];
635
+ index[i] = oldIndex[i0];
636
+ }
637
+
638
+ // Add any remaining new values.
639
+ for (; i1 < n1; ++i1, ++i) {
640
+ values[i] = newValues[i1];
641
+ index[i] = newIndex[i1] + n0;
642
+ }
643
+
644
+ // Bisect again to recompute lo0 and hi0.
645
+ bounds = refilter(values), lo0 = bounds[0], hi0 = bounds[1];
646
+ }
647
+
648
+ // When all filters have updated, notify index listeners of the new values.
649
+ function postAdd(newData, n0, n1) {
650
+ indexListeners.forEach(function(l) { l(newValues, newIndex, n0, n1); });
651
+ newValues = newIndex = null;
652
+ }
653
+
654
+ // Updates the selected values based on the specified bounds [lo, hi].
655
+ // This implementation is used by all the public filter methods.
656
+ function filterIndex(bounds) {
657
+ var i,
658
+ j,
659
+ k,
660
+ lo1 = bounds[0],
661
+ hi1 = bounds[1],
662
+ added = [],
663
+ removed = [];
664
+
665
+ // Fast incremental update based on previous lo index.
666
+ if (lo1 < lo0) {
667
+ for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) {
668
+ filters[k = index[i]] ^= one;
669
+ added.push(k);
670
+ }
671
+ } else if (lo1 > lo0) {
672
+ for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) {
673
+ filters[k = index[i]] ^= one;
674
+ removed.push(k);
675
+ }
676
+ }
677
+
678
+ // Fast incremental update based on previous hi index.
679
+ if (hi1 > hi0) {
680
+ for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) {
681
+ filters[k = index[i]] ^= one;
682
+ added.push(k);
683
+ }
684
+ } else if (hi1 < hi0) {
685
+ for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) {
686
+ filters[k = index[i]] ^= one;
687
+ removed.push(k);
688
+ }
689
+ }
690
+
691
+ lo0 = lo1;
692
+ hi0 = hi1;
693
+ filterListeners.forEach(function(l) { l(one, added, removed); });
694
+ return dimension;
695
+ }
696
+
697
+ // Filters this dimension using the specified range, value, or null.
698
+ // If the range is null, this is equivalent to filterAll.
699
+ // If the range is an array, this is equivalent to filterRange.
700
+ // Otherwise, this is equivalent to filterExact.
701
+ function filter(range) {
702
+ return range == null
703
+ ? filterAll() : Array.isArray(range)
704
+ ? filterRange(range)
705
+ : filterExact(range);
706
+ }
707
+
708
+ // Filters this dimension to select the exact value.
709
+ function filterExact(value) {
710
+ return filterIndex((refilter = crossfilter_filterExact(bisect, value))(values));
711
+ }
712
+
713
+ // Filters this dimension to select the specified range [lo, hi].
714
+ // The lower bound is inclusive, and the upper bound is exclusive.
715
+ function filterRange(range) {
716
+ return filterIndex((refilter = crossfilter_filterRange(bisect, range))(values));
717
+ }
718
+
719
+ // Clears any filters on this dimension.
720
+ function filterAll() {
721
+ return filterIndex((refilter = crossfilter_filterAll)(values));
722
+ }
723
+
724
+ // Returns the top K selected records, based on this dimension's order.
725
+ // Note: observes this dimension's filter, unlike group and groupAll.
726
+ function top(k) {
727
+ var array = [],
728
+ i = hi0,
729
+ j;
730
+
731
+ while (--i >= lo0 && k > 0) {
732
+ if (!filters[j = index[i]]) {
733
+ array.push(data[j]);
734
+ --k;
735
+ }
736
+ }
737
+
738
+ return array;
739
+ }
740
+
741
+ // Adds a new group to this dimension, using the specified key function.
742
+ function group(key) {
743
+ var group = {
744
+ top: top,
745
+ all: all,
746
+ reduce: reduce,
747
+ reduceCount: reduceCount,
748
+ reduceSum: reduceSum,
749
+ order: order,
750
+ orderNatural: orderNatural,
751
+ size: size
752
+ };
753
+
754
+ var groups, // array of {key, value}
755
+ groupIndex, // object id ↦ group id
756
+ groupWidth = 8,
757
+ groupCapacity = crossfilter_capacity(groupWidth),
758
+ k = 0, // cardinality
759
+ select,
760
+ heap,
761
+ reduceAdd,
762
+ reduceRemove,
763
+ reduceInitial,
764
+ update = crossfilter_null,
765
+ reset = crossfilter_null,
766
+ resetNeeded = true;
767
+
768
+ if (arguments.length < 1) key = crossfilter_identity;
769
+
770
+ // The group listens to the crossfilter for when any dimension changes, so
771
+ // that it can update the associated reduce values. It must also listen to
772
+ // the parent dimension for when data is added, and compute new keys.
773
+ filterListeners.push(update);
774
+ indexListeners.push(add);
775
+
776
+ // Incorporate any existing data into the grouping.
777
+ add(values, index, 0, n);
778
+
779
+ // Incorporates the specified new values into this group.
780
+ // This function is responsible for updating groups and groupIndex.
781
+ function add(newValues, newIndex, n0, n1) {
782
+ var oldGroups = groups,
783
+ reIndex = crossfilter_index(k, groupCapacity),
784
+ add = reduceAdd,
785
+ initial = reduceInitial,
786
+ k0 = k, // old cardinality
787
+ i0 = 0, // index of old group
788
+ i1 = 0, // index of new record
789
+ j, // object id
790
+ g0, // old group
791
+ x0, // old key
792
+ x1, // new key
793
+ g, // group to add
794
+ x; // key of group to add
795
+
796
+ // If a reset is needed, we don't need to update the reduce values.
797
+ if (resetNeeded) add = initial = crossfilter_null;
798
+
799
+ // Reset the new groups (k is a lower bound).
800
+ // Also, make sure that groupIndex exists and is long enough.
801
+ groups = new Array(k), k = 0;
802
+ groupIndex = k0 > 1 ? crossfilter_arrayLengthen(groupIndex, n) : crossfilter_index(n, groupCapacity);
803
+
804
+ // Get the first old key (x0 of g0), if it exists.
805
+ if (k0) x0 = (g0 = oldGroups[0]).key;
806
+
807
+ // Find the first new key (x1), skipping NaN keys.
808
+ while (i1 < n1 && !((x1 = key(newValues[i1])) >= x1)) ++i1;
809
+
810
+ // While new keys remain…
811
+ while (i1 < n1) {
812
+
813
+ // Determine the lesser of the two current keys; new and old.
814
+ // If there are no old keys remaining, then always add the new key.
815
+ if (g0 && x0 <= x1) {
816
+ g = g0, x = x0;
817
+
818
+ // Record the new index of the old group.
819
+ reIndex[i0] = k;
820
+
821
+ // Retrieve the next old key.
822
+ if (g0 = oldGroups[++i0]) x0 = g0.key;
823
+ } else {
824
+ g = {key: x1, value: initial()}, x = x1;
825
+ }
826
+
827
+ // Add the lesser group.
828
+ groups[k] = g;
829
+
830
+ // Add any selected records belonging to the added group, while
831
+ // advancing the new key and populating the associated group index.
832
+ while (!(x1 > x)) {
833
+ groupIndex[j = newIndex[i1] + n0] = k;
834
+ if (!(filters[j] & zero)) g.value = add(g.value, data[j]);
835
+ if (++i1 >= n1) break;
836
+ x1 = key(newValues[i1]);
837
+ }
838
+
839
+ groupIncrement();
840
+ }
841
+
842
+ // Add any remaining old groups that were greater than all new keys.
843
+ // No incremental reduce is needed; these groups have no new records.
844
+ // Also record the new index of the old group.
845
+ while (i0 < k0) {
846
+ groups[reIndex[i0] = k] = oldGroups[i0++];
847
+ groupIncrement();
848
+ }
849
+
850
+ // If we added any new groups before any old groups,
851
+ // update the group index of all the old records.
852
+ if (k > i0) for (i0 = 0; i0 < n0; ++i0) {
853
+ groupIndex[i0] = reIndex[groupIndex[i0]];
854
+ }
855
+
856
+ // Modify the update and reset behavior based on the cardinality.
857
+ // If the cardinality is less than or equal to one, then the groupIndex
858
+ // is not needed. If the cardinality is zero, then there are no records
859
+ // and therefore no groups to update or reset. Note that we also must
860
+ // change the registered listener to point to the new method.
861
+ j = filterListeners.indexOf(update);
862
+ if (k > 1) {
863
+ update = updateMany;
864
+ reset = resetMany;
865
+ } else {
866
+ if (k === 1) {
867
+ update = updateOne;
868
+ reset = resetOne;
869
+ } else {
870
+ update = crossfilter_null;
871
+ reset = crossfilter_null;
872
+ }
873
+ groupIndex = null;
874
+ }
875
+ filterListeners[j] = update;
876
+
877
+ // Count the number of added groups,
878
+ // and widen the group index as needed.
879
+ function groupIncrement() {
880
+ if (++k === groupCapacity) {
881
+ reIndex = crossfilter_arrayWiden(reIndex, groupWidth <<= 1);
882
+ groupIndex = crossfilter_arrayWiden(groupIndex, groupWidth);
883
+ groupCapacity = crossfilter_capacity(groupWidth);
884
+ }
885
+ }
886
+ }
887
+
888
+ // Reduces the specified selected or deselected records.
889
+ // This function is only used when the cardinality is greater than 1.
890
+ function updateMany(filterOne, added, removed) {
891
+ if (filterOne === one || resetNeeded) return;
892
+
893
+ var i,
894
+ k,
895
+ n,
896
+ g;
897
+
898
+ // Add the added values.
899
+ for (i = 0, n = added.length; i < n; ++i) {
900
+ if (!(filters[k = added[i]] & zero)) {
901
+ g = groups[groupIndex[k]];
902
+ g.value = reduceAdd(g.value, data[k]);
903
+ }
904
+ }
905
+
906
+ // Remove the removed values.
907
+ for (i = 0, n = removed.length; i < n; ++i) {
908
+ if ((filters[k = removed[i]] & zero) === filterOne) {
909
+ g = groups[groupIndex[k]];
910
+ g.value = reduceRemove(g.value, data[k]);
911
+ }
912
+ }
913
+ }
914
+
915
+ // Reduces the specified selected or deselected records.
916
+ // This function is only used when the cardinality is 1.
917
+ function updateOne(filterOne, added, removed) {
918
+ if (filterOne === one || resetNeeded) return;
919
+
920
+ var i,
921
+ k,
922
+ n,
923
+ g = groups[0];
924
+
925
+ // Add the added values.
926
+ for (i = 0, n = added.length; i < n; ++i) {
927
+ if (!(filters[k = added[i]] & zero)) {
928
+ g.value = reduceAdd(g.value, data[k]);
929
+ }
930
+ }
931
+
932
+ // Remove the removed values.
933
+ for (i = 0, n = removed.length; i < n; ++i) {
934
+ if ((filters[k = removed[i]] & zero) === filterOne) {
935
+ g.value = reduceRemove(g.value, data[k]);
936
+ }
937
+ }
938
+ }
939
+
940
+ // Recomputes the group reduce values from scratch.
941
+ // This function is only used when the cardinality is greater than 1.
942
+ function resetMany() {
943
+ var i,
944
+ g;
945
+
946
+ // Reset all group values.
947
+ for (i = 0; i < k; ++i) {
948
+ groups[i].value = reduceInitial();
949
+ }
950
+
951
+ // Add any selected records.
952
+ for (i = 0; i < n; ++i) {
953
+ if (!(filters[i] & zero)) {
954
+ g = groups[groupIndex[i]];
955
+ g.value = reduceAdd(g.value, data[i]);
956
+ }
957
+ }
958
+ }
959
+
960
+ // Recomputes the group reduce values from scratch.
961
+ // This function is only used when the cardinality is 1.
962
+ function resetOne() {
963
+ var i,
964
+ g = groups[0];
965
+
966
+ // Reset the singleton group values.
967
+ g.value = reduceInitial();
968
+
969
+ // Add any selected records.
970
+ for (i = 0; i < n; ++i) {
971
+ if (!(filters[i] & zero)) {
972
+ g.value = reduceAdd(g.value, data[i]);
973
+ }
974
+ }
975
+ }
976
+
977
+ // Returns the array of group values, in the dimension's natural order.
978
+ function all() {
979
+ if (resetNeeded) reset(), resetNeeded = false;
980
+ return groups;
981
+ }
982
+
983
+ // Returns a new array containing the top K group values, in reduce order.
984
+ function top(k) {
985
+ var top = select(all(), 0, groups.length, k);
986
+ return heap.sort(top, 0, top.length);
987
+ }
988
+
989
+ // Sets the reduce behavior for this group to use the specified functions.
990
+ // This method lazily recomputes the reduce values, waiting until needed.
991
+ function reduce(add, remove, initial) {
992
+ reduceAdd = add;
993
+ reduceRemove = remove;
994
+ reduceInitial = initial;
995
+ resetNeeded = true;
996
+ return group;
997
+ }
998
+
999
+ // A convenience method for reducing by count.
1000
+ function reduceCount() {
1001
+ return reduce(crossfilter_reduceIncrement, crossfilter_reduceDecrement, crossfilter_zero);
1002
+ }
1003
+
1004
+ // A convenience method for reducing by sum(value).
1005
+ function reduceSum(value) {
1006
+ return reduce(crossfilter_reduceAdd(value), crossfilter_reduceSubtract(value), crossfilter_zero);
1007
+ }
1008
+
1009
+ // Sets the reduce order, using the specified accessor.
1010
+ function order(value) {
1011
+ select = heapselect_by(valueOf);
1012
+ heap = heap_by(valueOf);
1013
+ function valueOf(d) { return value(d.value); }
1014
+ return group;
1015
+ }
1016
+
1017
+ // A convenience method for natural ordering by reduce value.
1018
+ function orderNatural() {
1019
+ return order(crossfilter_identity);
1020
+ }
1021
+
1022
+ // Returns the cardinality of this group, irrespective of any filters.
1023
+ function size() {
1024
+ return k;
1025
+ }
1026
+
1027
+ return reduceCount().orderNatural();
1028
+ }
1029
+
1030
+ // A convenience function for generating a singleton group.
1031
+ function groupAll() {
1032
+ var g = group(crossfilter_null), all = g.all;
1033
+ delete g.all;
1034
+ delete g.top;
1035
+ delete g.order;
1036
+ delete g.orderNatural;
1037
+ delete g.size;
1038
+ g.value = function() { return all()[0].value; };
1039
+ return g;
1040
+ }
1041
+
1042
+ return dimension;
1043
+ }
1044
+
1045
+ // A convenience method for groupAll on a dummy dimension.
1046
+ // This implementation can be optimized since it is always cardinality 1.
1047
+ function groupAll() {
1048
+ var group = {
1049
+ reduce: reduce,
1050
+ reduceCount: reduceCount,
1051
+ reduceSum: reduceSum,
1052
+ value: value
1053
+ };
1054
+
1055
+ var reduceValue,
1056
+ reduceAdd,
1057
+ reduceRemove,
1058
+ reduceInitial,
1059
+ resetNeeded = true;
1060
+
1061
+ // The group listens to the crossfilter for when any dimension changes, so
1062
+ // that it can update the reduce value. It must also listen to the parent
1063
+ // dimension for when data is added.
1064
+ filterListeners.push(update);
1065
+ dataListeners.push(add);
1066
+
1067
+ // For consistency; actually a no-op since resetNeeded is true.
1068
+ add(data, 0, n);
1069
+
1070
+ // Incorporates the specified new values into this group.
1071
+ function add(newData, n0, n1) {
1072
+ var i;
1073
+
1074
+ if (resetNeeded) return;
1075
+
1076
+ // Add the added values.
1077
+ for (i = n0; i < n; ++i) {
1078
+ if (!filters[i]) {
1079
+ reduceValue = reduceAdd(reduceValue, data[i]);
1080
+ }
1081
+ }
1082
+ }
1083
+
1084
+ // Reduces the specified selected or deselected records.
1085
+ function update(filterOne, added, removed) {
1086
+ var i,
1087
+ k,
1088
+ n;
1089
+
1090
+ if (resetNeeded) return;
1091
+
1092
+ // Add the added values.
1093
+ for (i = 0, n = added.length; i < n; ++i) {
1094
+ if (!filters[k = added[i]]) {
1095
+ reduceValue = reduceAdd(reduceValue, data[k]);
1096
+ }
1097
+ }
1098
+
1099
+ // Remove the removed values.
1100
+ for (i = 0, n = removed.length; i < n; ++i) {
1101
+ if (filters[k = removed[i]] === filterOne) {
1102
+ reduceValue = reduceRemove(reduceValue, data[k]);
1103
+ }
1104
+ }
1105
+ }
1106
+
1107
+ // Recomputes the group reduce value from scratch.
1108
+ function reset() {
1109
+ var i;
1110
+
1111
+ reduceValue = reduceInitial();
1112
+
1113
+ for (i = 0; i < n; ++i) {
1114
+ if (!filters[i]) {
1115
+ reduceValue = reduceAdd(reduceValue, data[i]);
1116
+ }
1117
+ }
1118
+ }
1119
+
1120
+ // Sets the reduce behavior for this group to use the specified functions.
1121
+ // This method lazily recomputes the reduce value, waiting until needed.
1122
+ function reduce(add, remove, initial) {
1123
+ reduceAdd = add;
1124
+ reduceRemove = remove;
1125
+ reduceInitial = initial;
1126
+ resetNeeded = true;
1127
+ return group;
1128
+ }
1129
+
1130
+ // A convenience method for reducing by count.
1131
+ function reduceCount() {
1132
+ return reduce(crossfilter_reduceIncrement, crossfilter_reduceDecrement, crossfilter_zero);
1133
+ }
1134
+
1135
+ // A convenience method for reducing by sum(value).
1136
+ function reduceSum(value) {
1137
+ return reduce(crossfilter_reduceAdd(value), crossfilter_reduceSubtract(value), crossfilter_zero);
1138
+ }
1139
+
1140
+ // Returns the computed reduce value.
1141
+ function value() {
1142
+ if (resetNeeded) reset(), resetNeeded = false;
1143
+ return reduceValue;
1144
+ }
1145
+
1146
+ return reduceCount();
1147
+ }
1148
+
1149
+ // Returns the number of records in this crossfilter, irrespective of any filters.
1150
+ function size() {
1151
+ return n;
1152
+ }
1153
+
1154
+ return arguments.length
1155
+ ? add(arguments[0])
1156
+ : crossfilter;
1157
+ }
1158
+
1159
+ // Returns an array of size n, big enough to store ids up to m.
1160
+ function crossfilter_index(n, m) {
1161
+ return (m < 0x101
1162
+ ? crossfilter_array8 : m < 0x10001
1163
+ ? crossfilter_array16
1164
+ : crossfilter_array32)(n);
1165
+ }
1166
+
1167
+ // Constructs a new array of size n, with sequential values from 0 to n - 1.
1168
+ function crossfilter_range(n) {
1169
+ var range = crossfilter_index(n, n);
1170
+ for (var i = -1; ++i < n;) range[i] = i;
1171
+ return range;
1172
+ }
1173
+
1174
+ function crossfilter_capacity(w) {
1175
+ return w === 8
1176
+ ? 0x100 : w === 16
1177
+ ? 0x10000
1178
+ : 0x100000000;
1179
+ }
1180
+ })(this);