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,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);