@veritone-ce/design-system 2.9.0-next.2 → 2.9.0-next.3

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 (629) hide show
  1. package/dist/cjs/bundled_modules/d3-array/src/ascending.js +9 -0
  2. package/dist/cjs/bundled_modules/d3-array/src/bisect.js +16 -0
  3. package/dist/cjs/bundled_modules/d3-array/src/bisector.js +62 -0
  4. package/dist/cjs/bundled_modules/d3-array/src/descending.js +13 -0
  5. package/dist/cjs/bundled_modules/d3-array/src/deviation.js +12 -0
  6. package/dist/cjs/bundled_modules/d3-array/src/fsum.js +45 -0
  7. package/dist/cjs/bundled_modules/d3-array/src/intersection.js +25 -0
  8. package/dist/cjs/bundled_modules/d3-array/src/max.js +26 -0
  9. package/dist/cjs/bundled_modules/d3-array/src/mean.js +25 -0
  10. package/dist/cjs/bundled_modules/d3-array/src/median.js +11 -0
  11. package/dist/cjs/bundled_modules/d3-array/src/merge.js +15 -0
  12. package/dist/cjs/bundled_modules/d3-array/src/min.js +26 -0
  13. package/dist/cjs/bundled_modules/d3-array/src/number.js +27 -0
  14. package/dist/cjs/bundled_modules/d3-array/src/permute.js +9 -0
  15. package/dist/cjs/bundled_modules/d3-array/src/quantile.js +36 -0
  16. package/dist/cjs/bundled_modules/d3-array/src/quickselect.js +59 -0
  17. package/dist/cjs/bundled_modules/d3-array/src/range.js +19 -0
  18. package/dist/cjs/bundled_modules/d3-array/src/sort.js +20 -0
  19. package/dist/cjs/bundled_modules/d3-array/src/sum.js +17 -0
  20. package/dist/cjs/bundled_modules/d3-array/src/ticks.js +63 -0
  21. package/dist/cjs/bundled_modules/d3-array/src/union.js +17 -0
  22. package/dist/cjs/bundled_modules/d3-array/src/variance.js +31 -0
  23. package/dist/cjs/bundled_modules/d3-color/src/color.js +410 -0
  24. package/dist/cjs/bundled_modules/d3-color/src/cubehelix.js +68 -0
  25. package/dist/cjs/bundled_modules/d3-color/src/define.js +17 -0
  26. package/dist/cjs/bundled_modules/d3-color/src/lab.js +124 -0
  27. package/dist/cjs/bundled_modules/d3-color/src/math.js +7 -0
  28. package/dist/cjs/bundled_modules/d3-delaunay/src/delaunay.js +254 -0
  29. package/dist/cjs/bundled_modules/d3-delaunay/src/path.js +43 -0
  30. package/dist/cjs/bundled_modules/d3-delaunay/src/polygon.js +23 -0
  31. package/dist/cjs/bundled_modules/d3-delaunay/src/voronoi.js +338 -0
  32. package/dist/cjs/bundled_modules/d3-dispatch/src/dispatch.js +88 -0
  33. package/dist/cjs/bundled_modules/d3-dsv/src/dsv.js +170 -0
  34. package/dist/cjs/bundled_modules/d3-force/src/center.js +46 -0
  35. package/dist/cjs/bundled_modules/d3-force/src/collide.js +106 -0
  36. package/dist/cjs/bundled_modules/d3-force/src/constant.js +11 -0
  37. package/dist/cjs/bundled_modules/d3-force/src/jiggle.js +9 -0
  38. package/dist/cjs/bundled_modules/d3-force/src/lcg.js +15 -0
  39. package/dist/cjs/bundled_modules/d3-force/src/link.js +123 -0
  40. package/dist/cjs/bundled_modules/d3-force/src/manyBody.js +122 -0
  41. package/dist/cjs/bundled_modules/d3-force/src/simulation.js +164 -0
  42. package/dist/cjs/bundled_modules/d3-force/src/x.js +47 -0
  43. package/dist/cjs/bundled_modules/d3-force/src/y.js +47 -0
  44. package/dist/cjs/bundled_modules/d3-format/src/defaultLocale.js +24 -0
  45. package/dist/cjs/bundled_modules/d3-format/src/exponent.js +11 -0
  46. package/dist/cjs/bundled_modules/d3-format/src/formatDecimal.js +27 -0
  47. package/dist/cjs/bundled_modules/d3-format/src/formatGroup.js +24 -0
  48. package/dist/cjs/bundled_modules/d3-format/src/formatNumerals.js +13 -0
  49. package/dist/cjs/bundled_modules/d3-format/src/formatPrefixAuto.js +22 -0
  50. package/dist/cjs/bundled_modules/d3-format/src/formatRounded.js +17 -0
  51. package/dist/cjs/bundled_modules/d3-format/src/formatSpecifier.js +54 -0
  52. package/dist/cjs/bundled_modules/d3-format/src/formatTrim.js +17 -0
  53. package/dist/cjs/bundled_modules/d3-format/src/formatTypes.js +25 -0
  54. package/dist/cjs/bundled_modules/d3-format/src/identity.js +9 -0
  55. package/dist/cjs/bundled_modules/d3-format/src/locale.js +154 -0
  56. package/dist/cjs/bundled_modules/d3-format/src/precisionFixed.js +11 -0
  57. package/dist/cjs/bundled_modules/d3-format/src/precisionPrefix.js +11 -0
  58. package/dist/cjs/bundled_modules/d3-format/src/precisionRound.js +12 -0
  59. package/dist/cjs/bundled_modules/d3-geo/src/area.js +83 -0
  60. package/dist/cjs/bundled_modules/d3-geo/src/bounds.js +185 -0
  61. package/dist/cjs/bundled_modules/d3-geo/src/cartesian.js +43 -0
  62. package/dist/cjs/bundled_modules/d3-geo/src/centroid.js +149 -0
  63. package/dist/cjs/bundled_modules/d3-geo/src/circle.js +35 -0
  64. package/dist/cjs/bundled_modules/d3-geo/src/clip/antimeridian.js +98 -0
  65. package/dist/cjs/bundled_modules/d3-geo/src/clip/buffer.js +30 -0
  66. package/dist/cjs/bundled_modules/d3-geo/src/clip/circle.js +183 -0
  67. package/dist/cjs/bundled_modules/d3-geo/src/clip/index.js +137 -0
  68. package/dist/cjs/bundled_modules/d3-geo/src/clip/line.js +65 -0
  69. package/dist/cjs/bundled_modules/d3-geo/src/clip/rectangle.js +174 -0
  70. package/dist/cjs/bundled_modules/d3-geo/src/clip/rejoin.js +109 -0
  71. package/dist/cjs/bundled_modules/d3-geo/src/compose.js +18 -0
  72. package/dist/cjs/bundled_modules/d3-geo/src/graticule.js +107 -0
  73. package/dist/cjs/bundled_modules/d3-geo/src/identity.js +7 -0
  74. package/dist/cjs/bundled_modules/d3-geo/src/math.js +57 -0
  75. package/dist/cjs/bundled_modules/d3-geo/src/noop.js +7 -0
  76. package/dist/cjs/bundled_modules/d3-geo/src/path/area.js +54 -0
  77. package/dist/cjs/bundled_modules/d3-geo/src/path/bounds.js +32 -0
  78. package/dist/cjs/bundled_modules/d3-geo/src/path/centroid.js +104 -0
  79. package/dist/cjs/bundled_modules/d3-geo/src/path/context.js +51 -0
  80. package/dist/cjs/bundled_modules/d3-geo/src/path/index.js +82 -0
  81. package/dist/cjs/bundled_modules/d3-geo/src/path/measure.js +49 -0
  82. package/dist/cjs/bundled_modules/d3-geo/src/path/string.js +92 -0
  83. package/dist/cjs/bundled_modules/d3-geo/src/pointEqual.js +11 -0
  84. package/dist/cjs/bundled_modules/d3-geo/src/polygonContains.js +80 -0
  85. package/dist/cjs/bundled_modules/d3-geo/src/projection/albers.js +16 -0
  86. package/dist/cjs/bundled_modules/d3-geo/src/projection/albersUsa.js +117 -0
  87. package/dist/cjs/bundled_modules/d3-geo/src/projection/azimuthal.js +32 -0
  88. package/dist/cjs/bundled_modules/d3-geo/src/projection/azimuthalEqualArea.js +24 -0
  89. package/dist/cjs/bundled_modules/d3-geo/src/projection/azimuthalEquidistant.js +24 -0
  90. package/dist/cjs/bundled_modules/d3-geo/src/projection/conic.js +19 -0
  91. package/dist/cjs/bundled_modules/d3-geo/src/projection/conicConformal.js +45 -0
  92. package/dist/cjs/bundled_modules/d3-geo/src/projection/conicEqualArea.js +40 -0
  93. package/dist/cjs/bundled_modules/d3-geo/src/projection/conicEquidistant.js +39 -0
  94. package/dist/cjs/bundled_modules/d3-geo/src/projection/cylindricalEqualArea.js +19 -0
  95. package/dist/cjs/bundled_modules/d3-geo/src/projection/equalEarth.js +43 -0
  96. package/dist/cjs/bundled_modules/d3-geo/src/projection/equirectangular.js +19 -0
  97. package/dist/cjs/bundled_modules/d3-geo/src/projection/fit.js +54 -0
  98. package/dist/cjs/bundled_modules/d3-geo/src/projection/gnomonic.js +23 -0
  99. package/dist/cjs/bundled_modules/d3-geo/src/projection/identity.js +91 -0
  100. package/dist/cjs/bundled_modules/d3-geo/src/projection/index.js +184 -0
  101. package/dist/cjs/bundled_modules/d3-geo/src/projection/mercator.js +60 -0
  102. package/dist/cjs/bundled_modules/d3-geo/src/projection/naturalEarth1.js +35 -0
  103. package/dist/cjs/bundled_modules/d3-geo/src/projection/orthographic.js +22 -0
  104. package/dist/cjs/bundled_modules/d3-geo/src/projection/resample.js +108 -0
  105. package/dist/cjs/bundled_modules/d3-geo/src/projection/stereographic.js +25 -0
  106. package/dist/cjs/bundled_modules/d3-geo/src/projection/transverseMercator.js +34 -0
  107. package/dist/cjs/bundled_modules/d3-geo/src/rotation.js +86 -0
  108. package/dist/cjs/bundled_modules/d3-geo/src/stream.js +75 -0
  109. package/dist/cjs/bundled_modules/d3-geo/src/transform.js +24 -0
  110. package/dist/cjs/bundled_modules/d3-geo-projection/src/math.js +28 -0
  111. package/dist/cjs/bundled_modules/d3-geo-projection/src/mollweide.js +38 -0
  112. package/dist/cjs/bundled_modules/d3-hierarchy/src/accessors.js +13 -0
  113. package/dist/cjs/bundled_modules/d3-hierarchy/src/array.js +27 -0
  114. package/dist/cjs/bundled_modules/d3-hierarchy/src/cluster.js +90 -0
  115. package/dist/cjs/bundled_modules/d3-hierarchy/src/constant.js +16 -0
  116. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/ancestors.js +13 -0
  117. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/count.js +18 -0
  118. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/descendants.js +9 -0
  119. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/each.js +13 -0
  120. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/eachAfter.js +21 -0
  121. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/eachBefore.js +18 -0
  122. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/find.js +14 -0
  123. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/index.js +99 -0
  124. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/iterator.js +20 -0
  125. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/leaves.js +15 -0
  126. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/links.js +15 -0
  127. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/path.js +36 -0
  128. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/sort.js +13 -0
  129. package/dist/cjs/bundled_modules/d3-hierarchy/src/hierarchy/sum.js +15 -0
  130. package/dist/cjs/bundled_modules/d3-hierarchy/src/lcg.js +15 -0
  131. package/dist/cjs/bundled_modules/d3-hierarchy/src/pack/enclose.js +122 -0
  132. package/dist/cjs/bundled_modules/d3-hierarchy/src/pack/index.js +87 -0
  133. package/dist/cjs/bundled_modules/d3-hierarchy/src/pack/siblings.js +118 -0
  134. package/dist/cjs/bundled_modules/d3-hierarchy/src/partition.js +58 -0
  135. package/dist/cjs/bundled_modules/d3-hierarchy/src/stratify.js +151 -0
  136. package/dist/cjs/bundled_modules/d3-hierarchy/src/tree.js +243 -0
  137. package/dist/cjs/bundled_modules/d3-hierarchy/src/treemap/binary.js +52 -0
  138. package/dist/cjs/bundled_modules/d3-hierarchy/src/treemap/dice.js +18 -0
  139. package/dist/cjs/bundled_modules/d3-hierarchy/src/treemap/index.js +100 -0
  140. package/dist/cjs/bundled_modules/d3-hierarchy/src/treemap/resquarify.js +42 -0
  141. package/dist/cjs/bundled_modules/d3-hierarchy/src/treemap/round.js +12 -0
  142. package/dist/cjs/bundled_modules/d3-hierarchy/src/treemap/slice.js +18 -0
  143. package/dist/cjs/bundled_modules/d3-hierarchy/src/treemap/sliceDice.js +12 -0
  144. package/dist/cjs/bundled_modules/d3-hierarchy/src/treemap/squarify.js +74 -0
  145. package/dist/cjs/bundled_modules/d3-interpolate/src/array.js +29 -0
  146. package/dist/cjs/bundled_modules/d3-interpolate/src/basis.js +26 -0
  147. package/dist/cjs/bundled_modules/d3-interpolate/src/basisClosed.js +19 -0
  148. package/dist/cjs/bundled_modules/d3-interpolate/src/color.js +37 -0
  149. package/dist/cjs/bundled_modules/d3-interpolate/src/constant.js +7 -0
  150. package/dist/cjs/bundled_modules/d3-interpolate/src/cubehelix.js +36 -0
  151. package/dist/cjs/bundled_modules/d3-interpolate/src/date.js +12 -0
  152. package/dist/cjs/bundled_modules/d3-interpolate/src/discrete.js +12 -0
  153. package/dist/cjs/bundled_modules/d3-interpolate/src/hcl.js +28 -0
  154. package/dist/cjs/bundled_modules/d3-interpolate/src/hsl.js +28 -0
  155. package/dist/cjs/bundled_modules/d3-interpolate/src/hue.js +15 -0
  156. package/dist/cjs/bundled_modules/d3-interpolate/src/index.js +53 -0
  157. package/dist/cjs/bundled_modules/d3-interpolate/src/lab.js +22 -0
  158. package/dist/cjs/bundled_modules/d3-interpolate/src/number.js +11 -0
  159. package/dist/cjs/bundled_modules/d3-interpolate/src/numberArray.js +21 -0
  160. package/dist/cjs/bundled_modules/d3-interpolate/src/object.js +29 -0
  161. package/dist/cjs/bundled_modules/d3-interpolate/src/piecewise.js +17 -0
  162. package/dist/cjs/bundled_modules/d3-interpolate/src/quantize.js +11 -0
  163. package/dist/cjs/bundled_modules/d3-interpolate/src/rgb.js +63 -0
  164. package/dist/cjs/bundled_modules/d3-interpolate/src/round.js +11 -0
  165. package/dist/cjs/bundled_modules/d3-interpolate/src/string.js +70 -0
  166. package/dist/cjs/bundled_modules/d3-interpolate/src/transform/decompose.js +33 -0
  167. package/dist/cjs/bundled_modules/d3-interpolate/src/transform/index.js +68 -0
  168. package/dist/cjs/bundled_modules/d3-interpolate/src/transform/parse.js +23 -0
  169. package/dist/cjs/bundled_modules/d3-interpolate/src/value.js +28 -0
  170. package/dist/cjs/bundled_modules/d3-interpolate/src/zoom.js +77 -0
  171. package/dist/cjs/bundled_modules/d3-path/src/path.js +157 -0
  172. package/dist/cjs/bundled_modules/d3-quadtree/src/add.js +91 -0
  173. package/dist/cjs/bundled_modules/d3-quadtree/src/cover.js +49 -0
  174. package/dist/cjs/bundled_modules/d3-quadtree/src/data.js +13 -0
  175. package/dist/cjs/bundled_modules/d3-quadtree/src/extent.js +11 -0
  176. package/dist/cjs/bundled_modules/d3-quadtree/src/find.js +76 -0
  177. package/dist/cjs/bundled_modules/d3-quadtree/src/quad.js +13 -0
  178. package/dist/cjs/bundled_modules/d3-quadtree/src/quadtree.js +79 -0
  179. package/dist/cjs/bundled_modules/d3-quadtree/src/remove.js +69 -0
  180. package/dist/cjs/bundled_modules/d3-quadtree/src/root.js +9 -0
  181. package/dist/cjs/bundled_modules/d3-quadtree/src/size.js +13 -0
  182. package/dist/cjs/bundled_modules/d3-quadtree/src/visit.js +22 -0
  183. package/dist/cjs/bundled_modules/d3-quadtree/src/visitAfter.js +27 -0
  184. package/dist/cjs/bundled_modules/d3-quadtree/src/x.js +14 -0
  185. package/dist/cjs/bundled_modules/d3-quadtree/src/y.js +14 -0
  186. package/dist/cjs/bundled_modules/d3-scale/src/constant.js +11 -0
  187. package/dist/cjs/bundled_modules/d3-scale/src/continuous.js +136 -0
  188. package/dist/cjs/bundled_modules/d3-scale/src/diverging.js +116 -0
  189. package/dist/cjs/bundled_modules/d3-scale/src/identity.js +34 -0
  190. package/dist/cjs/bundled_modules/d3-scale/src/init.js +31 -0
  191. package/dist/cjs/bundled_modules/d3-scale/src/linear.js +77 -0
  192. package/dist/cjs/bundled_modules/d3-scale/src/log.js +148 -0
  193. package/dist/cjs/bundled_modules/d3-scale/src/nice.js +24 -0
  194. package/dist/cjs/bundled_modules/d3-scale/src/number.js +9 -0
  195. package/dist/cjs/bundled_modules/d3-scale/src/ordinal.js +53 -0
  196. package/dist/cjs/bundled_modules/d3-scale/src/pow.js +58 -0
  197. package/dist/cjs/bundled_modules/d3-scale/src/quantile.js +65 -0
  198. package/dist/cjs/bundled_modules/d3-scale/src/quantize.js +62 -0
  199. package/dist/cjs/bundled_modules/d3-scale/src/sequential.js +119 -0
  200. package/dist/cjs/bundled_modules/d3-scale/src/symlog.js +42 -0
  201. package/dist/cjs/bundled_modules/d3-scale/src/threshold.js +45 -0
  202. package/dist/cjs/bundled_modules/d3-scale/src/tickFormat.js +39 -0
  203. package/dist/cjs/bundled_modules/d3-scale/src/time.js +85 -0
  204. package/dist/cjs/bundled_modules/d3-scale/src/utcTime.js +21 -0
  205. package/dist/cjs/bundled_modules/d3-scale-chromatic/src/categorical/Accent.js +9 -0
  206. package/dist/cjs/bundled_modules/d3-scale-chromatic/src/categorical/Dark2.js +9 -0
  207. package/dist/cjs/bundled_modules/d3-scale-chromatic/src/categorical/Paired.js +9 -0
  208. package/dist/cjs/bundled_modules/d3-scale-chromatic/src/categorical/Pastel1.js +9 -0
  209. package/dist/cjs/bundled_modules/d3-scale-chromatic/src/categorical/Pastel2.js +9 -0
  210. package/dist/cjs/bundled_modules/d3-scale-chromatic/src/categorical/Set1.js +9 -0
  211. package/dist/cjs/bundled_modules/d3-scale-chromatic/src/categorical/Set2.js +9 -0
  212. package/dist/cjs/bundled_modules/d3-scale-chromatic/src/categorical/Set3.js +9 -0
  213. package/dist/cjs/bundled_modules/d3-scale-chromatic/src/categorical/category10.js +9 -0
  214. package/dist/cjs/bundled_modules/d3-scale-chromatic/src/categorical/observable10.js +9 -0
  215. package/dist/cjs/bundled_modules/d3-scale-chromatic/src/colors.js +11 -0
  216. package/dist/cjs/bundled_modules/d3-shape/src/arc.js +274 -0
  217. package/dist/cjs/bundled_modules/d3-shape/src/area.js +118 -0
  218. package/dist/cjs/bundled_modules/d3-shape/src/array.js +11 -0
  219. package/dist/cjs/bundled_modules/d3-shape/src/constant.js +11 -0
  220. package/dist/cjs/bundled_modules/d3-shape/src/curve/basis.js +59 -0
  221. package/dist/cjs/bundled_modules/d3-shape/src/curve/basisClosed.js +58 -0
  222. package/dist/cjs/bundled_modules/d3-shape/src/curve/basisOpen.js +45 -0
  223. package/dist/cjs/bundled_modules/d3-shape/src/curve/bundle.js +62 -0
  224. package/dist/cjs/bundled_modules/d3-shape/src/curve/cardinal.js +69 -0
  225. package/dist/cjs/bundled_modules/d3-shape/src/curve/cardinalClosed.js +68 -0
  226. package/dist/cjs/bundled_modules/d3-shape/src/curve/cardinalOpen.js +56 -0
  227. package/dist/cjs/bundled_modules/d3-shape/src/curve/catmullRom.js +95 -0
  228. package/dist/cjs/bundled_modules/d3-shape/src/curve/catmullRomClosed.js +80 -0
  229. package/dist/cjs/bundled_modules/d3-shape/src/curve/catmullRomOpen.js +68 -0
  230. package/dist/cjs/bundled_modules/d3-shape/src/curve/linear.js +37 -0
  231. package/dist/cjs/bundled_modules/d3-shape/src/curve/linearClosed.js +31 -0
  232. package/dist/cjs/bundled_modules/d3-shape/src/curve/monotone.js +109 -0
  233. package/dist/cjs/bundled_modules/d3-shape/src/curve/natural.js +71 -0
  234. package/dist/cjs/bundled_modules/d3-shape/src/curve/step.js +61 -0
  235. package/dist/cjs/bundled_modules/d3-shape/src/line.js +64 -0
  236. package/dist/cjs/bundled_modules/d3-shape/src/math.js +36 -0
  237. package/dist/cjs/bundled_modules/d3-shape/src/noop.js +7 -0
  238. package/dist/cjs/bundled_modules/d3-shape/src/path.js +23 -0
  239. package/dist/cjs/bundled_modules/d3-shape/src/point.js +12 -0
  240. package/dist/cjs/bundled_modules/d3-shape/src/symbol/circle.js +15 -0
  241. package/dist/cjs/bundled_modules/d3-shape/src/symbol.js +38 -0
  242. package/dist/cjs/bundled_modules/d3-time/src/day.js +41 -0
  243. package/dist/cjs/bundled_modules/d3-time/src/duration.js +17 -0
  244. package/dist/cjs/bundled_modules/d3-time/src/hour.js +31 -0
  245. package/dist/cjs/bundled_modules/d3-time/src/interval.js +73 -0
  246. package/dist/cjs/bundled_modules/d3-time/src/millisecond.js +29 -0
  247. package/dist/cjs/bundled_modules/d3-time/src/minute.js +31 -0
  248. package/dist/cjs/bundled_modules/d3-time/src/month.js +32 -0
  249. package/dist/cjs/bundled_modules/d3-time/src/second.js +18 -0
  250. package/dist/cjs/bundled_modules/d3-time/src/ticks.js +64 -0
  251. package/dist/cjs/bundled_modules/d3-time/src/week.js +73 -0
  252. package/dist/cjs/bundled_modules/d3-time/src/year.js +54 -0
  253. package/dist/cjs/bundled_modules/d3-time-format/src/defaultLocale.js +33 -0
  254. package/dist/cjs/bundled_modules/d3-time-format/src/locale.js +694 -0
  255. package/dist/cjs/bundled_modules/d3-timer/src/interval.js +23 -0
  256. package/dist/cjs/bundled_modules/d3-timer/src/timer.js +117 -0
  257. package/dist/cjs/bundled_modules/delaunator/index.js +485 -0
  258. package/dist/cjs/bundled_modules/internmap/src/index.js +66 -0
  259. package/dist/cjs/bundled_modules/json-stringify-pretty-compact/index.js +104 -0
  260. package/dist/cjs/bundled_modules/robust-predicates/esm/orient2d.js +184 -0
  261. package/dist/cjs/bundled_modules/robust-predicates/esm/util.js +95 -0
  262. package/dist/cjs/bundled_modules/topojson-client/src/feature.js +77 -0
  263. package/dist/cjs/bundled_modules/topojson-client/src/identity.js +9 -0
  264. package/dist/cjs/bundled_modules/topojson-client/src/mesh.js +60 -0
  265. package/dist/cjs/bundled_modules/topojson-client/src/reverse.js +10 -0
  266. package/dist/cjs/bundled_modules/topojson-client/src/stitch.js +79 -0
  267. package/dist/cjs/bundled_modules/topojson-client/src/transform.js +25 -0
  268. package/dist/cjs/bundled_modules/vega/build/vega.module.js +272 -0
  269. package/dist/cjs/bundled_modules/vega-canvas/build/vega-canvas.browser.js +18 -0
  270. package/dist/cjs/bundled_modules/vega-crossfilter/build/vega-crossfilter.js +676 -0
  271. package/dist/cjs/bundled_modules/vega-dataflow/build/vega-dataflow.js +2102 -0
  272. package/dist/cjs/bundled_modules/vega-embed/build/embed.js +2939 -0
  273. package/dist/cjs/bundled_modules/vega-encode/build/vega-encode.js +962 -0
  274. package/dist/cjs/bundled_modules/vega-event-selector/build/vega-event-selector.js +192 -0
  275. package/dist/cjs/bundled_modules/vega-expression/build/vega-expression.js +1615 -0
  276. package/dist/cjs/bundled_modules/vega-force/build/vega-force.js +295 -0
  277. package/dist/cjs/bundled_modules/vega-format/build/vega-format.js +201 -0
  278. package/dist/cjs/bundled_modules/vega-functions/build/vega-functions.js +842 -0
  279. package/dist/cjs/bundled_modules/vega-geo/build/vega-geo.js +1333 -0
  280. package/dist/cjs/bundled_modules/vega-hierarchy/build/vega-hierarchy.js +580 -0
  281. package/dist/cjs/bundled_modules/vega-interpreter/build/vega-interpreter.js +310 -0
  282. package/dist/cjs/bundled_modules/vega-label/build/vega-label.js +876 -0
  283. package/dist/cjs/bundled_modules/vega-lite/build/index.js +20157 -0
  284. package/dist/cjs/bundled_modules/vega-loader/build/vega-loader.browser.js +337 -0
  285. package/dist/cjs/bundled_modules/vega-parser/build/vega-parser.js +3805 -0
  286. package/dist/cjs/bundled_modules/vega-projection/build/vega-projection.js +90 -0
  287. package/dist/cjs/bundled_modules/vega-regression/build/vega-regression.js +236 -0
  288. package/dist/cjs/bundled_modules/vega-runtime/build/vega-runtime.js +588 -0
  289. package/dist/cjs/bundled_modules/vega-scale/build/vega-scale.js +846 -0
  290. package/dist/cjs/bundled_modules/vega-scenegraph/build/vega-scenegraph.js +5040 -0
  291. package/dist/cjs/bundled_modules/vega-schema-url-parser/dist/parser.modern.js +7 -0
  292. package/dist/cjs/bundled_modules/vega-selections/build/vega-selection.js +342 -0
  293. package/dist/cjs/bundled_modules/vega-statistics/build/vega-statistics.js +1193 -0
  294. package/dist/cjs/bundled_modules/vega-themes/build/index.js +853 -0
  295. package/dist/cjs/bundled_modules/vega-time/build/vega-time.js +342 -0
  296. package/dist/cjs/bundled_modules/vega-tooltip/build/index.js +353 -0
  297. package/dist/cjs/bundled_modules/vega-transforms/build/vega-transforms.js +3781 -0
  298. package/dist/cjs/bundled_modules/vega-util/build/vega-util.js +824 -0
  299. package/dist/cjs/bundled_modules/vega-view/build/vega-view.js +1306 -0
  300. package/dist/cjs/bundled_modules/vega-view-transforms/build/vega-view-transforms.js +1313 -0
  301. package/dist/cjs/bundled_modules/vega-voronoi/build/vega-voronoi.js +80 -0
  302. package/dist/cjs/bundled_modules/vega-wordcloud/build/vega-wordcloud.js +540 -0
  303. package/dist/cjs/unstable/extras/chart/BarChart.js +42 -0
  304. package/dist/cjs/unstable/extras/chart/Chart.js +100 -0
  305. package/dist/cjs/unstable/extras/chart/DistributionChart.js +84 -0
  306. package/dist/cjs/unstable/extras/chart/DonutChart.js +43 -0
  307. package/dist/cjs/unstable/extras/chart/LineChart.js +45 -0
  308. package/dist/cjs/unstable/extras/chart/PieChart.js +39 -0
  309. package/dist/cjs/unstable/extras/chart/TimelineChart.js +48 -0
  310. package/dist/cjs/unstable/extras/chart/index.js +23 -0
  311. package/dist/esm/bundled_modules/d3-array/src/ascending.js +5 -0
  312. package/dist/esm/bundled_modules/d3-array/src/bisect.js +10 -0
  313. package/dist/esm/bundled_modules/d3-array/src/bisector.js +58 -0
  314. package/dist/esm/bundled_modules/d3-array/src/descending.js +9 -0
  315. package/dist/esm/bundled_modules/d3-array/src/deviation.js +8 -0
  316. package/dist/esm/bundled_modules/d3-array/src/fsum.js +43 -0
  317. package/dist/esm/bundled_modules/d3-array/src/intersection.js +21 -0
  318. package/dist/esm/bundled_modules/d3-array/src/max.js +22 -0
  319. package/dist/esm/bundled_modules/d3-array/src/mean.js +21 -0
  320. package/dist/esm/bundled_modules/d3-array/src/median.js +7 -0
  321. package/dist/esm/bundled_modules/d3-array/src/merge.js +11 -0
  322. package/dist/esm/bundled_modules/d3-array/src/min.js +22 -0
  323. package/dist/esm/bundled_modules/d3-array/src/number.js +22 -0
  324. package/dist/esm/bundled_modules/d3-array/src/permute.js +5 -0
  325. package/dist/esm/bundled_modules/d3-array/src/quantile.js +31 -0
  326. package/dist/esm/bundled_modules/d3-array/src/quickselect.js +55 -0
  327. package/dist/esm/bundled_modules/d3-array/src/range.js +15 -0
  328. package/dist/esm/bundled_modules/d3-array/src/sort.js +17 -0
  329. package/dist/esm/bundled_modules/d3-array/src/sum.js +13 -0
  330. package/dist/esm/bundled_modules/d3-array/src/ticks.js +57 -0
  331. package/dist/esm/bundled_modules/d3-array/src/union.js +13 -0
  332. package/dist/esm/bundled_modules/d3-array/src/variance.js +27 -0
  333. package/dist/esm/bundled_modules/d3-color/src/color.js +398 -0
  334. package/dist/esm/bundled_modules/d3-color/src/cubehelix.js +63 -0
  335. package/dist/esm/bundled_modules/d3-color/src/define.js +12 -0
  336. package/dist/esm/bundled_modules/d3-color/src/lab.js +117 -0
  337. package/dist/esm/bundled_modules/d3-color/src/math.js +4 -0
  338. package/dist/esm/bundled_modules/d3-delaunay/src/delaunay.js +250 -0
  339. package/dist/esm/bundled_modules/d3-delaunay/src/path.js +39 -0
  340. package/dist/esm/bundled_modules/d3-delaunay/src/polygon.js +19 -0
  341. package/dist/esm/bundled_modules/d3-delaunay/src/voronoi.js +334 -0
  342. package/dist/esm/bundled_modules/d3-dispatch/src/dispatch.js +84 -0
  343. package/dist/esm/bundled_modules/d3-dsv/src/dsv.js +166 -0
  344. package/dist/esm/bundled_modules/d3-force/src/center.js +42 -0
  345. package/dist/esm/bundled_modules/d3-force/src/collide.js +102 -0
  346. package/dist/esm/bundled_modules/d3-force/src/constant.js +7 -0
  347. package/dist/esm/bundled_modules/d3-force/src/jiggle.js +5 -0
  348. package/dist/esm/bundled_modules/d3-force/src/lcg.js +11 -0
  349. package/dist/esm/bundled_modules/d3-force/src/link.js +119 -0
  350. package/dist/esm/bundled_modules/d3-force/src/manyBody.js +118 -0
  351. package/dist/esm/bundled_modules/d3-force/src/simulation.js +158 -0
  352. package/dist/esm/bundled_modules/d3-force/src/x.js +43 -0
  353. package/dist/esm/bundled_modules/d3-force/src/y.js +43 -0
  354. package/dist/esm/bundled_modules/d3-format/src/defaultLocale.js +20 -0
  355. package/dist/esm/bundled_modules/d3-format/src/exponent.js +7 -0
  356. package/dist/esm/bundled_modules/d3-format/src/formatDecimal.js +22 -0
  357. package/dist/esm/bundled_modules/d3-format/src/formatGroup.js +20 -0
  358. package/dist/esm/bundled_modules/d3-format/src/formatNumerals.js +9 -0
  359. package/dist/esm/bundled_modules/d3-format/src/formatPrefixAuto.js +18 -0
  360. package/dist/esm/bundled_modules/d3-format/src/formatRounded.js +13 -0
  361. package/dist/esm/bundled_modules/d3-format/src/formatSpecifier.js +49 -0
  362. package/dist/esm/bundled_modules/d3-format/src/formatTrim.js +13 -0
  363. package/dist/esm/bundled_modules/d3-format/src/formatTypes.js +21 -0
  364. package/dist/esm/bundled_modules/d3-format/src/identity.js +5 -0
  365. package/dist/esm/bundled_modules/d3-format/src/locale.js +150 -0
  366. package/dist/esm/bundled_modules/d3-format/src/precisionFixed.js +7 -0
  367. package/dist/esm/bundled_modules/d3-format/src/precisionPrefix.js +7 -0
  368. package/dist/esm/bundled_modules/d3-format/src/precisionRound.js +8 -0
  369. package/dist/esm/bundled_modules/d3-geo/src/area.js +78 -0
  370. package/dist/esm/bundled_modules/d3-geo/src/bounds.js +181 -0
  371. package/dist/esm/bundled_modules/d3-geo/src/cartesian.js +35 -0
  372. package/dist/esm/bundled_modules/d3-geo/src/centroid.js +145 -0
  373. package/dist/esm/bundled_modules/d3-geo/src/circle.js +33 -0
  374. package/dist/esm/bundled_modules/d3-geo/src/clip/antimeridian.js +94 -0
  375. package/dist/esm/bundled_modules/d3-geo/src/clip/buffer.js +26 -0
  376. package/dist/esm/bundled_modules/d3-geo/src/clip/circle.js +179 -0
  377. package/dist/esm/bundled_modules/d3-geo/src/clip/index.js +133 -0
  378. package/dist/esm/bundled_modules/d3-geo/src/clip/line.js +61 -0
  379. package/dist/esm/bundled_modules/d3-geo/src/clip/rectangle.js +170 -0
  380. package/dist/esm/bundled_modules/d3-geo/src/clip/rejoin.js +105 -0
  381. package/dist/esm/bundled_modules/d3-geo/src/compose.js +14 -0
  382. package/dist/esm/bundled_modules/d3-geo/src/graticule.js +103 -0
  383. package/dist/esm/bundled_modules/d3-geo/src/identity.js +3 -0
  384. package/dist/esm/bundled_modules/d3-geo/src/math.js +33 -0
  385. package/dist/esm/bundled_modules/d3-geo/src/noop.js +3 -0
  386. package/dist/esm/bundled_modules/d3-geo/src/path/area.js +50 -0
  387. package/dist/esm/bundled_modules/d3-geo/src/path/bounds.js +28 -0
  388. package/dist/esm/bundled_modules/d3-geo/src/path/centroid.js +100 -0
  389. package/dist/esm/bundled_modules/d3-geo/src/path/context.js +47 -0
  390. package/dist/esm/bundled_modules/d3-geo/src/path/index.js +78 -0
  391. package/dist/esm/bundled_modules/d3-geo/src/path/measure.js +45 -0
  392. package/dist/esm/bundled_modules/d3-geo/src/path/string.js +88 -0
  393. package/dist/esm/bundled_modules/d3-geo/src/pointEqual.js +7 -0
  394. package/dist/esm/bundled_modules/d3-geo/src/polygonContains.js +76 -0
  395. package/dist/esm/bundled_modules/d3-geo/src/projection/albers.js +12 -0
  396. package/dist/esm/bundled_modules/d3-geo/src/projection/albersUsa.js +113 -0
  397. package/dist/esm/bundled_modules/d3-geo/src/projection/azimuthal.js +29 -0
  398. package/dist/esm/bundled_modules/d3-geo/src/projection/azimuthalEqualArea.js +19 -0
  399. package/dist/esm/bundled_modules/d3-geo/src/projection/azimuthalEquidistant.js +19 -0
  400. package/dist/esm/bundled_modules/d3-geo/src/projection/conic.js +17 -0
  401. package/dist/esm/bundled_modules/d3-geo/src/projection/conicConformal.js +40 -0
  402. package/dist/esm/bundled_modules/d3-geo/src/projection/conicEqualArea.js +35 -0
  403. package/dist/esm/bundled_modules/d3-geo/src/projection/conicEquidistant.js +34 -0
  404. package/dist/esm/bundled_modules/d3-geo/src/projection/cylindricalEqualArea.js +17 -0
  405. package/dist/esm/bundled_modules/d3-geo/src/projection/equalEarth.js +38 -0
  406. package/dist/esm/bundled_modules/d3-geo/src/projection/equirectangular.js +14 -0
  407. package/dist/esm/bundled_modules/d3-geo/src/projection/fit.js +49 -0
  408. package/dist/esm/bundled_modules/d3-geo/src/projection/gnomonic.js +18 -0
  409. package/dist/esm/bundled_modules/d3-geo/src/projection/identity.js +87 -0
  410. package/dist/esm/bundled_modules/d3-geo/src/projection/index.js +179 -0
  411. package/dist/esm/bundled_modules/d3-geo/src/projection/mercator.js +54 -0
  412. package/dist/esm/bundled_modules/d3-geo/src/projection/naturalEarth1.js +30 -0
  413. package/dist/esm/bundled_modules/d3-geo/src/projection/orthographic.js +17 -0
  414. package/dist/esm/bundled_modules/d3-geo/src/projection/resample.js +104 -0
  415. package/dist/esm/bundled_modules/d3-geo/src/projection/stereographic.js +20 -0
  416. package/dist/esm/bundled_modules/d3-geo/src/projection/transverseMercator.js +29 -0
  417. package/dist/esm/bundled_modules/d3-geo/src/rotation.js +81 -0
  418. package/dist/esm/bundled_modules/d3-geo/src/stream.js +71 -0
  419. package/dist/esm/bundled_modules/d3-geo/src/transform.js +22 -0
  420. package/dist/esm/bundled_modules/d3-geo-projection/src/math.js +18 -0
  421. package/dist/esm/bundled_modules/d3-geo-projection/src/mollweide.js +31 -0
  422. package/dist/esm/bundled_modules/d3-hierarchy/src/accessors.js +10 -0
  423. package/dist/esm/bundled_modules/d3-hierarchy/src/array.js +22 -0
  424. package/dist/esm/bundled_modules/d3-hierarchy/src/cluster.js +86 -0
  425. package/dist/esm/bundled_modules/d3-hierarchy/src/constant.js +11 -0
  426. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/ancestors.js +9 -0
  427. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/count.js +14 -0
  428. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/descendants.js +5 -0
  429. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/each.js +9 -0
  430. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/eachAfter.js +17 -0
  431. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/eachBefore.js +14 -0
  432. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/find.js +10 -0
  433. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/index.js +93 -0
  434. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/iterator.js +16 -0
  435. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/leaves.js +11 -0
  436. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/links.js +11 -0
  437. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/path.js +32 -0
  438. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/sort.js +9 -0
  439. package/dist/esm/bundled_modules/d3-hierarchy/src/hierarchy/sum.js +11 -0
  440. package/dist/esm/bundled_modules/d3-hierarchy/src/lcg.js +11 -0
  441. package/dist/esm/bundled_modules/d3-hierarchy/src/pack/enclose.js +120 -0
  442. package/dist/esm/bundled_modules/d3-hierarchy/src/pack/index.js +83 -0
  443. package/dist/esm/bundled_modules/d3-hierarchy/src/pack/siblings.js +116 -0
  444. package/dist/esm/bundled_modules/d3-hierarchy/src/partition.js +54 -0
  445. package/dist/esm/bundled_modules/d3-hierarchy/src/stratify.js +147 -0
  446. package/dist/esm/bundled_modules/d3-hierarchy/src/tree.js +239 -0
  447. package/dist/esm/bundled_modules/d3-hierarchy/src/treemap/binary.js +48 -0
  448. package/dist/esm/bundled_modules/d3-hierarchy/src/treemap/dice.js +14 -0
  449. package/dist/esm/bundled_modules/d3-hierarchy/src/treemap/index.js +96 -0
  450. package/dist/esm/bundled_modules/d3-hierarchy/src/treemap/resquarify.js +38 -0
  451. package/dist/esm/bundled_modules/d3-hierarchy/src/treemap/round.js +8 -0
  452. package/dist/esm/bundled_modules/d3-hierarchy/src/treemap/slice.js +14 -0
  453. package/dist/esm/bundled_modules/d3-hierarchy/src/treemap/sliceDice.js +8 -0
  454. package/dist/esm/bundled_modules/d3-hierarchy/src/treemap/squarify.js +68 -0
  455. package/dist/esm/bundled_modules/d3-interpolate/src/array.js +24 -0
  456. package/dist/esm/bundled_modules/d3-interpolate/src/basis.js +21 -0
  457. package/dist/esm/bundled_modules/d3-interpolate/src/basisClosed.js +15 -0
  458. package/dist/esm/bundled_modules/d3-interpolate/src/color.js +31 -0
  459. package/dist/esm/bundled_modules/d3-interpolate/src/constant.js +3 -0
  460. package/dist/esm/bundled_modules/d3-interpolate/src/cubehelix.js +31 -0
  461. package/dist/esm/bundled_modules/d3-interpolate/src/date.js +8 -0
  462. package/dist/esm/bundled_modules/d3-interpolate/src/discrete.js +8 -0
  463. package/dist/esm/bundled_modules/d3-interpolate/src/hcl.js +23 -0
  464. package/dist/esm/bundled_modules/d3-interpolate/src/hsl.js +23 -0
  465. package/dist/esm/bundled_modules/d3-interpolate/src/hue.js +11 -0
  466. package/dist/esm/bundled_modules/d3-interpolate/src/index.js +21 -0
  467. package/dist/esm/bundled_modules/d3-interpolate/src/lab.js +18 -0
  468. package/dist/esm/bundled_modules/d3-interpolate/src/number.js +7 -0
  469. package/dist/esm/bundled_modules/d3-interpolate/src/numberArray.js +16 -0
  470. package/dist/esm/bundled_modules/d3-interpolate/src/object.js +25 -0
  471. package/dist/esm/bundled_modules/d3-interpolate/src/piecewise.js +13 -0
  472. package/dist/esm/bundled_modules/d3-interpolate/src/quantize.js +7 -0
  473. package/dist/esm/bundled_modules/d3-interpolate/src/rgb.js +57 -0
  474. package/dist/esm/bundled_modules/d3-interpolate/src/round.js +7 -0
  475. package/dist/esm/bundled_modules/d3-interpolate/src/string.js +66 -0
  476. package/dist/esm/bundled_modules/d3-interpolate/src/transform/decompose.js +28 -0
  477. package/dist/esm/bundled_modules/d3-interpolate/src/transform/index.js +65 -0
  478. package/dist/esm/bundled_modules/d3-interpolate/src/transform/parse.js +20 -0
  479. package/dist/esm/bundled_modules/d3-interpolate/src/value.js +24 -0
  480. package/dist/esm/bundled_modules/d3-interpolate/src/zoom.js +73 -0
  481. package/dist/esm/bundled_modules/d3-path/src/path.js +154 -0
  482. package/dist/esm/bundled_modules/d3-quadtree/src/add.js +86 -0
  483. package/dist/esm/bundled_modules/d3-quadtree/src/cover.js +45 -0
  484. package/dist/esm/bundled_modules/d3-quadtree/src/data.js +9 -0
  485. package/dist/esm/bundled_modules/d3-quadtree/src/extent.js +7 -0
  486. package/dist/esm/bundled_modules/d3-quadtree/src/find.js +72 -0
  487. package/dist/esm/bundled_modules/d3-quadtree/src/quad.js +9 -0
  488. package/dist/esm/bundled_modules/d3-quadtree/src/quadtree.js +75 -0
  489. package/dist/esm/bundled_modules/d3-quadtree/src/remove.js +64 -0
  490. package/dist/esm/bundled_modules/d3-quadtree/src/root.js +5 -0
  491. package/dist/esm/bundled_modules/d3-quadtree/src/size.js +9 -0
  492. package/dist/esm/bundled_modules/d3-quadtree/src/visit.js +18 -0
  493. package/dist/esm/bundled_modules/d3-quadtree/src/visitAfter.js +23 -0
  494. package/dist/esm/bundled_modules/d3-quadtree/src/x.js +9 -0
  495. package/dist/esm/bundled_modules/d3-quadtree/src/y.js +9 -0
  496. package/dist/esm/bundled_modules/d3-scale/src/constant.js +7 -0
  497. package/dist/esm/bundled_modules/d3-scale/src/continuous.js +129 -0
  498. package/dist/esm/bundled_modules/d3-scale/src/diverging.js +108 -0
  499. package/dist/esm/bundled_modules/d3-scale/src/identity.js +30 -0
  500. package/dist/esm/bundled_modules/d3-scale/src/init.js +28 -0
  501. package/dist/esm/bundled_modules/d3-scale/src/linear.js +72 -0
  502. package/dist/esm/bundled_modules/d3-scale/src/log.js +143 -0
  503. package/dist/esm/bundled_modules/d3-scale/src/nice.js +20 -0
  504. package/dist/esm/bundled_modules/d3-scale/src/number.js +5 -0
  505. package/dist/esm/bundled_modules/d3-scale/src/ordinal.js +48 -0
  506. package/dist/esm/bundled_modules/d3-scale/src/pow.js +52 -0
  507. package/dist/esm/bundled_modules/d3-scale/src/quantile.js +61 -0
  508. package/dist/esm/bundled_modules/d3-scale/src/quantize.js +58 -0
  509. package/dist/esm/bundled_modules/d3-scale/src/sequential.js +110 -0
  510. package/dist/esm/bundled_modules/d3-scale/src/symlog.js +37 -0
  511. package/dist/esm/bundled_modules/d3-scale/src/threshold.js +41 -0
  512. package/dist/esm/bundled_modules/d3-scale/src/tickFormat.js +35 -0
  513. package/dist/esm/bundled_modules/d3-scale/src/time.js +80 -0
  514. package/dist/esm/bundled_modules/d3-scale/src/utcTime.js +17 -0
  515. package/dist/esm/bundled_modules/d3-scale-chromatic/src/categorical/Accent.js +5 -0
  516. package/dist/esm/bundled_modules/d3-scale-chromatic/src/categorical/Dark2.js +5 -0
  517. package/dist/esm/bundled_modules/d3-scale-chromatic/src/categorical/Paired.js +5 -0
  518. package/dist/esm/bundled_modules/d3-scale-chromatic/src/categorical/Pastel1.js +5 -0
  519. package/dist/esm/bundled_modules/d3-scale-chromatic/src/categorical/Pastel2.js +5 -0
  520. package/dist/esm/bundled_modules/d3-scale-chromatic/src/categorical/Set1.js +5 -0
  521. package/dist/esm/bundled_modules/d3-scale-chromatic/src/categorical/Set2.js +5 -0
  522. package/dist/esm/bundled_modules/d3-scale-chromatic/src/categorical/Set3.js +5 -0
  523. package/dist/esm/bundled_modules/d3-scale-chromatic/src/categorical/category10.js +5 -0
  524. package/dist/esm/bundled_modules/d3-scale-chromatic/src/categorical/observable10.js +5 -0
  525. package/dist/esm/bundled_modules/d3-scale-chromatic/src/colors.js +7 -0
  526. package/dist/esm/bundled_modules/d3-shape/src/arc.js +270 -0
  527. package/dist/esm/bundled_modules/d3-shape/src/area.js +114 -0
  528. package/dist/esm/bundled_modules/d3-shape/src/array.js +7 -0
  529. package/dist/esm/bundled_modules/d3-shape/src/constant.js +7 -0
  530. package/dist/esm/bundled_modules/d3-shape/src/curve/basis.js +53 -0
  531. package/dist/esm/bundled_modules/d3-shape/src/curve/basisClosed.js +54 -0
  532. package/dist/esm/bundled_modules/d3-shape/src/curve/basisOpen.js +41 -0
  533. package/dist/esm/bundled_modules/d3-shape/src/curve/bundle.js +58 -0
  534. package/dist/esm/bundled_modules/d3-shape/src/curve/cardinal.js +63 -0
  535. package/dist/esm/bundled_modules/d3-shape/src/curve/cardinalClosed.js +63 -0
  536. package/dist/esm/bundled_modules/d3-shape/src/curve/cardinalOpen.js +51 -0
  537. package/dist/esm/bundled_modules/d3-shape/src/curve/catmullRom.js +90 -0
  538. package/dist/esm/bundled_modules/d3-shape/src/curve/catmullRomClosed.js +76 -0
  539. package/dist/esm/bundled_modules/d3-shape/src/curve/catmullRomOpen.js +64 -0
  540. package/dist/esm/bundled_modules/d3-shape/src/curve/linear.js +33 -0
  541. package/dist/esm/bundled_modules/d3-shape/src/curve/linearClosed.js +27 -0
  542. package/dist/esm/bundled_modules/d3-shape/src/curve/monotone.js +106 -0
  543. package/dist/esm/bundled_modules/d3-shape/src/curve/natural.js +67 -0
  544. package/dist/esm/bundled_modules/d3-shape/src/curve/step.js +55 -0
  545. package/dist/esm/bundled_modules/d3-shape/src/line.js +60 -0
  546. package/dist/esm/bundled_modules/d3-shape/src/math.js +22 -0
  547. package/dist/esm/bundled_modules/d3-shape/src/noop.js +3 -0
  548. package/dist/esm/bundled_modules/d3-shape/src/path.js +21 -0
  549. package/dist/esm/bundled_modules/d3-shape/src/point.js +9 -0
  550. package/dist/esm/bundled_modules/d3-shape/src/symbol/circle.js +11 -0
  551. package/dist/esm/bundled_modules/d3-shape/src/symbol.js +34 -0
  552. package/dist/esm/bundled_modules/d3-time/src/day.js +37 -0
  553. package/dist/esm/bundled_modules/d3-time/src/duration.js +9 -0
  554. package/dist/esm/bundled_modules/d3-time/src/hour.js +28 -0
  555. package/dist/esm/bundled_modules/d3-time/src/interval.js +71 -0
  556. package/dist/esm/bundled_modules/d3-time/src/millisecond.js +27 -0
  557. package/dist/esm/bundled_modules/d3-time/src/minute.js +28 -0
  558. package/dist/esm/bundled_modules/d3-time/src/month.js +29 -0
  559. package/dist/esm/bundled_modules/d3-time/src/second.js +16 -0
  560. package/dist/esm/bundled_modules/d3-time/src/ticks.js +59 -0
  561. package/dist/esm/bundled_modules/d3-time/src/week.js +58 -0
  562. package/dist/esm/bundled_modules/d3-time/src/year.js +51 -0
  563. package/dist/esm/bundled_modules/d3-time-format/src/defaultLocale.js +29 -0
  564. package/dist/esm/bundled_modules/d3-time-format/src/locale.js +690 -0
  565. package/dist/esm/bundled_modules/d3-timer/src/interval.js +19 -0
  566. package/dist/esm/bundled_modules/d3-timer/src/timer.js +112 -0
  567. package/dist/esm/bundled_modules/delaunator/index.js +481 -0
  568. package/dist/esm/bundled_modules/internmap/src/index.js +63 -0
  569. package/dist/esm/bundled_modules/json-stringify-pretty-compact/index.js +100 -0
  570. package/dist/esm/bundled_modules/robust-predicates/esm/orient2d.js +182 -0
  571. package/dist/esm/bundled_modules/robust-predicates/esm/util.js +88 -0
  572. package/dist/esm/bundled_modules/topojson-client/src/feature.js +72 -0
  573. package/dist/esm/bundled_modules/topojson-client/src/identity.js +5 -0
  574. package/dist/esm/bundled_modules/topojson-client/src/mesh.js +55 -0
  575. package/dist/esm/bundled_modules/topojson-client/src/reverse.js +6 -0
  576. package/dist/esm/bundled_modules/topojson-client/src/stitch.js +75 -0
  577. package/dist/esm/bundled_modules/topojson-client/src/transform.js +21 -0
  578. package/dist/esm/bundled_modules/vega/build/vega.module.js +38 -0
  579. package/dist/esm/bundled_modules/vega-canvas/build/vega-canvas.browser.js +14 -0
  580. package/dist/esm/bundled_modules/vega-crossfilter/build/vega-crossfilter.js +673 -0
  581. package/dist/esm/bundled_modules/vega-dataflow/build/vega-dataflow.js +2080 -0
  582. package/dist/esm/bundled_modules/vega-embed/build/embed.js +2932 -0
  583. package/dist/esm/bundled_modules/vega-encode/build/vega-encode.js +952 -0
  584. package/dist/esm/bundled_modules/vega-event-selector/build/vega-event-selector.js +190 -0
  585. package/dist/esm/bundled_modules/vega-expression/build/vega-expression.js +1597 -0
  586. package/dist/esm/bundled_modules/vega-force/build/vega-force.js +293 -0
  587. package/dist/esm/bundled_modules/vega-format/build/vega-format.js +191 -0
  588. package/dist/esm/bundled_modules/vega-functions/build/vega-functions.js +779 -0
  589. package/dist/esm/bundled_modules/vega-geo/build/vega-geo.js +1322 -0
  590. package/dist/esm/bundled_modules/vega-hierarchy/build/vega-hierarchy.js +572 -0
  591. package/dist/esm/bundled_modules/vega-interpreter/build/vega-interpreter.js +308 -0
  592. package/dist/esm/bundled_modules/vega-label/build/vega-label.js +874 -0
  593. package/dist/esm/bundled_modules/vega-lite/build/index.js +20110 -0
  594. package/dist/esm/bundled_modules/vega-loader/build/vega-loader.browser.js +328 -0
  595. package/dist/esm/bundled_modules/vega-parser/build/vega-parser.js +3783 -0
  596. package/dist/esm/bundled_modules/vega-projection/build/vega-projection.js +86 -0
  597. package/dist/esm/bundled_modules/vega-regression/build/vega-regression.js +233 -0
  598. package/dist/esm/bundled_modules/vega-runtime/build/vega-runtime.js +586 -0
  599. package/dist/esm/bundled_modules/vega-scale/build/vega-scale.js +799 -0
  600. package/dist/esm/bundled_modules/vega-scenegraph/build/vega-scenegraph.js +4982 -0
  601. package/dist/esm/bundled_modules/vega-schema-url-parser/dist/parser.modern.js +3 -0
  602. package/dist/esm/bundled_modules/vega-selections/build/vega-selection.js +336 -0
  603. package/dist/esm/bundled_modules/vega-statistics/build/vega-statistics.js +1157 -0
  604. package/dist/esm/bundled_modules/vega-themes/build/index.js +837 -0
  605. package/dist/esm/bundled_modules/vega-time/build/vega-time.js +314 -0
  606. package/dist/esm/bundled_modules/vega-tooltip/build/index.js +339 -0
  607. package/dist/esm/bundled_modules/vega-transforms/build/vega-transforms.js +3740 -0
  608. package/dist/esm/bundled_modules/vega-util/build/vega-util.js +753 -0
  609. package/dist/esm/bundled_modules/vega-view/build/vega-view.js +1304 -0
  610. package/dist/esm/bundled_modules/vega-view-transforms/build/vega-view-transforms.js +1306 -0
  611. package/dist/esm/bundled_modules/vega-voronoi/build/vega-voronoi.js +78 -0
  612. package/dist/esm/bundled_modules/vega-wordcloud/build/vega-wordcloud.js +538 -0
  613. package/dist/esm/unstable/extras/chart/BarChart.js +40 -0
  614. package/dist/esm/unstable/extras/chart/Chart.js +96 -0
  615. package/dist/esm/unstable/extras/chart/DistributionChart.js +82 -0
  616. package/dist/esm/unstable/extras/chart/DonutChart.js +41 -0
  617. package/dist/esm/unstable/extras/chart/LineChart.js +43 -0
  618. package/dist/esm/unstable/extras/chart/PieChart.js +37 -0
  619. package/dist/esm/unstable/extras/chart/TimelineChart.js +46 -0
  620. package/dist/esm/unstable/extras/chart/index.js +8 -0
  621. package/dist/types/unstable/extras/chart/BarChart.d.ts +16 -0
  622. package/dist/types/unstable/extras/chart/Chart.d.ts +33 -0
  623. package/dist/types/unstable/extras/chart/DistributionChart.d.ts +18 -0
  624. package/dist/types/unstable/extras/chart/DonutChart.d.ts +16 -0
  625. package/dist/types/unstable/extras/chart/LineChart.d.ts +16 -0
  626. package/dist/types/unstable/extras/chart/PieChart.d.ts +14 -0
  627. package/dist/types/unstable/extras/chart/TimelineChart.d.ts +15 -0
  628. package/dist/types/unstable/extras/chart/index.d.ts +15 -0
  629. package/package.json +1 -1
@@ -0,0 +1,3781 @@
1
+ 'use strict';
2
+
3
+ var vegaUtil = require('../../vega-util/build/vega-util.js');
4
+ var vegaDataflow = require('../../vega-dataflow/build/vega-dataflow.js');
5
+ var vegaStatistics = require('../../vega-statistics/build/vega-statistics.js');
6
+ var vegaTime = require('../../vega-time/build/vega-time.js');
7
+ var range = require('../../d3-array/src/range.js');
8
+ var bisector = require('../../d3-array/src/bisector.js');
9
+ var max = require('../../d3-array/src/max.js');
10
+ var min = require('../../d3-array/src/min.js');
11
+ var mean = require('../../d3-array/src/mean.js');
12
+ var median = require('../../d3-array/src/median.js');
13
+
14
+ function multikey(f) {
15
+ return x => {
16
+ const n = f.length;
17
+ let i = 1,
18
+ k = String(f[0](x));
19
+ for (; i < n; ++i) {
20
+ k += '|' + f[i](x);
21
+ }
22
+ return k;
23
+ };
24
+ }
25
+ function groupkey(fields) {
26
+ return !fields || !fields.length ? function () {
27
+ return '';
28
+ } : fields.length === 1 ? fields[0] : multikey(fields);
29
+ }
30
+
31
+ function measureName(op, field, as) {
32
+ return as || op + (!field ? '' : '_' + field);
33
+ }
34
+ const noop = () => {};
35
+ const base_op = {
36
+ init: noop,
37
+ add: noop,
38
+ rem: noop,
39
+ idx: 0
40
+ };
41
+ const AggregateOps = {
42
+ values: {
43
+ init: m => m.cell.store = true,
44
+ value: m => m.cell.data.values(),
45
+ idx: -1
46
+ },
47
+ count: {
48
+ value: m => m.cell.num
49
+ },
50
+ __count__: {
51
+ value: m => m.missing + m.valid
52
+ },
53
+ missing: {
54
+ value: m => m.missing
55
+ },
56
+ valid: {
57
+ value: m => m.valid
58
+ },
59
+ sum: {
60
+ init: m => m.sum = 0,
61
+ value: m => m.valid ? m.sum : undefined,
62
+ add: (m, v) => m.sum += +v,
63
+ rem: (m, v) => m.sum -= v
64
+ },
65
+ product: {
66
+ init: m => m.product = 1,
67
+ value: m => m.valid ? m.product : undefined,
68
+ add: (m, v) => m.product *= v,
69
+ rem: (m, v) => m.product /= v
70
+ },
71
+ mean: {
72
+ init: m => m.mean = 0,
73
+ value: m => m.valid ? m.mean : undefined,
74
+ add: (m, v) => (m.mean_d = v - m.mean, m.mean += m.mean_d / m.valid),
75
+ rem: (m, v) => (m.mean_d = v - m.mean, m.mean -= m.valid ? m.mean_d / m.valid : m.mean)
76
+ },
77
+ average: {
78
+ value: m => m.valid ? m.mean : undefined,
79
+ req: ['mean'],
80
+ idx: 1
81
+ },
82
+ variance: {
83
+ init: m => m.dev = 0,
84
+ value: m => m.valid > 1 ? m.dev / (m.valid - 1) : undefined,
85
+ add: (m, v) => m.dev += m.mean_d * (v - m.mean),
86
+ rem: (m, v) => m.dev -= m.mean_d * (v - m.mean),
87
+ req: ['mean'],
88
+ idx: 1
89
+ },
90
+ variancep: {
91
+ value: m => m.valid > 1 ? m.dev / m.valid : undefined,
92
+ req: ['variance'],
93
+ idx: 2
94
+ },
95
+ stdev: {
96
+ value: m => m.valid > 1 ? Math.sqrt(m.dev / (m.valid - 1)) : undefined,
97
+ req: ['variance'],
98
+ idx: 2
99
+ },
100
+ stdevp: {
101
+ value: m => m.valid > 1 ? Math.sqrt(m.dev / m.valid) : undefined,
102
+ req: ['variance'],
103
+ idx: 2
104
+ },
105
+ stderr: {
106
+ value: m => m.valid > 1 ? Math.sqrt(m.dev / (m.valid * (m.valid - 1))) : undefined,
107
+ req: ['variance'],
108
+ idx: 2
109
+ },
110
+ distinct: {
111
+ value: m => m.cell.data.distinct(m.get),
112
+ req: ['values'],
113
+ idx: 3
114
+ },
115
+ ci0: {
116
+ value: m => m.cell.data.ci0(m.get),
117
+ req: ['values'],
118
+ idx: 3
119
+ },
120
+ ci1: {
121
+ value: m => m.cell.data.ci1(m.get),
122
+ req: ['values'],
123
+ idx: 3
124
+ },
125
+ median: {
126
+ value: m => m.cell.data.q2(m.get),
127
+ req: ['values'],
128
+ idx: 3
129
+ },
130
+ q1: {
131
+ value: m => m.cell.data.q1(m.get),
132
+ req: ['values'],
133
+ idx: 3
134
+ },
135
+ q3: {
136
+ value: m => m.cell.data.q3(m.get),
137
+ req: ['values'],
138
+ idx: 3
139
+ },
140
+ min: {
141
+ init: m => m.min = undefined,
142
+ value: m => m.min = Number.isNaN(m.min) ? m.cell.data.min(m.get) : m.min,
143
+ add: (m, v) => {
144
+ if (v < m.min || m.min === undefined) m.min = v;
145
+ },
146
+ rem: (m, v) => {
147
+ if (v <= m.min) m.min = NaN;
148
+ },
149
+ req: ['values'],
150
+ idx: 4
151
+ },
152
+ max: {
153
+ init: m => m.max = undefined,
154
+ value: m => m.max = Number.isNaN(m.max) ? m.cell.data.max(m.get) : m.max,
155
+ add: (m, v) => {
156
+ if (v > m.max || m.max === undefined) m.max = v;
157
+ },
158
+ rem: (m, v) => {
159
+ if (v >= m.max) m.max = NaN;
160
+ },
161
+ req: ['values'],
162
+ idx: 4
163
+ },
164
+ argmin: {
165
+ init: m => m.argmin = undefined,
166
+ value: m => m.argmin || m.cell.data.argmin(m.get),
167
+ add: (m, v, t) => {
168
+ if (v < m.min) m.argmin = t;
169
+ },
170
+ rem: (m, v) => {
171
+ if (v <= m.min) m.argmin = undefined;
172
+ },
173
+ req: ['min', 'values'],
174
+ idx: 3
175
+ },
176
+ argmax: {
177
+ init: m => m.argmax = undefined,
178
+ value: m => m.argmax || m.cell.data.argmax(m.get),
179
+ add: (m, v, t) => {
180
+ if (v > m.max) m.argmax = t;
181
+ },
182
+ rem: (m, v) => {
183
+ if (v >= m.max) m.argmax = undefined;
184
+ },
185
+ req: ['max', 'values'],
186
+ idx: 3
187
+ },
188
+ exponential: {
189
+ init: (m, r) => {
190
+ m.exp = 0;
191
+ m.exp_r = r;
192
+ },
193
+ value: m => m.valid ? m.exp * (1 - m.exp_r) / (1 - m.exp_r ** m.valid) : undefined,
194
+ add: (m, v) => m.exp = m.exp_r * m.exp + v,
195
+ rem: (m, v) => m.exp = (m.exp - v / m.exp_r ** (m.valid - 1)) / m.exp_r
196
+ },
197
+ exponentialb: {
198
+ value: m => m.valid ? m.exp * (1 - m.exp_r) : undefined,
199
+ req: ['exponential'],
200
+ idx: 1
201
+ }
202
+ };
203
+ const ValidAggregateOps = Object.keys(AggregateOps).filter(d => d !== '__count__');
204
+ function measure(key, value) {
205
+ return (out, aggregate_param) => vegaUtil.extend({
206
+ name: key,
207
+ aggregate_param: aggregate_param,
208
+ out: out || key
209
+ }, base_op, value);
210
+ }
211
+ [...ValidAggregateOps, '__count__'].forEach(key => {
212
+ AggregateOps[key] = measure(key, AggregateOps[key]);
213
+ });
214
+ function createMeasure(op, param, name) {
215
+ return AggregateOps[op](name, param);
216
+ }
217
+ function compareIndex(a, b) {
218
+ return a.idx - b.idx;
219
+ }
220
+ function resolve(agg) {
221
+ const map = {};
222
+ agg.forEach(a => map[a.name] = a);
223
+ const getreqs = a => {
224
+ if (!a.req) return;
225
+ a.req.forEach(key => {
226
+ if (!map[key]) getreqs(map[key] = AggregateOps[key]());
227
+ });
228
+ };
229
+ agg.forEach(getreqs);
230
+ return Object.values(map).sort(compareIndex);
231
+ }
232
+ function init() {
233
+ this.valid = 0;
234
+ this.missing = 0;
235
+ this._ops.forEach(op => op.aggregate_param == null ? op.init(this) : op.init(this, op.aggregate_param));
236
+ }
237
+ function add(v, t) {
238
+ if (v == null || v === '') {
239
+ ++this.missing;
240
+ return;
241
+ }
242
+ if (v !== v) return;
243
+ ++this.valid;
244
+ this._ops.forEach(op => op.add(this, v, t));
245
+ }
246
+ function rem(v, t) {
247
+ if (v == null || v === '') {
248
+ --this.missing;
249
+ return;
250
+ }
251
+ if (v !== v) return;
252
+ --this.valid;
253
+ this._ops.forEach(op => op.rem(this, v, t));
254
+ }
255
+ function set(t) {
256
+ this._out.forEach(op => t[op.out] = op.value(this));
257
+ return t;
258
+ }
259
+ function compileMeasures(agg, field) {
260
+ const get = field || vegaUtil.identity,
261
+ ops = resolve(agg),
262
+ out = agg.slice().sort(compareIndex);
263
+ function ctr(cell) {
264
+ this._ops = ops;
265
+ this._out = out;
266
+ this.cell = cell;
267
+ this.init();
268
+ }
269
+ ctr.prototype.init = init;
270
+ ctr.prototype.add = add;
271
+ ctr.prototype.rem = rem;
272
+ ctr.prototype.set = set;
273
+ ctr.prototype.get = get;
274
+ ctr.fields = agg.map(op => op.out);
275
+ return ctr;
276
+ }
277
+
278
+ function TupleStore(key) {
279
+ this._key = key ? vegaUtil.field(key) : vegaDataflow.tupleid;
280
+ this.reset();
281
+ }
282
+ const prototype$1 = TupleStore.prototype;
283
+ prototype$1.reset = function () {
284
+ this._add = [];
285
+ this._rem = [];
286
+ this._ext = null;
287
+ this._get = null;
288
+ this._q = null;
289
+ };
290
+ prototype$1.add = function (v) {
291
+ this._add.push(v);
292
+ };
293
+ prototype$1.rem = function (v) {
294
+ this._rem.push(v);
295
+ };
296
+ prototype$1.values = function () {
297
+ this._get = null;
298
+ if (this._rem.length === 0) return this._add;
299
+ const a = this._add,
300
+ r = this._rem,
301
+ k = this._key,
302
+ n = a.length,
303
+ m = r.length,
304
+ x = Array(n - m),
305
+ map = {};
306
+ let i, j, v;
307
+
308
+ // use unique key field to clear removed values
309
+ for (i = 0; i < m; ++i) {
310
+ map[k(r[i])] = 1;
311
+ }
312
+ for (i = 0, j = 0; i < n; ++i) {
313
+ if (map[k(v = a[i])]) {
314
+ map[k(v)] = 0;
315
+ } else {
316
+ x[j++] = v;
317
+ }
318
+ }
319
+ this._rem = [];
320
+ return this._add = x;
321
+ };
322
+
323
+ // memoizing statistics methods
324
+
325
+ prototype$1.distinct = function (get) {
326
+ const v = this.values(),
327
+ map = {};
328
+ let n = v.length,
329
+ count = 0,
330
+ s;
331
+ while (--n >= 0) {
332
+ s = get(v[n]) + '';
333
+ if (!vegaUtil.hasOwnProperty(map, s)) {
334
+ map[s] = 1;
335
+ ++count;
336
+ }
337
+ }
338
+ return count;
339
+ };
340
+ prototype$1.extent = function (get) {
341
+ if (this._get !== get || !this._ext) {
342
+ const v = this.values(),
343
+ i = vegaUtil.extentIndex(v, get);
344
+ this._ext = [v[i[0]], v[i[1]]];
345
+ this._get = get;
346
+ }
347
+ return this._ext;
348
+ };
349
+ prototype$1.argmin = function (get) {
350
+ return this.extent(get)[0] || {};
351
+ };
352
+ prototype$1.argmax = function (get) {
353
+ return this.extent(get)[1] || {};
354
+ };
355
+ prototype$1.min = function (get) {
356
+ const m = this.extent(get)[0];
357
+ return m != null ? get(m) : undefined;
358
+ };
359
+ prototype$1.max = function (get) {
360
+ const m = this.extent(get)[1];
361
+ return m != null ? get(m) : undefined;
362
+ };
363
+ prototype$1.quartile = function (get) {
364
+ if (this._get !== get || !this._q) {
365
+ this._q = vegaStatistics.quartiles(this.values(), get);
366
+ this._get = get;
367
+ }
368
+ return this._q;
369
+ };
370
+ prototype$1.q1 = function (get) {
371
+ return this.quartile(get)[0];
372
+ };
373
+ prototype$1.q2 = function (get) {
374
+ return this.quartile(get)[1];
375
+ };
376
+ prototype$1.q3 = function (get) {
377
+ return this.quartile(get)[2];
378
+ };
379
+ prototype$1.ci = function (get) {
380
+ if (this._get !== get || !this._ci) {
381
+ this._ci = vegaStatistics.bootstrapCI(this.values(), 1000, 0.05, get);
382
+ this._get = get;
383
+ }
384
+ return this._ci;
385
+ };
386
+ prototype$1.ci0 = function (get) {
387
+ return this.ci(get)[0];
388
+ };
389
+ prototype$1.ci1 = function (get) {
390
+ return this.ci(get)[1];
391
+ };
392
+
393
+ /**
394
+ * Group-by aggregation operator.
395
+ * @constructor
396
+ * @param {object} params - The parameters for this operator.
397
+ * @param {Array<function(object): *>} [params.groupby] - An array of accessors to groupby.
398
+ * @param {Array<function(object): *>} [params.fields] - An array of accessors to aggregate.
399
+ * @param {Array<string>} [params.ops] - An array of strings indicating aggregation operations.
400
+ * @param {Array<number>} [params.aggregate_params] - An optional array of parameters for aggregation operations.
401
+ * @param {Array<string>} [params.as] - An array of output field names for aggregated values.
402
+ * @param {boolean} [params.cross=false] - A flag indicating that the full
403
+ * cross-product of groupby values should be generated, including empty cells.
404
+ * If true, the drop parameter is ignored and empty cells are retained.
405
+ * @param {boolean} [params.drop=true] - A flag indicating if empty cells should be removed.
406
+ */
407
+ function Aggregate(params) {
408
+ vegaDataflow.Transform.call(this, null, params);
409
+ this._adds = []; // array of added output tuples
410
+ this._mods = []; // array of modified output tuples
411
+ this._alen = 0; // number of active added tuples
412
+ this._mlen = 0; // number of active modified tuples
413
+ this._drop = true; // should empty aggregation cells be removed
414
+ this._cross = false; // produce full cross-product of group-by values
415
+
416
+ this._dims = []; // group-by dimension accessors
417
+ this._dnames = []; // group-by dimension names
418
+
419
+ this._measures = []; // collection of aggregation monoids
420
+ this._countOnly = false; // flag indicating only count aggregation
421
+ this._counts = null; // collection of count fields
422
+ this._prev = null; // previous aggregation cells
423
+
424
+ this._inputs = null; // array of dependent input tuple field names
425
+ this._outputs = null; // array of output tuple field names
426
+ }
427
+ Aggregate.Definition = {
428
+ 'type': 'Aggregate',
429
+ 'metadata': {
430
+ 'generates': true,
431
+ 'changes': true
432
+ },
433
+ 'params': [{
434
+ 'name': 'groupby',
435
+ 'type': 'field',
436
+ 'array': true
437
+ }, {
438
+ 'name': 'ops',
439
+ 'type': 'enum',
440
+ 'array': true,
441
+ 'values': ValidAggregateOps
442
+ }, {
443
+ 'name': 'aggregate_params',
444
+ 'type': 'number',
445
+ 'null': true,
446
+ 'array': true
447
+ }, {
448
+ 'name': 'fields',
449
+ 'type': 'field',
450
+ 'null': true,
451
+ 'array': true
452
+ }, {
453
+ 'name': 'as',
454
+ 'type': 'string',
455
+ 'null': true,
456
+ 'array': true
457
+ }, {
458
+ 'name': 'drop',
459
+ 'type': 'boolean',
460
+ 'default': true
461
+ }, {
462
+ 'name': 'cross',
463
+ 'type': 'boolean',
464
+ 'default': false
465
+ }, {
466
+ 'name': 'key',
467
+ 'type': 'field'
468
+ }]
469
+ };
470
+ vegaUtil.inherits(Aggregate, vegaDataflow.Transform, {
471
+ transform(_, pulse) {
472
+ const aggr = this,
473
+ out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS),
474
+ mod = _.modified();
475
+ aggr.stamp = out.stamp;
476
+ if (aggr.value && (mod || pulse.modified(aggr._inputs, true))) {
477
+ aggr._prev = aggr.value;
478
+ aggr.value = mod ? aggr.init(_) : Object.create(null);
479
+ pulse.visit(pulse.SOURCE, t => aggr.add(t));
480
+ } else {
481
+ aggr.value = aggr.value || aggr.init(_);
482
+ pulse.visit(pulse.REM, t => aggr.rem(t));
483
+ pulse.visit(pulse.ADD, t => aggr.add(t));
484
+ }
485
+
486
+ // Indicate output fields and return aggregate tuples.
487
+ out.modifies(aggr._outputs);
488
+
489
+ // Should empty cells be dropped?
490
+ aggr._drop = _.drop !== false;
491
+
492
+ // If domain cross-product requested, generate empty cells as needed
493
+ // and ensure that empty cells are not dropped
494
+ if (_.cross && aggr._dims.length > 1) {
495
+ aggr._drop = false;
496
+ aggr.cross();
497
+ }
498
+ if (pulse.clean() && aggr._drop) {
499
+ out.clean(true).runAfter(() => this.clean());
500
+ }
501
+ return aggr.changes(out);
502
+ },
503
+ cross() {
504
+ const aggr = this,
505
+ curr = aggr.value,
506
+ dims = aggr._dnames,
507
+ vals = dims.map(() => ({})),
508
+ n = dims.length;
509
+
510
+ // collect all group-by domain values
511
+ function collect(cells) {
512
+ let key, i, t, v;
513
+ for (key in cells) {
514
+ t = cells[key].tuple;
515
+ for (i = 0; i < n; ++i) {
516
+ vals[i][v = t[dims[i]]] = v;
517
+ }
518
+ }
519
+ }
520
+ collect(aggr._prev);
521
+ collect(curr);
522
+
523
+ // iterate over key cross-product, create cells as needed
524
+ function generate(base, tuple, index) {
525
+ const name = dims[index],
526
+ v = vals[index++];
527
+ for (const k in v) {
528
+ const key = base ? base + '|' + k : k;
529
+ tuple[name] = v[k];
530
+ if (index < n) generate(key, tuple, index);else if (!curr[key]) aggr.cell(key, tuple);
531
+ }
532
+ }
533
+ generate('', {}, 0);
534
+ },
535
+ init(_) {
536
+ // initialize input and output fields
537
+ const inputs = this._inputs = [],
538
+ outputs = this._outputs = [],
539
+ inputMap = {};
540
+ function inputVisit(get) {
541
+ const fields = vegaUtil.array(vegaUtil.accessorFields(get)),
542
+ n = fields.length;
543
+ let i = 0,
544
+ f;
545
+ for (; i < n; ++i) {
546
+ if (!inputMap[f = fields[i]]) {
547
+ inputMap[f] = 1;
548
+ inputs.push(f);
549
+ }
550
+ }
551
+ }
552
+
553
+ // initialize group-by dimensions
554
+ this._dims = vegaUtil.array(_.groupby);
555
+ this._dnames = this._dims.map(d => {
556
+ const dname = vegaUtil.accessorName(d);
557
+ inputVisit(d);
558
+ outputs.push(dname);
559
+ return dname;
560
+ });
561
+ this.cellkey = _.key ? _.key : groupkey(this._dims);
562
+
563
+ // initialize aggregate measures
564
+ this._countOnly = true;
565
+ this._counts = [];
566
+ this._measures = [];
567
+ const fields = _.fields || [null],
568
+ ops = _.ops || ['count'],
569
+ aggregate_params = _.aggregate_params || [null],
570
+ as = _.as || [],
571
+ n = fields.length,
572
+ map = {};
573
+ let field, op, aggregate_param, m, mname, outname, i;
574
+ if (n !== ops.length) {
575
+ vegaUtil.error('Unmatched number of fields and aggregate ops.');
576
+ }
577
+ for (i = 0; i < n; ++i) {
578
+ field = fields[i];
579
+ op = ops[i];
580
+ aggregate_param = aggregate_params[i] || null;
581
+ if (field == null && op !== 'count') {
582
+ vegaUtil.error('Null aggregate field specified.');
583
+ }
584
+ mname = vegaUtil.accessorName(field);
585
+ outname = measureName(op, mname, as[i]);
586
+ outputs.push(outname);
587
+ if (op === 'count') {
588
+ this._counts.push(outname);
589
+ continue;
590
+ }
591
+ m = map[mname];
592
+ if (!m) {
593
+ inputVisit(field);
594
+ m = map[mname] = [];
595
+ m.field = field;
596
+ this._measures.push(m);
597
+ }
598
+ if (op !== 'count') this._countOnly = false;
599
+ m.push(createMeasure(op, aggregate_param, outname));
600
+ }
601
+ this._measures = this._measures.map(m => compileMeasures(m, m.field));
602
+ return Object.create(null); // aggregation cells (this.value)
603
+ },
604
+ // -- Cell Management -----
605
+
606
+ cellkey: groupkey(),
607
+ cell(key, t) {
608
+ let cell = this.value[key];
609
+ if (!cell) {
610
+ cell = this.value[key] = this.newcell(key, t);
611
+ this._adds[this._alen++] = cell;
612
+ } else if (cell.num === 0 && this._drop && cell.stamp < this.stamp) {
613
+ cell.stamp = this.stamp;
614
+ this._adds[this._alen++] = cell;
615
+ } else if (cell.stamp < this.stamp) {
616
+ cell.stamp = this.stamp;
617
+ this._mods[this._mlen++] = cell;
618
+ }
619
+ return cell;
620
+ },
621
+ newcell(key, t) {
622
+ const cell = {
623
+ key: key,
624
+ num: 0,
625
+ agg: null,
626
+ tuple: this.newtuple(t, this._prev && this._prev[key]),
627
+ stamp: this.stamp,
628
+ store: false
629
+ };
630
+ if (!this._countOnly) {
631
+ const measures = this._measures,
632
+ n = measures.length;
633
+ cell.agg = Array(n);
634
+ for (let i = 0; i < n; ++i) {
635
+ cell.agg[i] = new measures[i](cell);
636
+ }
637
+ }
638
+ if (cell.store) {
639
+ cell.data = new TupleStore();
640
+ }
641
+ return cell;
642
+ },
643
+ newtuple(t, p) {
644
+ const names = this._dnames,
645
+ dims = this._dims,
646
+ n = dims.length,
647
+ x = {};
648
+ for (let i = 0; i < n; ++i) {
649
+ x[names[i]] = dims[i](t);
650
+ }
651
+ return p ? vegaDataflow.replace(p.tuple, x) : vegaDataflow.ingest(x);
652
+ },
653
+ clean() {
654
+ const cells = this.value;
655
+ for (const key in cells) {
656
+ if (cells[key].num === 0) {
657
+ delete cells[key];
658
+ }
659
+ }
660
+ },
661
+ // -- Process Tuples -----
662
+
663
+ add(t) {
664
+ const key = this.cellkey(t),
665
+ cell = this.cell(key, t);
666
+ cell.num += 1;
667
+ if (this._countOnly) return;
668
+ if (cell.store) cell.data.add(t);
669
+ const agg = cell.agg;
670
+ for (let i = 0, n = agg.length; i < n; ++i) {
671
+ agg[i].add(agg[i].get(t), t);
672
+ }
673
+ },
674
+ rem(t) {
675
+ const key = this.cellkey(t),
676
+ cell = this.cell(key, t);
677
+ cell.num -= 1;
678
+ if (this._countOnly) return;
679
+ if (cell.store) cell.data.rem(t);
680
+ const agg = cell.agg;
681
+ for (let i = 0, n = agg.length; i < n; ++i) {
682
+ agg[i].rem(agg[i].get(t), t);
683
+ }
684
+ },
685
+ celltuple(cell) {
686
+ const tuple = cell.tuple,
687
+ counts = this._counts;
688
+
689
+ // consolidate stored values
690
+ if (cell.store) {
691
+ cell.data.values();
692
+ }
693
+
694
+ // update tuple properties
695
+ for (let i = 0, n = counts.length; i < n; ++i) {
696
+ tuple[counts[i]] = cell.num;
697
+ }
698
+ if (!this._countOnly) {
699
+ const agg = cell.agg;
700
+ for (let i = 0, n = agg.length; i < n; ++i) {
701
+ agg[i].set(tuple);
702
+ }
703
+ }
704
+ return tuple;
705
+ },
706
+ changes(out) {
707
+ const adds = this._adds,
708
+ mods = this._mods,
709
+ prev = this._prev,
710
+ drop = this._drop,
711
+ add = out.add,
712
+ rem = out.rem,
713
+ mod = out.mod;
714
+ let cell, key, i, n;
715
+ if (prev) for (key in prev) {
716
+ cell = prev[key];
717
+ if (!drop || cell.num) rem.push(cell.tuple);
718
+ }
719
+ for (i = 0, n = this._alen; i < n; ++i) {
720
+ add.push(this.celltuple(adds[i]));
721
+ adds[i] = null; // for garbage collection
722
+ }
723
+ for (i = 0, n = this._mlen; i < n; ++i) {
724
+ cell = mods[i];
725
+ (cell.num === 0 && drop ? rem : mod).push(this.celltuple(cell));
726
+ mods[i] = null; // for garbage collection
727
+ }
728
+ this._alen = this._mlen = 0; // reset list of active cells
729
+ this._prev = null;
730
+ return out;
731
+ }
732
+ });
733
+
734
+ // epsilon bias to offset floating point error (#1737)
735
+ const EPSILON$1 = 1e-14;
736
+
737
+ /**
738
+ * Generates a binning function for discretizing data.
739
+ * @constructor
740
+ * @param {object} params - The parameters for this operator. The
741
+ * provided values should be valid options for the {@link bin} function.
742
+ * @param {function(object): *} params.field - The data field to bin.
743
+ */
744
+ function Bin(params) {
745
+ vegaDataflow.Transform.call(this, null, params);
746
+ }
747
+ Bin.Definition = {
748
+ 'type': 'Bin',
749
+ 'metadata': {
750
+ 'modifies': true
751
+ },
752
+ 'params': [{
753
+ 'name': 'field',
754
+ 'type': 'field',
755
+ 'required': true
756
+ }, {
757
+ 'name': 'interval',
758
+ 'type': 'boolean',
759
+ 'default': true
760
+ }, {
761
+ 'name': 'anchor',
762
+ 'type': 'number'
763
+ }, {
764
+ 'name': 'maxbins',
765
+ 'type': 'number',
766
+ 'default': 20
767
+ }, {
768
+ 'name': 'base',
769
+ 'type': 'number',
770
+ 'default': 10
771
+ }, {
772
+ 'name': 'divide',
773
+ 'type': 'number',
774
+ 'array': true,
775
+ 'default': [5, 2]
776
+ }, {
777
+ 'name': 'extent',
778
+ 'type': 'number',
779
+ 'array': true,
780
+ 'length': 2,
781
+ 'required': true
782
+ }, {
783
+ 'name': 'span',
784
+ 'type': 'number'
785
+ }, {
786
+ 'name': 'step',
787
+ 'type': 'number'
788
+ }, {
789
+ 'name': 'steps',
790
+ 'type': 'number',
791
+ 'array': true
792
+ }, {
793
+ 'name': 'minstep',
794
+ 'type': 'number',
795
+ 'default': 0
796
+ }, {
797
+ 'name': 'nice',
798
+ 'type': 'boolean',
799
+ 'default': true
800
+ }, {
801
+ 'name': 'name',
802
+ 'type': 'string'
803
+ }, {
804
+ 'name': 'as',
805
+ 'type': 'string',
806
+ 'array': true,
807
+ 'length': 2,
808
+ 'default': ['bin0', 'bin1']
809
+ }]
810
+ };
811
+ vegaUtil.inherits(Bin, vegaDataflow.Transform, {
812
+ transform(_, pulse) {
813
+ const band = _.interval !== false,
814
+ bins = this._bins(_),
815
+ start = bins.start,
816
+ step = bins.step,
817
+ as = _.as || ['bin0', 'bin1'],
818
+ b0 = as[0],
819
+ b1 = as[1];
820
+ let flag;
821
+ if (_.modified()) {
822
+ pulse = pulse.reflow(true);
823
+ flag = pulse.SOURCE;
824
+ } else {
825
+ flag = pulse.modified(vegaUtil.accessorFields(_.field)) ? pulse.ADD_MOD : pulse.ADD;
826
+ }
827
+ pulse.visit(flag, band ? t => {
828
+ const v = bins(t);
829
+ // minimum bin value (inclusive)
830
+ t[b0] = v;
831
+ // maximum bin value (exclusive)
832
+ // use convoluted math for better floating point agreement
833
+ // see https://github.com/vega/vega/issues/830
834
+ // infinite values propagate through this formula! #2227
835
+ t[b1] = v == null ? null : start + step * (1 + (v - start) / step);
836
+ } : t => t[b0] = bins(t));
837
+ return pulse.modifies(band ? as : b0);
838
+ },
839
+ _bins(_) {
840
+ if (this.value && !_.modified()) {
841
+ return this.value;
842
+ }
843
+ const field = _.field,
844
+ bins = vegaStatistics.bin(_),
845
+ step = bins.step;
846
+ let start = bins.start,
847
+ stop = start + Math.ceil((bins.stop - start) / step) * step,
848
+ a,
849
+ d;
850
+ if ((a = _.anchor) != null) {
851
+ d = a - (start + step * Math.floor((a - start) / step));
852
+ start += d;
853
+ stop += d;
854
+ }
855
+ const f = function (t) {
856
+ let v = vegaUtil.toNumber(field(t));
857
+ return v == null ? null : v < start ? -Infinity : v > stop ? +Infinity : (v = Math.max(start, Math.min(v, stop - step)), start + step * Math.floor(EPSILON$1 + (v - start) / step));
858
+ };
859
+ f.start = start;
860
+ f.stop = bins.stop;
861
+ f.step = step;
862
+ return this.value = vegaUtil.accessor(f, vegaUtil.accessorFields(field), _.name || 'bin_' + vegaUtil.accessorName(field));
863
+ }
864
+ });
865
+
866
+ function SortedList (idFunc, source, input) {
867
+ const $ = idFunc;
868
+ let data = source || [],
869
+ add = input || [],
870
+ rem = {},
871
+ cnt = 0;
872
+ return {
873
+ add: t => add.push(t),
874
+ remove: t => rem[$(t)] = ++cnt,
875
+ size: () => data.length,
876
+ data: (compare, resort) => {
877
+ if (cnt) {
878
+ data = data.filter(t => !rem[$(t)]);
879
+ rem = {};
880
+ cnt = 0;
881
+ }
882
+ if (resort && compare) {
883
+ data.sort(compare);
884
+ }
885
+ if (add.length) {
886
+ data = compare ? vegaUtil.merge(compare, data, add.sort(compare)) : data.concat(add);
887
+ add = [];
888
+ }
889
+ return data;
890
+ }
891
+ };
892
+ }
893
+
894
+ /**
895
+ * Collects all data tuples that pass through this operator.
896
+ * @constructor
897
+ * @param {object} params - The parameters for this operator.
898
+ * @param {function(*,*): number} [params.sort] - An optional
899
+ * comparator function for additionally sorting the collected tuples.
900
+ */
901
+ function Collect(params) {
902
+ vegaDataflow.Transform.call(this, [], params);
903
+ }
904
+ Collect.Definition = {
905
+ 'type': 'Collect',
906
+ 'metadata': {
907
+ 'source': true
908
+ },
909
+ 'params': [{
910
+ 'name': 'sort',
911
+ 'type': 'compare'
912
+ }]
913
+ };
914
+ vegaUtil.inherits(Collect, vegaDataflow.Transform, {
915
+ transform(_, pulse) {
916
+ const out = pulse.fork(pulse.ALL),
917
+ list = SortedList(vegaDataflow.tupleid, this.value, out.materialize(out.ADD).add),
918
+ sort = _.sort,
919
+ mod = pulse.changed() || sort && (_.modified('sort') || pulse.modified(sort.fields));
920
+ out.visit(out.REM, list.remove);
921
+ this.modified(mod);
922
+ this.value = out.source = list.data(vegaDataflow.stableCompare(sort), mod);
923
+
924
+ // propagate tree root if defined
925
+ if (pulse.source && pulse.source.root) {
926
+ this.value.root = pulse.source.root;
927
+ }
928
+ return out;
929
+ }
930
+ });
931
+
932
+ /**
933
+ * Generates a comparator function.
934
+ * @constructor
935
+ * @param {object} params - The parameters for this operator.
936
+ * @param {Array<string|function>} params.fields - The fields to compare.
937
+ * @param {Array<string>} [params.orders] - The sort orders.
938
+ * Each entry should be one of "ascending" (default) or "descending".
939
+ */
940
+ function Compare(params) {
941
+ vegaDataflow.Operator.call(this, null, update$5, params);
942
+ }
943
+ vegaUtil.inherits(Compare, vegaDataflow.Operator);
944
+ function update$5(_) {
945
+ return this.value && !_.modified() ? this.value : vegaUtil.compare(_.fields, _.orders);
946
+ }
947
+
948
+ /**
949
+ * Count regexp-defined pattern occurrences in a text field.
950
+ * @constructor
951
+ * @param {object} params - The parameters for this operator.
952
+ * @param {function(object): *} params.field - An accessor for the text field.
953
+ * @param {string} [params.pattern] - RegExp string defining the text pattern.
954
+ * @param {string} [params.case] - One of 'lower', 'upper' or null (mixed) case.
955
+ * @param {string} [params.stopwords] - RegExp string of words to ignore.
956
+ */
957
+ function CountPattern(params) {
958
+ vegaDataflow.Transform.call(this, null, params);
959
+ }
960
+ CountPattern.Definition = {
961
+ 'type': 'CountPattern',
962
+ 'metadata': {
963
+ 'generates': true,
964
+ 'changes': true
965
+ },
966
+ 'params': [{
967
+ 'name': 'field',
968
+ 'type': 'field',
969
+ 'required': true
970
+ }, {
971
+ 'name': 'case',
972
+ 'type': 'enum',
973
+ 'values': ['upper', 'lower', 'mixed'],
974
+ 'default': 'mixed'
975
+ }, {
976
+ 'name': 'pattern',
977
+ 'type': 'string',
978
+ 'default': '[\\w"]+'
979
+ }, {
980
+ 'name': 'stopwords',
981
+ 'type': 'string',
982
+ 'default': ''
983
+ }, {
984
+ 'name': 'as',
985
+ 'type': 'string',
986
+ 'array': true,
987
+ 'length': 2,
988
+ 'default': ['text', 'count']
989
+ }]
990
+ };
991
+ function tokenize(text, tcase, match) {
992
+ switch (tcase) {
993
+ case 'upper':
994
+ text = text.toUpperCase();
995
+ break;
996
+ case 'lower':
997
+ text = text.toLowerCase();
998
+ break;
999
+ }
1000
+ return text.match(match);
1001
+ }
1002
+ vegaUtil.inherits(CountPattern, vegaDataflow.Transform, {
1003
+ transform(_, pulse) {
1004
+ const process = update => tuple => {
1005
+ var tokens = tokenize(get(tuple), _.case, match) || [],
1006
+ t;
1007
+ for (var i = 0, n = tokens.length; i < n; ++i) {
1008
+ if (!stop.test(t = tokens[i])) update(t);
1009
+ }
1010
+ };
1011
+ const init = this._parameterCheck(_, pulse),
1012
+ counts = this._counts,
1013
+ match = this._match,
1014
+ stop = this._stop,
1015
+ get = _.field,
1016
+ as = _.as || ['text', 'count'],
1017
+ add = process(t => counts[t] = 1 + (counts[t] || 0)),
1018
+ rem = process(t => counts[t] -= 1);
1019
+ if (init) {
1020
+ pulse.visit(pulse.SOURCE, add);
1021
+ } else {
1022
+ pulse.visit(pulse.ADD, add);
1023
+ pulse.visit(pulse.REM, rem);
1024
+ }
1025
+ return this._finish(pulse, as); // generate output tuples
1026
+ },
1027
+ _parameterCheck(_, pulse) {
1028
+ let init = false;
1029
+ if (_.modified('stopwords') || !this._stop) {
1030
+ this._stop = new RegExp('^' + (_.stopwords || '') + '$', 'i');
1031
+ init = true;
1032
+ }
1033
+ if (_.modified('pattern') || !this._match) {
1034
+ this._match = new RegExp(_.pattern || '[\\w\']+', 'g');
1035
+ init = true;
1036
+ }
1037
+ if (_.modified('field') || pulse.modified(_.field.fields)) {
1038
+ init = true;
1039
+ }
1040
+ if (init) this._counts = {};
1041
+ return init;
1042
+ },
1043
+ _finish(pulse, as) {
1044
+ const counts = this._counts,
1045
+ tuples = this._tuples || (this._tuples = {}),
1046
+ text = as[0],
1047
+ count = as[1],
1048
+ out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS);
1049
+ let w, t, c;
1050
+ for (w in counts) {
1051
+ t = tuples[w];
1052
+ c = counts[w] || 0;
1053
+ if (!t && c) {
1054
+ tuples[w] = t = vegaDataflow.ingest({});
1055
+ t[text] = w;
1056
+ t[count] = c;
1057
+ out.add.push(t);
1058
+ } else if (c === 0) {
1059
+ if (t) out.rem.push(t);
1060
+ counts[w] = null;
1061
+ tuples[w] = null;
1062
+ } else if (t[count] !== c) {
1063
+ t[count] = c;
1064
+ out.mod.push(t);
1065
+ }
1066
+ }
1067
+ return out.modifies(as);
1068
+ }
1069
+ });
1070
+
1071
+ /**
1072
+ * Perform a cross-product of a tuple stream with itself.
1073
+ * @constructor
1074
+ * @param {object} params - The parameters for this operator.
1075
+ * @param {function(object):boolean} [params.filter] - An optional filter
1076
+ * function for selectively including tuples in the cross product.
1077
+ * @param {Array<string>} [params.as] - The names of the output fields.
1078
+ */
1079
+ function Cross(params) {
1080
+ vegaDataflow.Transform.call(this, null, params);
1081
+ }
1082
+ Cross.Definition = {
1083
+ 'type': 'Cross',
1084
+ 'metadata': {
1085
+ 'generates': true
1086
+ },
1087
+ 'params': [{
1088
+ 'name': 'filter',
1089
+ 'type': 'expr'
1090
+ }, {
1091
+ 'name': 'as',
1092
+ 'type': 'string',
1093
+ 'array': true,
1094
+ 'length': 2,
1095
+ 'default': ['a', 'b']
1096
+ }]
1097
+ };
1098
+ vegaUtil.inherits(Cross, vegaDataflow.Transform, {
1099
+ transform(_, pulse) {
1100
+ const out = pulse.fork(pulse.NO_SOURCE),
1101
+ as = _.as || ['a', 'b'],
1102
+ a = as[0],
1103
+ b = as[1],
1104
+ reset = !this.value || pulse.changed(pulse.ADD_REM) || _.modified('as') || _.modified('filter');
1105
+ let data = this.value;
1106
+ if (reset) {
1107
+ if (data) out.rem = data;
1108
+ data = pulse.materialize(pulse.SOURCE).source;
1109
+ out.add = this.value = cross(data, a, b, _.filter || vegaUtil.truthy);
1110
+ } else {
1111
+ out.mod = data;
1112
+ }
1113
+ out.source = this.value;
1114
+ return out.modifies(as);
1115
+ }
1116
+ });
1117
+ function cross(input, a, b, filter) {
1118
+ var data = [],
1119
+ t = {},
1120
+ n = input.length,
1121
+ i = 0,
1122
+ j,
1123
+ left;
1124
+ for (; i < n; ++i) {
1125
+ t[a] = left = input[i];
1126
+ for (j = 0; j < n; ++j) {
1127
+ t[b] = input[j];
1128
+ if (filter(t)) {
1129
+ data.push(vegaDataflow.ingest(t));
1130
+ t = {};
1131
+ t[a] = left;
1132
+ }
1133
+ }
1134
+ }
1135
+ return data;
1136
+ }
1137
+
1138
+ const Distributions = {
1139
+ kde: vegaStatistics.randomKDE,
1140
+ mixture: vegaStatistics.randomMixture,
1141
+ normal: vegaStatistics.randomNormal,
1142
+ lognormal: vegaStatistics.randomLogNormal,
1143
+ uniform: vegaStatistics.randomUniform
1144
+ };
1145
+ const DISTRIBUTIONS = 'distributions',
1146
+ FUNCTION = 'function',
1147
+ FIELD = 'field';
1148
+
1149
+ /**
1150
+ * Parse a parameter object for a probability distribution.
1151
+ * @param {object} def - The distribution parameter object.
1152
+ * @param {function():Array<object>} - A method for requesting
1153
+ * source data. Used for distributions (such as KDE) that
1154
+ * require sample data points. This method will only be
1155
+ * invoked if the 'from' parameter for a target data source
1156
+ * is not provided. Typically this method returns backing
1157
+ * source data for a Pulse object.
1158
+ * @return {object} - The output distribution object.
1159
+ */
1160
+ function parse(def, data) {
1161
+ const func = def[FUNCTION];
1162
+ if (!vegaUtil.hasOwnProperty(Distributions, func)) {
1163
+ vegaUtil.error('Unknown distribution function: ' + func);
1164
+ }
1165
+ const d = Distributions[func]();
1166
+ for (const name in def) {
1167
+ // if data field, extract values
1168
+ if (name === FIELD) {
1169
+ d.data((def.from || data()).map(def[name]));
1170
+ }
1171
+
1172
+ // if distribution mixture, recurse to parse each definition
1173
+ else if (name === DISTRIBUTIONS) {
1174
+ d[name](def[name].map(_ => parse(_, data)));
1175
+ }
1176
+
1177
+ // otherwise, simply set the parameter
1178
+ else if (typeof d[name] === FUNCTION) {
1179
+ d[name](def[name]);
1180
+ }
1181
+ }
1182
+ return d;
1183
+ }
1184
+
1185
+ /**
1186
+ * Grid sample points for a probability density. Given a distribution and
1187
+ * a sampling extent, will generate points suitable for plotting either
1188
+ * PDF (probability density function) or CDF (cumulative distribution
1189
+ * function) curves.
1190
+ * @constructor
1191
+ * @param {object} params - The parameters for this operator.
1192
+ * @param {object} params.distribution - The probability distribution. This
1193
+ * is an object parameter dependent on the distribution type.
1194
+ * @param {string} [params.method='pdf'] - The distribution method to sample.
1195
+ * One of 'pdf' or 'cdf'.
1196
+ * @param {Array<number>} [params.extent] - The [min, max] extent over which
1197
+ * to sample the distribution. This argument is required in most cases, but
1198
+ * can be omitted if the distribution (e.g., 'kde') supports a 'data' method
1199
+ * that returns numerical sample points from which the extent can be deduced.
1200
+ * @param {number} [params.minsteps=25] - The minimum number of curve samples
1201
+ * for plotting the density.
1202
+ * @param {number} [params.maxsteps=200] - The maximum number of curve samples
1203
+ * for plotting the density.
1204
+ * @param {number} [params.steps] - The exact number of curve samples for
1205
+ * plotting the density. If specified, overrides both minsteps and maxsteps
1206
+ * to set an exact number of uniform samples. Useful in conjunction with
1207
+ * a fixed extent to ensure consistent sample points for stacked densities.
1208
+ */
1209
+ function Density(params) {
1210
+ vegaDataflow.Transform.call(this, null, params);
1211
+ }
1212
+ const distributions = [{
1213
+ 'key': {
1214
+ 'function': 'normal'
1215
+ },
1216
+ 'params': [{
1217
+ 'name': 'mean',
1218
+ 'type': 'number',
1219
+ 'default': 0
1220
+ }, {
1221
+ 'name': 'stdev',
1222
+ 'type': 'number',
1223
+ 'default': 1
1224
+ }]
1225
+ }, {
1226
+ 'key': {
1227
+ 'function': 'lognormal'
1228
+ },
1229
+ 'params': [{
1230
+ 'name': 'mean',
1231
+ 'type': 'number',
1232
+ 'default': 0
1233
+ }, {
1234
+ 'name': 'stdev',
1235
+ 'type': 'number',
1236
+ 'default': 1
1237
+ }]
1238
+ }, {
1239
+ 'key': {
1240
+ 'function': 'uniform'
1241
+ },
1242
+ 'params': [{
1243
+ 'name': 'min',
1244
+ 'type': 'number',
1245
+ 'default': 0
1246
+ }, {
1247
+ 'name': 'max',
1248
+ 'type': 'number',
1249
+ 'default': 1
1250
+ }]
1251
+ }, {
1252
+ 'key': {
1253
+ 'function': 'kde'
1254
+ },
1255
+ 'params': [{
1256
+ 'name': 'field',
1257
+ 'type': 'field',
1258
+ 'required': true
1259
+ }, {
1260
+ 'name': 'from',
1261
+ 'type': 'data'
1262
+ }, {
1263
+ 'name': 'bandwidth',
1264
+ 'type': 'number',
1265
+ 'default': 0
1266
+ }]
1267
+ }];
1268
+ const mixture = {
1269
+ 'key': {
1270
+ 'function': 'mixture'
1271
+ },
1272
+ 'params': [{
1273
+ 'name': 'distributions',
1274
+ 'type': 'param',
1275
+ 'array': true,
1276
+ 'params': distributions
1277
+ }, {
1278
+ 'name': 'weights',
1279
+ 'type': 'number',
1280
+ 'array': true
1281
+ }]
1282
+ };
1283
+ Density.Definition = {
1284
+ 'type': 'Density',
1285
+ 'metadata': {
1286
+ 'generates': true
1287
+ },
1288
+ 'params': [{
1289
+ 'name': 'extent',
1290
+ 'type': 'number',
1291
+ 'array': true,
1292
+ 'length': 2
1293
+ }, {
1294
+ 'name': 'steps',
1295
+ 'type': 'number'
1296
+ }, {
1297
+ 'name': 'minsteps',
1298
+ 'type': 'number',
1299
+ 'default': 25
1300
+ }, {
1301
+ 'name': 'maxsteps',
1302
+ 'type': 'number',
1303
+ 'default': 200
1304
+ }, {
1305
+ 'name': 'method',
1306
+ 'type': 'string',
1307
+ 'default': 'pdf',
1308
+ 'values': ['pdf', 'cdf']
1309
+ }, {
1310
+ 'name': 'distribution',
1311
+ 'type': 'param',
1312
+ 'params': distributions.concat(mixture)
1313
+ }, {
1314
+ 'name': 'as',
1315
+ 'type': 'string',
1316
+ 'array': true,
1317
+ 'default': ['value', 'density']
1318
+ }]
1319
+ };
1320
+ vegaUtil.inherits(Density, vegaDataflow.Transform, {
1321
+ transform(_, pulse) {
1322
+ const out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS);
1323
+ if (!this.value || pulse.changed() || _.modified()) {
1324
+ const dist = parse(_.distribution, source(pulse)),
1325
+ minsteps = _.steps || _.minsteps || 25,
1326
+ maxsteps = _.steps || _.maxsteps || 200;
1327
+ let method = _.method || 'pdf';
1328
+ if (method !== 'pdf' && method !== 'cdf') {
1329
+ vegaUtil.error('Invalid density method: ' + method);
1330
+ }
1331
+ if (!_.extent && !dist.data) {
1332
+ vegaUtil.error('Missing density extent parameter.');
1333
+ }
1334
+ method = dist[method];
1335
+ const as = _.as || ['value', 'density'],
1336
+ domain = _.extent || vegaUtil.extent(dist.data()),
1337
+ values = vegaStatistics.sampleCurve(method, domain, minsteps, maxsteps).map(v => {
1338
+ const tuple = {};
1339
+ tuple[as[0]] = v[0];
1340
+ tuple[as[1]] = v[1];
1341
+ return vegaDataflow.ingest(tuple);
1342
+ });
1343
+ if (this.value) out.rem = this.value;
1344
+ this.value = out.add = out.source = values;
1345
+ }
1346
+ return out;
1347
+ }
1348
+ });
1349
+ function source(pulse) {
1350
+ return () => pulse.materialize(pulse.SOURCE).source;
1351
+ }
1352
+
1353
+ // use either provided alias or accessor field name
1354
+ function fieldNames(fields, as) {
1355
+ if (!fields) return null;
1356
+ return fields.map((f, i) => as[i] || vegaUtil.accessorName(f));
1357
+ }
1358
+ function partition$1(data, groupby, field) {
1359
+ const groups = [],
1360
+ get = f => f(t);
1361
+ let map, i, n, t, k, g;
1362
+
1363
+ // partition data points into groups
1364
+ if (groupby == null) {
1365
+ groups.push(data.map(field));
1366
+ } else {
1367
+ for (map = {}, i = 0, n = data.length; i < n; ++i) {
1368
+ t = data[i];
1369
+ k = groupby.map(get);
1370
+ g = map[k];
1371
+ if (!g) {
1372
+ map[k] = g = [];
1373
+ g.dims = k;
1374
+ groups.push(g);
1375
+ }
1376
+ g.push(field(t));
1377
+ }
1378
+ }
1379
+ return groups;
1380
+ }
1381
+
1382
+ const Output = 'bin';
1383
+
1384
+ /**
1385
+ * Dot density binning for dot plot construction.
1386
+ * Based on Leland Wilkinson, Dot Plots, The American Statistician, 1999.
1387
+ * https://www.cs.uic.edu/~wilkinson/Publications/dotplots.pdf
1388
+ * @constructor
1389
+ * @param {object} params - The parameters for this operator.
1390
+ * @param {function(object): *} params.field - The value field to bin.
1391
+ * @param {Array<function(object): *>} [params.groupby] - An array of accessors to groupby.
1392
+ * @param {number} [params.step] - The step size (bin width) within which dots should be
1393
+ * stacked. Defaults to 1/30 of the extent of the data *field*.
1394
+ * @param {boolean} [params.smooth=false] - A boolean flag indicating if dot density
1395
+ * stacks should be smoothed to reduce variance.
1396
+ */
1397
+ function DotBin(params) {
1398
+ vegaDataflow.Transform.call(this, null, params);
1399
+ }
1400
+ DotBin.Definition = {
1401
+ 'type': 'DotBin',
1402
+ 'metadata': {
1403
+ 'modifies': true
1404
+ },
1405
+ 'params': [{
1406
+ 'name': 'field',
1407
+ 'type': 'field',
1408
+ 'required': true
1409
+ }, {
1410
+ 'name': 'groupby',
1411
+ 'type': 'field',
1412
+ 'array': true
1413
+ }, {
1414
+ 'name': 'step',
1415
+ 'type': 'number'
1416
+ }, {
1417
+ 'name': 'smooth',
1418
+ 'type': 'boolean',
1419
+ 'default': false
1420
+ }, {
1421
+ 'name': 'as',
1422
+ 'type': 'string',
1423
+ 'default': Output
1424
+ }]
1425
+ };
1426
+ const autostep = (data, field) => vegaUtil.span(vegaUtil.extent(data, field)) / 30;
1427
+ vegaUtil.inherits(DotBin, vegaDataflow.Transform, {
1428
+ transform(_, pulse) {
1429
+ if (this.value && !(_.modified() || pulse.changed())) {
1430
+ return pulse; // early exit
1431
+ }
1432
+ const source = pulse.materialize(pulse.SOURCE).source,
1433
+ groups = partition$1(pulse.source, _.groupby, vegaUtil.identity),
1434
+ smooth = _.smooth || false,
1435
+ field = _.field,
1436
+ step = _.step || autostep(source, field),
1437
+ sort = vegaDataflow.stableCompare((a, b) => field(a) - field(b)),
1438
+ as = _.as || Output,
1439
+ n = groups.length;
1440
+
1441
+ // compute dotplot bins per group
1442
+ let min = Infinity,
1443
+ max = -Infinity,
1444
+ i = 0,
1445
+ j;
1446
+ for (; i < n; ++i) {
1447
+ const g = groups[i].sort(sort);
1448
+ j = -1;
1449
+ for (const v of vegaStatistics.dotbin(g, step, smooth, field)) {
1450
+ if (v < min) min = v;
1451
+ if (v > max) max = v;
1452
+ g[++j][as] = v;
1453
+ }
1454
+ }
1455
+ this.value = {
1456
+ start: min,
1457
+ stop: max,
1458
+ step: step
1459
+ };
1460
+ return pulse.reflow(true).modifies(as);
1461
+ }
1462
+ });
1463
+
1464
+ /**
1465
+ * Wraps an expression function with access to external parameters.
1466
+ * @constructor
1467
+ * @param {object} params - The parameters for this operator.
1468
+ * @param {function} params.expr - The expression function. The
1469
+ * function should accept both a datum and a parameter object.
1470
+ * This operator's value will be a new function that wraps the
1471
+ * expression function with access to this operator's parameters.
1472
+ */
1473
+ function Expression(params) {
1474
+ vegaDataflow.Operator.call(this, null, update$4, params);
1475
+ this.modified(true);
1476
+ }
1477
+ vegaUtil.inherits(Expression, vegaDataflow.Operator);
1478
+ function update$4(_) {
1479
+ const expr = _.expr;
1480
+ return this.value && !_.modified('expr') ? this.value : vegaUtil.accessor(datum => expr(datum, _), vegaUtil.accessorFields(expr), vegaUtil.accessorName(expr));
1481
+ }
1482
+
1483
+ /**
1484
+ * Computes extents (min/max) for a data field.
1485
+ * @constructor
1486
+ * @param {object} params - The parameters for this operator.
1487
+ * @param {function(object): *} params.field - The field over which to compute extends.
1488
+ */
1489
+ function Extent(params) {
1490
+ vegaDataflow.Transform.call(this, [undefined, undefined], params);
1491
+ }
1492
+ Extent.Definition = {
1493
+ 'type': 'Extent',
1494
+ 'metadata': {},
1495
+ 'params': [{
1496
+ 'name': 'field',
1497
+ 'type': 'field',
1498
+ 'required': true
1499
+ }]
1500
+ };
1501
+ vegaUtil.inherits(Extent, vegaDataflow.Transform, {
1502
+ transform(_, pulse) {
1503
+ const extent = this.value,
1504
+ field = _.field,
1505
+ mod = pulse.changed() || pulse.modified(field.fields) || _.modified('field');
1506
+ let min = extent[0],
1507
+ max = extent[1];
1508
+ if (mod || min == null) {
1509
+ min = +Infinity;
1510
+ max = -Infinity;
1511
+ }
1512
+ pulse.visit(mod ? pulse.SOURCE : pulse.ADD, t => {
1513
+ const v = vegaUtil.toNumber(field(t));
1514
+ if (v != null) {
1515
+ // NaNs will fail all comparisons!
1516
+ if (v < min) min = v;
1517
+ if (v > max) max = v;
1518
+ }
1519
+ });
1520
+ if (!Number.isFinite(min) || !Number.isFinite(max)) {
1521
+ let name = vegaUtil.accessorName(field);
1522
+ if (name) name = ` for field "${name}"`;
1523
+ pulse.dataflow.warn(`Infinite extent${name}: [${min}, ${max}]`);
1524
+ min = max = undefined;
1525
+ }
1526
+ this.value = [min, max];
1527
+ }
1528
+ });
1529
+
1530
+ /**
1531
+ * Provides a bridge between a parent transform and a target subflow that
1532
+ * consumes only a subset of the tuples that pass through the parent.
1533
+ * @constructor
1534
+ * @param {Pulse} pulse - A pulse to use as the value of this operator.
1535
+ * @param {Transform} parent - The parent transform (typically a Facet instance).
1536
+ */
1537
+ function Subflow(pulse, parent) {
1538
+ vegaDataflow.Operator.call(this, pulse);
1539
+ this.parent = parent;
1540
+ this.count = 0;
1541
+ }
1542
+ vegaUtil.inherits(Subflow, vegaDataflow.Operator, {
1543
+ /**
1544
+ * Routes pulses from this subflow to a target transform.
1545
+ * @param {Transform} target - A transform that receives the subflow of tuples.
1546
+ */
1547
+ connect(target) {
1548
+ this.detachSubflow = target.detachSubflow;
1549
+ this.targets().add(target);
1550
+ return target.source = this;
1551
+ },
1552
+ /**
1553
+ * Add an 'add' tuple to the subflow pulse.
1554
+ * @param {Tuple} t - The tuple being added.
1555
+ */
1556
+ add(t) {
1557
+ this.count += 1;
1558
+ this.value.add.push(t);
1559
+ },
1560
+ /**
1561
+ * Add a 'rem' tuple to the subflow pulse.
1562
+ * @param {Tuple} t - The tuple being removed.
1563
+ */
1564
+ rem(t) {
1565
+ this.count -= 1;
1566
+ this.value.rem.push(t);
1567
+ },
1568
+ /**
1569
+ * Add a 'mod' tuple to the subflow pulse.
1570
+ * @param {Tuple} t - The tuple being modified.
1571
+ */
1572
+ mod(t) {
1573
+ this.value.mod.push(t);
1574
+ },
1575
+ /**
1576
+ * Re-initialize this operator's pulse value.
1577
+ * @param {Pulse} pulse - The pulse to copy from.
1578
+ * @see Pulse.init
1579
+ */
1580
+ init(pulse) {
1581
+ this.value.init(pulse, pulse.NO_SOURCE);
1582
+ },
1583
+ /**
1584
+ * Evaluate this operator. This method overrides the
1585
+ * default behavior to simply return the contained pulse value.
1586
+ * @return {Pulse}
1587
+ */
1588
+ evaluate() {
1589
+ // assert: this.value.stamp === pulse.stamp
1590
+ return this.value;
1591
+ }
1592
+ });
1593
+
1594
+ /**
1595
+ * Facets a dataflow into a set of subflows based on a key.
1596
+ * @constructor
1597
+ * @param {object} params - The parameters for this operator.
1598
+ * @param {function(Dataflow, string): Operator} params.subflow - A function
1599
+ * that generates a subflow of operators and returns its root operator.
1600
+ * @param {function(object): *} params.key - The key field to facet by.
1601
+ */
1602
+ function Facet(params) {
1603
+ vegaDataflow.Transform.call(this, {}, params);
1604
+ this._keys = vegaUtil.fastmap(); // cache previously calculated key values
1605
+
1606
+ // keep track of active subflows, use as targets array for listeners
1607
+ // this allows us to limit propagation to only updated subflows
1608
+ const a = this._targets = [];
1609
+ a.active = 0;
1610
+ a.forEach = f => {
1611
+ for (let i = 0, n = a.active; i < n; ++i) {
1612
+ f(a[i], i, a);
1613
+ }
1614
+ };
1615
+ }
1616
+ vegaUtil.inherits(Facet, vegaDataflow.Transform, {
1617
+ activate(flow) {
1618
+ this._targets[this._targets.active++] = flow;
1619
+ },
1620
+ // parent argument provided by PreFacet subclass
1621
+ subflow(key, flow, pulse, parent) {
1622
+ const flows = this.value;
1623
+ let sf = vegaUtil.hasOwnProperty(flows, key) && flows[key],
1624
+ df,
1625
+ p;
1626
+ if (!sf) {
1627
+ p = parent || (p = this._group[key]) && p.tuple;
1628
+ df = pulse.dataflow;
1629
+ sf = new Subflow(pulse.fork(pulse.NO_SOURCE), this);
1630
+ df.add(sf).connect(flow(df, key, p));
1631
+ flows[key] = sf;
1632
+ this.activate(sf);
1633
+ } else if (sf.value.stamp < pulse.stamp) {
1634
+ sf.init(pulse);
1635
+ this.activate(sf);
1636
+ }
1637
+ return sf;
1638
+ },
1639
+ clean() {
1640
+ const flows = this.value;
1641
+ let detached = 0;
1642
+ for (const key in flows) {
1643
+ if (flows[key].count === 0) {
1644
+ const detach = flows[key].detachSubflow;
1645
+ if (detach) detach();
1646
+ delete flows[key];
1647
+ ++detached;
1648
+ }
1649
+ }
1650
+
1651
+ // remove inactive targets from the active targets array
1652
+ if (detached) {
1653
+ const active = this._targets.filter(sf => sf && sf.count > 0);
1654
+ this.initTargets(active);
1655
+ }
1656
+ },
1657
+ initTargets(act) {
1658
+ const a = this._targets,
1659
+ n = a.length,
1660
+ m = act ? act.length : 0;
1661
+ let i = 0;
1662
+ for (; i < m; ++i) {
1663
+ a[i] = act[i];
1664
+ }
1665
+ for (; i < n && a[i] != null; ++i) {
1666
+ a[i] = null; // ensure old flows can be garbage collected
1667
+ }
1668
+ a.active = m;
1669
+ },
1670
+ transform(_, pulse) {
1671
+ const df = pulse.dataflow,
1672
+ key = _.key,
1673
+ flow = _.subflow,
1674
+ cache = this._keys,
1675
+ rekey = _.modified('key'),
1676
+ subflow = key => this.subflow(key, flow, pulse);
1677
+ this._group = _.group || {};
1678
+ this.initTargets(); // reset list of active subflows
1679
+
1680
+ pulse.visit(pulse.REM, t => {
1681
+ const id = vegaDataflow.tupleid(t),
1682
+ k = cache.get(id);
1683
+ if (k !== undefined) {
1684
+ cache.delete(id);
1685
+ subflow(k).rem(t);
1686
+ }
1687
+ });
1688
+ pulse.visit(pulse.ADD, t => {
1689
+ const k = key(t);
1690
+ cache.set(vegaDataflow.tupleid(t), k);
1691
+ subflow(k).add(t);
1692
+ });
1693
+ if (rekey || pulse.modified(key.fields)) {
1694
+ pulse.visit(pulse.MOD, t => {
1695
+ const id = vegaDataflow.tupleid(t),
1696
+ k0 = cache.get(id),
1697
+ k1 = key(t);
1698
+ if (k0 === k1) {
1699
+ subflow(k1).mod(t);
1700
+ } else {
1701
+ cache.set(id, k1);
1702
+ subflow(k0).rem(t);
1703
+ subflow(k1).add(t);
1704
+ }
1705
+ });
1706
+ } else if (pulse.changed(pulse.MOD)) {
1707
+ pulse.visit(pulse.MOD, t => {
1708
+ subflow(cache.get(vegaDataflow.tupleid(t))).mod(t);
1709
+ });
1710
+ }
1711
+ if (rekey) {
1712
+ pulse.visit(pulse.REFLOW, t => {
1713
+ const id = vegaDataflow.tupleid(t),
1714
+ k0 = cache.get(id),
1715
+ k1 = key(t);
1716
+ if (k0 !== k1) {
1717
+ cache.set(id, k1);
1718
+ subflow(k0).rem(t);
1719
+ subflow(k1).add(t);
1720
+ }
1721
+ });
1722
+ }
1723
+ if (pulse.clean()) {
1724
+ df.runAfter(() => {
1725
+ this.clean();
1726
+ cache.clean();
1727
+ });
1728
+ } else if (cache.empty > df.cleanThreshold) {
1729
+ df.runAfter(cache.clean);
1730
+ }
1731
+ return pulse;
1732
+ }
1733
+ });
1734
+
1735
+ /**
1736
+ * Generates one or more field accessor functions.
1737
+ * If the 'name' parameter is an array, an array of field accessors
1738
+ * will be created and the 'as' parameter will be ignored.
1739
+ * @constructor
1740
+ * @param {object} params - The parameters for this operator.
1741
+ * @param {string} params.name - The field name(s) to access.
1742
+ * @param {string} params.as - The accessor function name.
1743
+ */
1744
+ function Field(params) {
1745
+ vegaDataflow.Operator.call(this, null, update$3, params);
1746
+ }
1747
+ vegaUtil.inherits(Field, vegaDataflow.Operator);
1748
+ function update$3(_) {
1749
+ return this.value && !_.modified() ? this.value : vegaUtil.isArray(_.name) ? vegaUtil.array(_.name).map(f => vegaUtil.field(f)) : vegaUtil.field(_.name, _.as);
1750
+ }
1751
+
1752
+ /**
1753
+ * Filters data tuples according to a predicate function.
1754
+ * @constructor
1755
+ * @param {object} params - The parameters for this operator.
1756
+ * @param {function(object): *} params.expr - The predicate expression function
1757
+ * that determines a tuple's filter status. Truthy values pass the filter.
1758
+ */
1759
+ function Filter(params) {
1760
+ vegaDataflow.Transform.call(this, vegaUtil.fastmap(), params);
1761
+ }
1762
+ Filter.Definition = {
1763
+ 'type': 'Filter',
1764
+ 'metadata': {
1765
+ 'changes': true
1766
+ },
1767
+ 'params': [{
1768
+ 'name': 'expr',
1769
+ 'type': 'expr',
1770
+ 'required': true
1771
+ }]
1772
+ };
1773
+ vegaUtil.inherits(Filter, vegaDataflow.Transform, {
1774
+ transform(_, pulse) {
1775
+ const df = pulse.dataflow,
1776
+ cache = this.value,
1777
+ // cache ids of filtered tuples
1778
+ output = pulse.fork(),
1779
+ add = output.add,
1780
+ rem = output.rem,
1781
+ mod = output.mod,
1782
+ test = _.expr;
1783
+ let isMod = true;
1784
+ pulse.visit(pulse.REM, t => {
1785
+ const id = vegaDataflow.tupleid(t);
1786
+ if (!cache.has(id)) rem.push(t);else cache.delete(id);
1787
+ });
1788
+ pulse.visit(pulse.ADD, t => {
1789
+ if (test(t, _)) add.push(t);else cache.set(vegaDataflow.tupleid(t), 1);
1790
+ });
1791
+ function revisit(t) {
1792
+ const id = vegaDataflow.tupleid(t),
1793
+ b = test(t, _),
1794
+ s = cache.get(id);
1795
+ if (b && s) {
1796
+ cache.delete(id);
1797
+ add.push(t);
1798
+ } else if (!b && !s) {
1799
+ cache.set(id, 1);
1800
+ rem.push(t);
1801
+ } else if (isMod && b && !s) {
1802
+ mod.push(t);
1803
+ }
1804
+ }
1805
+ pulse.visit(pulse.MOD, revisit);
1806
+ if (_.modified()) {
1807
+ isMod = false;
1808
+ pulse.visit(pulse.REFLOW, revisit);
1809
+ }
1810
+ if (cache.empty > df.cleanThreshold) df.runAfter(cache.clean);
1811
+ return output;
1812
+ }
1813
+ });
1814
+
1815
+ /**
1816
+ * Flattens array-typed field values into new data objects.
1817
+ * If multiple fields are specified, they are treated as parallel arrays,
1818
+ * with output values included for each matching index (or null if missing).
1819
+ * @constructor
1820
+ * @param {object} params - The parameters for this operator.
1821
+ * @param {Array<function(object): *>} params.fields - An array of field
1822
+ * accessors for the tuple fields that should be flattened.
1823
+ * @param {string} [params.index] - Optional output field name for index
1824
+ * value. If unspecified, no index field is included in the output.
1825
+ * @param {Array<string>} [params.as] - Output field names for flattened
1826
+ * array fields. Any unspecified fields will use the field name provided
1827
+ * by the fields accessors.
1828
+ */
1829
+ function Flatten(params) {
1830
+ vegaDataflow.Transform.call(this, [], params);
1831
+ }
1832
+ Flatten.Definition = {
1833
+ 'type': 'Flatten',
1834
+ 'metadata': {
1835
+ 'generates': true
1836
+ },
1837
+ 'params': [{
1838
+ 'name': 'fields',
1839
+ 'type': 'field',
1840
+ 'array': true,
1841
+ 'required': true
1842
+ }, {
1843
+ 'name': 'index',
1844
+ 'type': 'string'
1845
+ }, {
1846
+ 'name': 'as',
1847
+ 'type': 'string',
1848
+ 'array': true
1849
+ }]
1850
+ };
1851
+ vegaUtil.inherits(Flatten, vegaDataflow.Transform, {
1852
+ transform(_, pulse) {
1853
+ const out = pulse.fork(pulse.NO_SOURCE),
1854
+ fields = _.fields,
1855
+ as = fieldNames(fields, _.as || []),
1856
+ index = _.index || null,
1857
+ m = as.length;
1858
+
1859
+ // remove any previous results
1860
+ out.rem = this.value;
1861
+
1862
+ // generate flattened tuples
1863
+ pulse.visit(pulse.SOURCE, t => {
1864
+ const arrays = fields.map(f => f(t)),
1865
+ maxlen = arrays.reduce((l, a) => Math.max(l, a.length), 0);
1866
+ let i = 0,
1867
+ j,
1868
+ d,
1869
+ v;
1870
+ for (; i < maxlen; ++i) {
1871
+ d = vegaDataflow.derive(t);
1872
+ for (j = 0; j < m; ++j) {
1873
+ d[as[j]] = (v = arrays[j][i]) == null ? null : v;
1874
+ }
1875
+ if (index) {
1876
+ d[index] = i;
1877
+ }
1878
+ out.add.push(d);
1879
+ }
1880
+ });
1881
+ this.value = out.source = out.add;
1882
+ if (index) out.modifies(index);
1883
+ return out.modifies(as);
1884
+ }
1885
+ });
1886
+
1887
+ /**
1888
+ * Folds one more tuple fields into multiple tuples in which the field
1889
+ * name and values are available under new 'key' and 'value' fields.
1890
+ * @constructor
1891
+ * @param {object} params - The parameters for this operator.
1892
+ * @param {function(object): *} params.fields - An array of field accessors
1893
+ * for the tuple fields that should be folded.
1894
+ * @param {Array<string>} [params.as] - Output field names for folded key
1895
+ * and value fields, defaults to ['key', 'value'].
1896
+ */
1897
+ function Fold(params) {
1898
+ vegaDataflow.Transform.call(this, [], params);
1899
+ }
1900
+ Fold.Definition = {
1901
+ 'type': 'Fold',
1902
+ 'metadata': {
1903
+ 'generates': true
1904
+ },
1905
+ 'params': [{
1906
+ 'name': 'fields',
1907
+ 'type': 'field',
1908
+ 'array': true,
1909
+ 'required': true
1910
+ }, {
1911
+ 'name': 'as',
1912
+ 'type': 'string',
1913
+ 'array': true,
1914
+ 'length': 2,
1915
+ 'default': ['key', 'value']
1916
+ }]
1917
+ };
1918
+ vegaUtil.inherits(Fold, vegaDataflow.Transform, {
1919
+ transform(_, pulse) {
1920
+ const out = pulse.fork(pulse.NO_SOURCE),
1921
+ fields = _.fields,
1922
+ fnames = fields.map(vegaUtil.accessorName),
1923
+ as = _.as || ['key', 'value'],
1924
+ k = as[0],
1925
+ v = as[1],
1926
+ n = fields.length;
1927
+ out.rem = this.value;
1928
+ pulse.visit(pulse.SOURCE, t => {
1929
+ for (let i = 0, d; i < n; ++i) {
1930
+ d = vegaDataflow.derive(t);
1931
+ d[k] = fnames[i];
1932
+ d[v] = fields[i](t);
1933
+ out.add.push(d);
1934
+ }
1935
+ });
1936
+ this.value = out.source = out.add;
1937
+ return out.modifies(as);
1938
+ }
1939
+ });
1940
+
1941
+ /**
1942
+ * Invokes a function for each data tuple and saves the results as a new field.
1943
+ * @constructor
1944
+ * @param {object} params - The parameters for this operator.
1945
+ * @param {function(object): *} params.expr - The formula function to invoke for each tuple.
1946
+ * @param {string} params.as - The field name under which to save the result.
1947
+ * @param {boolean} [params.initonly=false] - If true, the formula is applied to
1948
+ * added tuples only, and does not update in response to modifications.
1949
+ */
1950
+ function Formula(params) {
1951
+ vegaDataflow.Transform.call(this, null, params);
1952
+ }
1953
+ Formula.Definition = {
1954
+ 'type': 'Formula',
1955
+ 'metadata': {
1956
+ 'modifies': true
1957
+ },
1958
+ 'params': [{
1959
+ 'name': 'expr',
1960
+ 'type': 'expr',
1961
+ 'required': true
1962
+ }, {
1963
+ 'name': 'as',
1964
+ 'type': 'string',
1965
+ 'required': true
1966
+ }, {
1967
+ 'name': 'initonly',
1968
+ 'type': 'boolean'
1969
+ }]
1970
+ };
1971
+ vegaUtil.inherits(Formula, vegaDataflow.Transform, {
1972
+ transform(_, pulse) {
1973
+ const func = _.expr,
1974
+ as = _.as,
1975
+ mod = _.modified(),
1976
+ flag = _.initonly ? pulse.ADD : mod ? pulse.SOURCE : pulse.modified(func.fields) || pulse.modified(as) ? pulse.ADD_MOD : pulse.ADD;
1977
+ if (mod) {
1978
+ // parameters updated, need to reflow
1979
+ pulse = pulse.materialize().reflow(true);
1980
+ }
1981
+ if (!_.initonly) {
1982
+ pulse.modifies(as);
1983
+ }
1984
+ return pulse.visit(flag, t => t[as] = func(t, _));
1985
+ }
1986
+ });
1987
+
1988
+ /**
1989
+ * Generates data tuples using a provided generator function.
1990
+ * @constructor
1991
+ * @param {object} params - The parameters for this operator.
1992
+ * @param {function(Parameters): object} params.generator - A tuple generator
1993
+ * function. This function is given the operator parameters as input.
1994
+ * Changes to any additional parameters will not trigger re-calculation
1995
+ * of previously generated tuples. Only future tuples are affected.
1996
+ * @param {number} params.size - The number of tuples to produce.
1997
+ */
1998
+ function Generate(params) {
1999
+ vegaDataflow.Transform.call(this, [], params);
2000
+ }
2001
+ vegaUtil.inherits(Generate, vegaDataflow.Transform, {
2002
+ transform(_, pulse) {
2003
+ const out = pulse.fork(pulse.ALL),
2004
+ gen = _.generator;
2005
+ let data = this.value,
2006
+ num = _.size - data.length,
2007
+ add,
2008
+ rem,
2009
+ t;
2010
+ if (num > 0) {
2011
+ // need more tuples, generate and add
2012
+ for (add = []; --num >= 0;) {
2013
+ add.push(t = vegaDataflow.ingest(gen(_)));
2014
+ data.push(t);
2015
+ }
2016
+ out.add = out.add.length ? out.materialize(out.ADD).add.concat(add) : add;
2017
+ } else {
2018
+ // need fewer tuples, remove
2019
+ rem = data.slice(0, -num);
2020
+ out.rem = out.rem.length ? out.materialize(out.REM).rem.concat(rem) : rem;
2021
+ data = data.slice(-num);
2022
+ }
2023
+ out.source = this.value = data;
2024
+ return out;
2025
+ }
2026
+ });
2027
+
2028
+ const Methods = {
2029
+ value: 'value',
2030
+ median: median.default,
2031
+ mean: mean.default,
2032
+ min: min.default,
2033
+ max: max.default
2034
+ };
2035
+ const Empty = [];
2036
+
2037
+ /**
2038
+ * Impute missing values.
2039
+ * @constructor
2040
+ * @param {object} params - The parameters for this operator.
2041
+ * @param {function(object): *} params.field - The value field to impute.
2042
+ * @param {Array<function(object): *>} [params.groupby] - An array of
2043
+ * accessors to determine series within which to perform imputation.
2044
+ * @param {function(object): *} params.key - An accessor for a key value.
2045
+ * Each key value should be unique within a group. New tuples will be
2046
+ * imputed for any key values that are not found within a group.
2047
+ * @param {Array<*>} [params.keyvals] - Optional array of required key
2048
+ * values. New tuples will be imputed for any key values that are not
2049
+ * found within a group. In addition, these values will be automatically
2050
+ * augmented with the key values observed in the input data.
2051
+ * @param {string} [method='value'] - The imputation method to use. One of
2052
+ * 'value', 'mean', 'median', 'max', 'min'.
2053
+ * @param {*} [value=0] - The constant value to use for imputation
2054
+ * when using method 'value'.
2055
+ */
2056
+ function Impute(params) {
2057
+ vegaDataflow.Transform.call(this, [], params);
2058
+ }
2059
+ Impute.Definition = {
2060
+ 'type': 'Impute',
2061
+ 'metadata': {
2062
+ 'changes': true
2063
+ },
2064
+ 'params': [{
2065
+ 'name': 'field',
2066
+ 'type': 'field',
2067
+ 'required': true
2068
+ }, {
2069
+ 'name': 'key',
2070
+ 'type': 'field',
2071
+ 'required': true
2072
+ }, {
2073
+ 'name': 'keyvals',
2074
+ 'array': true
2075
+ }, {
2076
+ 'name': 'groupby',
2077
+ 'type': 'field',
2078
+ 'array': true
2079
+ }, {
2080
+ 'name': 'method',
2081
+ 'type': 'enum',
2082
+ 'default': 'value',
2083
+ 'values': ['value', 'mean', 'median', 'max', 'min']
2084
+ }, {
2085
+ 'name': 'value',
2086
+ 'default': 0
2087
+ }]
2088
+ };
2089
+ function getValue(_) {
2090
+ var m = _.method || Methods.value,
2091
+ v;
2092
+ if (Methods[m] == null) {
2093
+ vegaUtil.error('Unrecognized imputation method: ' + m);
2094
+ } else if (m === Methods.value) {
2095
+ v = _.value !== undefined ? _.value : 0;
2096
+ return () => v;
2097
+ } else {
2098
+ return Methods[m];
2099
+ }
2100
+ }
2101
+ function getField(_) {
2102
+ const f = _.field;
2103
+ return t => t ? f(t) : NaN;
2104
+ }
2105
+ vegaUtil.inherits(Impute, vegaDataflow.Transform, {
2106
+ transform(_, pulse) {
2107
+ var out = pulse.fork(pulse.ALL),
2108
+ impute = getValue(_),
2109
+ field = getField(_),
2110
+ fName = vegaUtil.accessorName(_.field),
2111
+ kName = vegaUtil.accessorName(_.key),
2112
+ gNames = (_.groupby || []).map(vegaUtil.accessorName),
2113
+ groups = partition(pulse.source, _.groupby, _.key, _.keyvals),
2114
+ curr = [],
2115
+ prev = this.value,
2116
+ m = groups.domain.length,
2117
+ group,
2118
+ value,
2119
+ gVals,
2120
+ kVal,
2121
+ g,
2122
+ i,
2123
+ j,
2124
+ l,
2125
+ n,
2126
+ t;
2127
+ for (g = 0, l = groups.length; g < l; ++g) {
2128
+ group = groups[g];
2129
+ gVals = group.values;
2130
+ value = NaN;
2131
+
2132
+ // add tuples for missing values
2133
+ for (j = 0; j < m; ++j) {
2134
+ if (group[j] != null) continue;
2135
+ kVal = groups.domain[j];
2136
+ t = {
2137
+ _impute: true
2138
+ };
2139
+ for (i = 0, n = gVals.length; i < n; ++i) t[gNames[i]] = gVals[i];
2140
+ t[kName] = kVal;
2141
+ t[fName] = Number.isNaN(value) ? value = impute(group, field) : value;
2142
+ curr.push(vegaDataflow.ingest(t));
2143
+ }
2144
+ }
2145
+
2146
+ // update pulse with imputed tuples
2147
+ if (curr.length) out.add = out.materialize(out.ADD).add.concat(curr);
2148
+ if (prev.length) out.rem = out.materialize(out.REM).rem.concat(prev);
2149
+ this.value = curr;
2150
+ return out;
2151
+ }
2152
+ });
2153
+ function partition(data, groupby, key, keyvals) {
2154
+ var get = f => f(t),
2155
+ groups = [],
2156
+ domain = keyvals ? keyvals.slice() : [],
2157
+ kMap = {},
2158
+ gMap = {},
2159
+ gVals,
2160
+ gKey,
2161
+ group,
2162
+ i,
2163
+ j,
2164
+ k,
2165
+ n,
2166
+ t;
2167
+ domain.forEach((k, i) => kMap[k] = i + 1);
2168
+ for (i = 0, n = data.length; i < n; ++i) {
2169
+ t = data[i];
2170
+ k = key(t);
2171
+ j = kMap[k] || (kMap[k] = domain.push(k));
2172
+ gKey = (gVals = groupby ? groupby.map(get) : Empty) + '';
2173
+ if (!(group = gMap[gKey])) {
2174
+ group = gMap[gKey] = [];
2175
+ groups.push(group);
2176
+ group.values = gVals;
2177
+ }
2178
+ group[j - 1] = t;
2179
+ }
2180
+ groups.domain = domain;
2181
+ return groups;
2182
+ }
2183
+
2184
+ /**
2185
+ * Extend input tuples with aggregate values.
2186
+ * Calcuates aggregate values and joins them with the input stream.
2187
+ * @constructor
2188
+ */
2189
+ function JoinAggregate(params) {
2190
+ Aggregate.call(this, params);
2191
+ }
2192
+ JoinAggregate.Definition = {
2193
+ 'type': 'JoinAggregate',
2194
+ 'metadata': {
2195
+ 'modifies': true
2196
+ },
2197
+ 'params': [{
2198
+ 'name': 'groupby',
2199
+ 'type': 'field',
2200
+ 'array': true
2201
+ }, {
2202
+ 'name': 'fields',
2203
+ 'type': 'field',
2204
+ 'null': true,
2205
+ 'array': true
2206
+ }, {
2207
+ 'name': 'ops',
2208
+ 'type': 'enum',
2209
+ 'array': true,
2210
+ 'values': ValidAggregateOps
2211
+ }, {
2212
+ 'name': 'as',
2213
+ 'type': 'string',
2214
+ 'null': true,
2215
+ 'array': true
2216
+ }, {
2217
+ 'name': 'key',
2218
+ 'type': 'field'
2219
+ }]
2220
+ };
2221
+ vegaUtil.inherits(JoinAggregate, Aggregate, {
2222
+ transform(_, pulse) {
2223
+ const aggr = this,
2224
+ mod = _.modified();
2225
+ let cells;
2226
+
2227
+ // process all input tuples to calculate aggregates
2228
+ if (aggr.value && (mod || pulse.modified(aggr._inputs, true))) {
2229
+ cells = aggr.value = mod ? aggr.init(_) : {};
2230
+ pulse.visit(pulse.SOURCE, t => aggr.add(t));
2231
+ } else {
2232
+ cells = aggr.value = aggr.value || this.init(_);
2233
+ pulse.visit(pulse.REM, t => aggr.rem(t));
2234
+ pulse.visit(pulse.ADD, t => aggr.add(t));
2235
+ }
2236
+
2237
+ // update aggregation cells
2238
+ aggr.changes();
2239
+
2240
+ // write aggregate values to input tuples
2241
+ pulse.visit(pulse.SOURCE, t => {
2242
+ vegaUtil.extend(t, cells[aggr.cellkey(t)].tuple);
2243
+ });
2244
+ return pulse.reflow(mod).modifies(this._outputs);
2245
+ },
2246
+ changes() {
2247
+ const adds = this._adds,
2248
+ mods = this._mods;
2249
+ let i, n;
2250
+ for (i = 0, n = this._alen; i < n; ++i) {
2251
+ this.celltuple(adds[i]);
2252
+ adds[i] = null; // for garbage collection
2253
+ }
2254
+ for (i = 0, n = this._mlen; i < n; ++i) {
2255
+ this.celltuple(mods[i]);
2256
+ mods[i] = null; // for garbage collection
2257
+ }
2258
+ this._alen = this._mlen = 0; // reset list of active cells
2259
+ }
2260
+ });
2261
+
2262
+ /**
2263
+ * Compute kernel density estimates (KDE) for one or more data groups.
2264
+ * @constructor
2265
+ * @param {object} params - The parameters for this operator.
2266
+ * @param {Array<function(object): *>} [params.groupby] - An array of accessors
2267
+ * to groupby.
2268
+ * @param {function(object): *} params.field - An accessor for the data field
2269
+ * to estimate.
2270
+ * @param {number} [params.bandwidth=0] - The KDE kernel bandwidth.
2271
+ * If zero or unspecified, the bandwidth is automatically determined.
2272
+ * @param {boolean} [params.counts=false] - A boolean flag indicating if the
2273
+ * output values should be probability estimates (false, default) or
2274
+ * smoothed counts (true).
2275
+ * @param {string} [params.cumulative=false] - A boolean flag indicating if a
2276
+ * density (false) or cumulative distribution (true) should be generated.
2277
+ * @param {Array<number>} [params.extent] - The domain extent over which to
2278
+ * plot the density. If unspecified, the [min, max] data extent is used.
2279
+ * @param {string} [params.resolve='independent'] - Indicates how parameters for
2280
+ * multiple densities should be resolved. If "independent" (the default), each
2281
+ * density may have its own domain extent and dynamic number of curve sample
2282
+ * steps. If "shared", the KDE transform will ensure that all densities are
2283
+ * defined over a shared domain and curve steps, enabling stacking.
2284
+ * @param {number} [params.minsteps=25] - The minimum number of curve samples
2285
+ * for plotting the density.
2286
+ * @param {number} [params.maxsteps=200] - The maximum number of curve samples
2287
+ * for plotting the density.
2288
+ * @param {number} [params.steps] - The exact number of curve samples for
2289
+ * plotting the density. If specified, overrides both minsteps and maxsteps
2290
+ * to set an exact number of uniform samples. Useful in conjunction with
2291
+ * a fixed extent to ensure consistent sample points for stacked densities.
2292
+ */
2293
+ function KDE(params) {
2294
+ vegaDataflow.Transform.call(this, null, params);
2295
+ }
2296
+ KDE.Definition = {
2297
+ 'type': 'KDE',
2298
+ 'metadata': {
2299
+ 'generates': true
2300
+ },
2301
+ 'params': [{
2302
+ 'name': 'groupby',
2303
+ 'type': 'field',
2304
+ 'array': true
2305
+ }, {
2306
+ 'name': 'field',
2307
+ 'type': 'field',
2308
+ 'required': true
2309
+ }, {
2310
+ 'name': 'cumulative',
2311
+ 'type': 'boolean',
2312
+ 'default': false
2313
+ }, {
2314
+ 'name': 'counts',
2315
+ 'type': 'boolean',
2316
+ 'default': false
2317
+ }, {
2318
+ 'name': 'bandwidth',
2319
+ 'type': 'number',
2320
+ 'default': 0
2321
+ }, {
2322
+ 'name': 'extent',
2323
+ 'type': 'number',
2324
+ 'array': true,
2325
+ 'length': 2
2326
+ }, {
2327
+ 'name': 'resolve',
2328
+ 'type': 'enum',
2329
+ 'values': ['shared', 'independent'],
2330
+ 'default': 'independent'
2331
+ }, {
2332
+ 'name': 'steps',
2333
+ 'type': 'number'
2334
+ }, {
2335
+ 'name': 'minsteps',
2336
+ 'type': 'number',
2337
+ 'default': 25
2338
+ }, {
2339
+ 'name': 'maxsteps',
2340
+ 'type': 'number',
2341
+ 'default': 200
2342
+ }, {
2343
+ 'name': 'as',
2344
+ 'type': 'string',
2345
+ 'array': true,
2346
+ 'default': ['value', 'density']
2347
+ }]
2348
+ };
2349
+ vegaUtil.inherits(KDE, vegaDataflow.Transform, {
2350
+ transform(_, pulse) {
2351
+ const out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS);
2352
+ if (!this.value || pulse.changed() || _.modified()) {
2353
+ const source = pulse.materialize(pulse.SOURCE).source,
2354
+ groups = partition$1(source, _.groupby, _.field),
2355
+ names = (_.groupby || []).map(vegaUtil.accessorName),
2356
+ bandwidth = _.bandwidth,
2357
+ method = _.cumulative ? 'cdf' : 'pdf',
2358
+ as = _.as || ['value', 'density'],
2359
+ values = [];
2360
+ let domain = _.extent,
2361
+ minsteps = _.steps || _.minsteps || 25,
2362
+ maxsteps = _.steps || _.maxsteps || 200;
2363
+ if (method !== 'pdf' && method !== 'cdf') {
2364
+ vegaUtil.error('Invalid density method: ' + method);
2365
+ }
2366
+ if (_.resolve === 'shared') {
2367
+ if (!domain) domain = vegaUtil.extent(source, _.field);
2368
+ minsteps = maxsteps = _.steps || maxsteps;
2369
+ }
2370
+ groups.forEach(g => {
2371
+ const density = vegaStatistics.randomKDE(g, bandwidth)[method],
2372
+ scale = _.counts ? g.length : 1,
2373
+ local = domain || vegaUtil.extent(g);
2374
+ vegaStatistics.sampleCurve(density, local, minsteps, maxsteps).forEach(v => {
2375
+ const t = {};
2376
+ for (let i = 0; i < names.length; ++i) {
2377
+ t[names[i]] = g.dims[i];
2378
+ }
2379
+ t[as[0]] = v[0];
2380
+ t[as[1]] = v[1] * scale;
2381
+ values.push(vegaDataflow.ingest(t));
2382
+ });
2383
+ });
2384
+ if (this.value) out.rem = this.value;
2385
+ this.value = out.add = out.source = values;
2386
+ }
2387
+ return out;
2388
+ }
2389
+ });
2390
+
2391
+ /**
2392
+ * Generates a key function.
2393
+ * @constructor
2394
+ * @param {object} params - The parameters for this operator.
2395
+ * @param {Array<string>} params.fields - The field name(s) for the key function.
2396
+ * @param {boolean} params.flat - A boolean flag indicating if the field names
2397
+ * should be treated as flat property names, side-stepping nested field
2398
+ * lookups normally indicated by dot or bracket notation.
2399
+ */
2400
+ function Key(params) {
2401
+ vegaDataflow.Operator.call(this, null, update$2, params);
2402
+ }
2403
+ vegaUtil.inherits(Key, vegaDataflow.Operator);
2404
+ function update$2(_) {
2405
+ return this.value && !_.modified() ? this.value : vegaUtil.key(_.fields, _.flat);
2406
+ }
2407
+
2408
+ /**
2409
+ * Load and parse data from an external source. Marshalls parameter
2410
+ * values and then invokes the Dataflow request method.
2411
+ * @constructor
2412
+ * @param {object} params - The parameters for this operator.
2413
+ * @param {string} params.url - The URL to load from.
2414
+ * @param {object} params.format - The data format options.
2415
+ */
2416
+ function Load(params) {
2417
+ vegaDataflow.Transform.call(this, [], params);
2418
+ this._pending = null;
2419
+ }
2420
+ vegaUtil.inherits(Load, vegaDataflow.Transform, {
2421
+ transform(_, pulse) {
2422
+ const df = pulse.dataflow;
2423
+ if (this._pending) {
2424
+ // update state and return pulse
2425
+ return output(this, pulse, this._pending);
2426
+ }
2427
+ if (stop(_)) return pulse.StopPropagation;
2428
+ if (_.values) {
2429
+ // parse and ingest values, return output pulse
2430
+ return output(this, pulse, df.parse(_.values, _.format));
2431
+ } else if (_.async) {
2432
+ // return promise for non-blocking async loading
2433
+ const p = df.request(_.url, _.format).then(res => {
2434
+ this._pending = vegaUtil.array(res.data);
2435
+ return df => df.touch(this);
2436
+ });
2437
+ return {
2438
+ async: p
2439
+ };
2440
+ } else {
2441
+ // return promise for synchronous loading
2442
+ return df.request(_.url, _.format).then(res => output(this, pulse, vegaUtil.array(res.data)));
2443
+ }
2444
+ }
2445
+ });
2446
+ function stop(_) {
2447
+ return _.modified('async') && !(_.modified('values') || _.modified('url') || _.modified('format'));
2448
+ }
2449
+ function output(op, pulse, data) {
2450
+ data.forEach(vegaDataflow.ingest);
2451
+ const out = pulse.fork(pulse.NO_FIELDS & pulse.NO_SOURCE);
2452
+ out.rem = op.value;
2453
+ op.value = out.source = out.add = data;
2454
+ op._pending = null;
2455
+ if (out.rem.length) out.clean(true);
2456
+ return out;
2457
+ }
2458
+
2459
+ /**
2460
+ * Extend tuples by joining them with values from a lookup table.
2461
+ * @constructor
2462
+ * @param {object} params - The parameters for this operator.
2463
+ * @param {Map} params.index - The lookup table map.
2464
+ * @param {Array<function(object): *} params.fields - The fields to lookup.
2465
+ * @param {Array<string>} params.as - Output field names for each lookup value.
2466
+ * @param {*} [params.default] - A default value to use if lookup fails.
2467
+ */
2468
+ function Lookup(params) {
2469
+ vegaDataflow.Transform.call(this, {}, params);
2470
+ }
2471
+ Lookup.Definition = {
2472
+ 'type': 'Lookup',
2473
+ 'metadata': {
2474
+ 'modifies': true
2475
+ },
2476
+ 'params': [{
2477
+ 'name': 'index',
2478
+ 'type': 'index',
2479
+ 'params': [{
2480
+ 'name': 'from',
2481
+ 'type': 'data',
2482
+ 'required': true
2483
+ }, {
2484
+ 'name': 'key',
2485
+ 'type': 'field',
2486
+ 'required': true
2487
+ }]
2488
+ }, {
2489
+ 'name': 'values',
2490
+ 'type': 'field',
2491
+ 'array': true
2492
+ }, {
2493
+ 'name': 'fields',
2494
+ 'type': 'field',
2495
+ 'array': true,
2496
+ 'required': true
2497
+ }, {
2498
+ 'name': 'as',
2499
+ 'type': 'string',
2500
+ 'array': true
2501
+ }, {
2502
+ 'name': 'default',
2503
+ 'default': null
2504
+ }]
2505
+ };
2506
+ vegaUtil.inherits(Lookup, vegaDataflow.Transform, {
2507
+ transform(_, pulse) {
2508
+ const keys = _.fields,
2509
+ index = _.index,
2510
+ values = _.values,
2511
+ defaultValue = _.default == null ? null : _.default,
2512
+ reset = _.modified(),
2513
+ n = keys.length;
2514
+ let flag = reset ? pulse.SOURCE : pulse.ADD,
2515
+ out = pulse,
2516
+ as = _.as,
2517
+ set,
2518
+ m,
2519
+ mods;
2520
+ if (values) {
2521
+ m = values.length;
2522
+ if (n > 1 && !as) {
2523
+ vegaUtil.error('Multi-field lookup requires explicit "as" parameter.');
2524
+ }
2525
+ if (as && as.length !== n * m) {
2526
+ vegaUtil.error('The "as" parameter has too few output field names.');
2527
+ }
2528
+ as = as || values.map(vegaUtil.accessorName);
2529
+ set = function (t) {
2530
+ for (var i = 0, k = 0, j, v; i < n; ++i) {
2531
+ v = index.get(keys[i](t));
2532
+ if (v == null) for (j = 0; j < m; ++j, ++k) t[as[k]] = defaultValue;else for (j = 0; j < m; ++j, ++k) t[as[k]] = values[j](v);
2533
+ }
2534
+ };
2535
+ } else {
2536
+ if (!as) {
2537
+ vegaUtil.error('Missing output field names.');
2538
+ }
2539
+ set = function (t) {
2540
+ for (var i = 0, v; i < n; ++i) {
2541
+ v = index.get(keys[i](t));
2542
+ t[as[i]] = v == null ? defaultValue : v;
2543
+ }
2544
+ };
2545
+ }
2546
+ if (reset) {
2547
+ out = pulse.reflow(true);
2548
+ } else {
2549
+ mods = keys.some(k => pulse.modified(k.fields));
2550
+ flag |= mods ? pulse.MOD : 0;
2551
+ }
2552
+ pulse.visit(flag, set);
2553
+ return out.modifies(as);
2554
+ }
2555
+ });
2556
+
2557
+ /**
2558
+ * Computes global min/max extents over a collection of extents.
2559
+ * @constructor
2560
+ * @param {object} params - The parameters for this operator.
2561
+ * @param {Array<Array<number>>} params.extents - The input extents.
2562
+ */
2563
+ function MultiExtent(params) {
2564
+ vegaDataflow.Operator.call(this, null, update$1, params);
2565
+ }
2566
+ vegaUtil.inherits(MultiExtent, vegaDataflow.Operator);
2567
+ function update$1(_) {
2568
+ if (this.value && !_.modified()) {
2569
+ return this.value;
2570
+ }
2571
+ const ext = _.extents,
2572
+ n = ext.length;
2573
+ let min = +Infinity,
2574
+ max = -Infinity,
2575
+ i,
2576
+ e;
2577
+ for (i = 0; i < n; ++i) {
2578
+ e = ext[i];
2579
+ if (e[0] < min) min = e[0];
2580
+ if (e[1] > max) max = e[1];
2581
+ }
2582
+ return [min, max];
2583
+ }
2584
+
2585
+ /**
2586
+ * Merge a collection of value arrays.
2587
+ * @constructor
2588
+ * @param {object} params - The parameters for this operator.
2589
+ * @param {Array<Array<*>>} params.values - The input value arrrays.
2590
+ */
2591
+ function MultiValues(params) {
2592
+ vegaDataflow.Operator.call(this, null, update, params);
2593
+ }
2594
+ vegaUtil.inherits(MultiValues, vegaDataflow.Operator);
2595
+ function update(_) {
2596
+ return this.value && !_.modified() ? this.value : _.values.reduce((data, _) => data.concat(_), []);
2597
+ }
2598
+
2599
+ /**
2600
+ * Operator whose value is simply its parameter hash. This operator is
2601
+ * useful for enabling reactive updates to values of nested objects.
2602
+ * @constructor
2603
+ * @param {object} params - The parameters for this operator.
2604
+ */
2605
+ function Params(params) {
2606
+ vegaDataflow.Transform.call(this, null, params);
2607
+ }
2608
+ vegaUtil.inherits(Params, vegaDataflow.Transform, {
2609
+ transform(_, pulse) {
2610
+ this.modified(_.modified());
2611
+ this.value = _;
2612
+ return pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS); // do not pass tuples
2613
+ }
2614
+ });
2615
+
2616
+ /**
2617
+ * Aggregate and pivot selected field values to become new fields.
2618
+ * This operator is useful to construction cross-tabulations.
2619
+ * @constructor
2620
+ * @param {Array<function(object): *>} [params.groupby] - An array of accessors
2621
+ * to groupby. These fields act just like groupby fields of an Aggregate transform.
2622
+ * @param {function(object): *} params.field - The field to pivot on. The unique
2623
+ * values of this field become new field names in the output stream.
2624
+ * @param {function(object): *} params.value - The field to populate pivoted fields.
2625
+ * The aggregate values of this field become the values of the new pivoted fields.
2626
+ * @param {string} [params.op] - The aggregation operation for the value field,
2627
+ * applied per cell in the output stream. The default is "sum".
2628
+ * @param {number} [params.limit] - An optional parameter indicating the maximum
2629
+ * number of pivoted fields to generate. The pivoted field names are sorted in
2630
+ * ascending order prior to enforcing the limit.
2631
+ */
2632
+ function Pivot(params) {
2633
+ Aggregate.call(this, params);
2634
+ }
2635
+ Pivot.Definition = {
2636
+ 'type': 'Pivot',
2637
+ 'metadata': {
2638
+ 'generates': true,
2639
+ 'changes': true
2640
+ },
2641
+ 'params': [{
2642
+ 'name': 'groupby',
2643
+ 'type': 'field',
2644
+ 'array': true
2645
+ }, {
2646
+ 'name': 'field',
2647
+ 'type': 'field',
2648
+ 'required': true
2649
+ }, {
2650
+ 'name': 'value',
2651
+ 'type': 'field',
2652
+ 'required': true
2653
+ }, {
2654
+ 'name': 'op',
2655
+ 'type': 'enum',
2656
+ 'values': ValidAggregateOps,
2657
+ 'default': 'sum'
2658
+ }, {
2659
+ 'name': 'limit',
2660
+ 'type': 'number',
2661
+ 'default': 0
2662
+ }, {
2663
+ 'name': 'key',
2664
+ 'type': 'field'
2665
+ }]
2666
+ };
2667
+ vegaUtil.inherits(Pivot, Aggregate, {
2668
+ _transform: Aggregate.prototype.transform,
2669
+ transform(_, pulse) {
2670
+ return this._transform(aggregateParams(_, pulse), pulse);
2671
+ }
2672
+ });
2673
+
2674
+ // Shoehorn a pivot transform into an aggregate transform!
2675
+ // First collect all unique pivot field values.
2676
+ // Then generate aggregate fields for each output pivot field.
2677
+ function aggregateParams(_, pulse) {
2678
+ const key = _.field,
2679
+ value = _.value,
2680
+ op = (_.op === 'count' ? '__count__' : _.op) || 'sum',
2681
+ fields = vegaUtil.accessorFields(key).concat(vegaUtil.accessorFields(value)),
2682
+ keys = pivotKeys(key, _.limit || 0, pulse);
2683
+
2684
+ // if data stream content changes, pivot fields may change
2685
+ // flag parameter modification to ensure re-initialization
2686
+ if (pulse.changed()) _.set('__pivot__', null, null, true);
2687
+ return {
2688
+ key: _.key,
2689
+ groupby: _.groupby,
2690
+ ops: keys.map(() => op),
2691
+ fields: keys.map(k => get(k, key, value, fields)),
2692
+ as: keys.map(k => k + ''),
2693
+ modified: _.modified.bind(_)
2694
+ };
2695
+ }
2696
+
2697
+ // Generate aggregate field accessor.
2698
+ // Output NaN for non-existent values; aggregator will ignore!
2699
+ function get(k, key, value, fields) {
2700
+ return vegaUtil.accessor(d => key(d) === k ? value(d) : NaN, fields, k + '');
2701
+ }
2702
+
2703
+ // Collect (and optionally limit) all unique pivot values.
2704
+ function pivotKeys(key, limit, pulse) {
2705
+ const map = {},
2706
+ list = [];
2707
+ pulse.visit(pulse.SOURCE, t => {
2708
+ const k = key(t);
2709
+ if (!map[k]) {
2710
+ map[k] = 1;
2711
+ list.push(k);
2712
+ }
2713
+ });
2714
+ list.sort(vegaUtil.ascending);
2715
+ return limit ? list.slice(0, limit) : list;
2716
+ }
2717
+
2718
+ /**
2719
+ * Partitions pre-faceted data into tuple subflows.
2720
+ * @constructor
2721
+ * @param {object} params - The parameters for this operator.
2722
+ * @param {function(Dataflow, string): Operator} params.subflow - A function
2723
+ * that generates a subflow of operators and returns its root operator.
2724
+ * @param {function(object): Array<object>} params.field - The field
2725
+ * accessor for an array of subflow tuple objects.
2726
+ */
2727
+ function PreFacet(params) {
2728
+ Facet.call(this, params);
2729
+ }
2730
+ vegaUtil.inherits(PreFacet, Facet, {
2731
+ transform(_, pulse) {
2732
+ const flow = _.subflow,
2733
+ field = _.field,
2734
+ subflow = t => this.subflow(vegaDataflow.tupleid(t), flow, pulse, t);
2735
+ if (_.modified('field') || field && pulse.modified(vegaUtil.accessorFields(field))) {
2736
+ vegaUtil.error('PreFacet does not support field modification.');
2737
+ }
2738
+ this.initTargets(); // reset list of active subflows
2739
+
2740
+ if (field) {
2741
+ pulse.visit(pulse.MOD, t => {
2742
+ const sf = subflow(t);
2743
+ field(t).forEach(_ => sf.mod(_));
2744
+ });
2745
+ pulse.visit(pulse.ADD, t => {
2746
+ const sf = subflow(t);
2747
+ field(t).forEach(_ => sf.add(vegaDataflow.ingest(_)));
2748
+ });
2749
+ pulse.visit(pulse.REM, t => {
2750
+ const sf = subflow(t);
2751
+ field(t).forEach(_ => sf.rem(_));
2752
+ });
2753
+ } else {
2754
+ pulse.visit(pulse.MOD, t => subflow(t).mod(t));
2755
+ pulse.visit(pulse.ADD, t => subflow(t).add(t));
2756
+ pulse.visit(pulse.REM, t => subflow(t).rem(t));
2757
+ }
2758
+ if (pulse.clean()) {
2759
+ pulse.runAfter(() => this.clean());
2760
+ }
2761
+ return pulse;
2762
+ }
2763
+ });
2764
+
2765
+ /**
2766
+ * Performs a relational projection, copying selected fields from source
2767
+ * tuples to a new set of derived tuples.
2768
+ * @constructor
2769
+ * @param {object} params - The parameters for this operator.
2770
+ * @param {Array<function(object): *} params.fields - The fields to project,
2771
+ * as an array of field accessors. If unspecified, all fields will be
2772
+ * copied with names unchanged.
2773
+ * @param {Array<string>} [params.as] - Output field names for each projected
2774
+ * field. Any unspecified fields will use the field name provided by
2775
+ * the field accessor.
2776
+ */
2777
+ function Project(params) {
2778
+ vegaDataflow.Transform.call(this, null, params);
2779
+ }
2780
+ Project.Definition = {
2781
+ 'type': 'Project',
2782
+ 'metadata': {
2783
+ 'generates': true,
2784
+ 'changes': true
2785
+ },
2786
+ 'params': [{
2787
+ 'name': 'fields',
2788
+ 'type': 'field',
2789
+ 'array': true
2790
+ }, {
2791
+ 'name': 'as',
2792
+ 'type': 'string',
2793
+ 'null': true,
2794
+ 'array': true
2795
+ }]
2796
+ };
2797
+ vegaUtil.inherits(Project, vegaDataflow.Transform, {
2798
+ transform(_, pulse) {
2799
+ const out = pulse.fork(pulse.NO_SOURCE),
2800
+ fields = _.fields,
2801
+ as = fieldNames(_.fields, _.as || []),
2802
+ derive = fields ? (s, t) => project(s, t, fields, as) : vegaDataflow.rederive;
2803
+ let lut;
2804
+ if (this.value) {
2805
+ lut = this.value;
2806
+ } else {
2807
+ pulse = pulse.addAll();
2808
+ lut = this.value = {};
2809
+ }
2810
+ pulse.visit(pulse.REM, t => {
2811
+ const id = vegaDataflow.tupleid(t);
2812
+ out.rem.push(lut[id]);
2813
+ lut[id] = null;
2814
+ });
2815
+ pulse.visit(pulse.ADD, t => {
2816
+ const dt = derive(t, vegaDataflow.ingest({}));
2817
+ lut[vegaDataflow.tupleid(t)] = dt;
2818
+ out.add.push(dt);
2819
+ });
2820
+ pulse.visit(pulse.MOD, t => {
2821
+ out.mod.push(derive(t, lut[vegaDataflow.tupleid(t)]));
2822
+ });
2823
+ return out;
2824
+ }
2825
+ });
2826
+ function project(s, t, fields, as) {
2827
+ for (let i = 0, n = fields.length; i < n; ++i) {
2828
+ t[as[i]] = fields[i](s);
2829
+ }
2830
+ return t;
2831
+ }
2832
+
2833
+ /**
2834
+ * Proxy the value of another operator as a pure signal value.
2835
+ * Ensures no tuples are propagated.
2836
+ * @constructor
2837
+ * @param {object} params - The parameters for this operator.
2838
+ * @param {*} params.value - The value to proxy, becomes the value of this operator.
2839
+ */
2840
+ function Proxy(params) {
2841
+ vegaDataflow.Transform.call(this, null, params);
2842
+ }
2843
+ vegaUtil.inherits(Proxy, vegaDataflow.Transform, {
2844
+ transform(_, pulse) {
2845
+ this.value = _.value;
2846
+ return _.modified('value') ? pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS) : pulse.StopPropagation;
2847
+ }
2848
+ });
2849
+
2850
+ /**
2851
+ * Generates sample quantile values from an input data stream.
2852
+ * @constructor
2853
+ * @param {object} params - The parameters for this operator.
2854
+ * @param {function(object): *} params.field - An accessor for the data field
2855
+ * over which to calculate quantile values.
2856
+ * @param {Array<function(object): *>} [params.groupby] - An array of accessors
2857
+ * to groupby.
2858
+ * @param {Array<number>} [params.probs] - An array of probabilities in
2859
+ * the range (0, 1) for which to compute quantile values. If not specified,
2860
+ * the *step* parameter will be used.
2861
+ * @param {Array<number>} [params.step=0.01] - A probability step size for
2862
+ * sampling quantile values. All values from one-half the step size up to
2863
+ * 1 (exclusive) will be sampled. This parameter is only used if the
2864
+ * *quantiles* parameter is not provided.
2865
+ */
2866
+ function Quantile(params) {
2867
+ vegaDataflow.Transform.call(this, null, params);
2868
+ }
2869
+ Quantile.Definition = {
2870
+ 'type': 'Quantile',
2871
+ 'metadata': {
2872
+ 'generates': true,
2873
+ 'changes': true
2874
+ },
2875
+ 'params': [{
2876
+ 'name': 'groupby',
2877
+ 'type': 'field',
2878
+ 'array': true
2879
+ }, {
2880
+ 'name': 'field',
2881
+ 'type': 'field',
2882
+ 'required': true
2883
+ }, {
2884
+ 'name': 'probs',
2885
+ 'type': 'number',
2886
+ 'array': true
2887
+ }, {
2888
+ 'name': 'step',
2889
+ 'type': 'number',
2890
+ 'default': 0.01
2891
+ }, {
2892
+ 'name': 'as',
2893
+ 'type': 'string',
2894
+ 'array': true,
2895
+ 'default': ['prob', 'value']
2896
+ }]
2897
+ };
2898
+ const EPSILON = 1e-14;
2899
+ vegaUtil.inherits(Quantile, vegaDataflow.Transform, {
2900
+ transform(_, pulse) {
2901
+ const out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS),
2902
+ as = _.as || ['prob', 'value'];
2903
+ if (this.value && !_.modified() && !pulse.changed()) {
2904
+ out.source = this.value;
2905
+ return out;
2906
+ }
2907
+ const source = pulse.materialize(pulse.SOURCE).source,
2908
+ groups = partition$1(source, _.groupby, _.field),
2909
+ names = (_.groupby || []).map(vegaUtil.accessorName),
2910
+ values = [],
2911
+ step = _.step || 0.01,
2912
+ p = _.probs || range.default(step / 2, 1 - EPSILON, step),
2913
+ n = p.length;
2914
+ groups.forEach(g => {
2915
+ const q = vegaStatistics.quantiles(g, p);
2916
+ for (let i = 0; i < n; ++i) {
2917
+ const t = {};
2918
+ for (let i = 0; i < names.length; ++i) {
2919
+ t[names[i]] = g.dims[i];
2920
+ }
2921
+ t[as[0]] = p[i];
2922
+ t[as[1]] = q[i];
2923
+ values.push(vegaDataflow.ingest(t));
2924
+ }
2925
+ });
2926
+ if (this.value) out.rem = this.value;
2927
+ this.value = out.add = out.source = values;
2928
+ return out;
2929
+ }
2930
+ });
2931
+
2932
+ /**
2933
+ * Relays a data stream between data processing pipelines.
2934
+ * If the derive parameter is set, this transform will create derived
2935
+ * copies of observed tuples. This provides derived data streams in which
2936
+ * modifications to the tuples do not pollute an upstream data source.
2937
+ * @param {object} params - The parameters for this operator.
2938
+ * @param {number} [params.derive=false] - Boolean flag indicating if
2939
+ * the transform should make derived copies of incoming tuples.
2940
+ * @constructor
2941
+ */
2942
+ function Relay(params) {
2943
+ vegaDataflow.Transform.call(this, null, params);
2944
+ }
2945
+ vegaUtil.inherits(Relay, vegaDataflow.Transform, {
2946
+ transform(_, pulse) {
2947
+ let out, lut;
2948
+ if (this.value) {
2949
+ lut = this.value;
2950
+ } else {
2951
+ out = pulse = pulse.addAll();
2952
+ lut = this.value = {};
2953
+ }
2954
+ if (_.derive) {
2955
+ out = pulse.fork(pulse.NO_SOURCE);
2956
+ pulse.visit(pulse.REM, t => {
2957
+ const id = vegaDataflow.tupleid(t);
2958
+ out.rem.push(lut[id]);
2959
+ lut[id] = null;
2960
+ });
2961
+ pulse.visit(pulse.ADD, t => {
2962
+ const dt = vegaDataflow.derive(t);
2963
+ lut[vegaDataflow.tupleid(t)] = dt;
2964
+ out.add.push(dt);
2965
+ });
2966
+ pulse.visit(pulse.MOD, t => {
2967
+ const dt = lut[vegaDataflow.tupleid(t)];
2968
+ for (const k in t) {
2969
+ dt[k] = t[k];
2970
+ // down stream writes may overwrite re-derived tuples
2971
+ // conservatively mark all source fields as modified
2972
+ out.modifies(k);
2973
+ }
2974
+ out.mod.push(dt);
2975
+ });
2976
+ }
2977
+ return out;
2978
+ }
2979
+ });
2980
+
2981
+ /**
2982
+ * Samples tuples passing through this operator.
2983
+ * Uses reservoir sampling to maintain a representative sample.
2984
+ * @constructor
2985
+ * @param {object} params - The parameters for this operator.
2986
+ * @param {number} [params.size=1000] - The maximum number of samples.
2987
+ */
2988
+ function Sample(params) {
2989
+ vegaDataflow.Transform.call(this, [], params);
2990
+ this.count = 0;
2991
+ }
2992
+ Sample.Definition = {
2993
+ 'type': 'Sample',
2994
+ 'metadata': {},
2995
+ 'params': [{
2996
+ 'name': 'size',
2997
+ 'type': 'number',
2998
+ 'default': 1000
2999
+ }]
3000
+ };
3001
+ vegaUtil.inherits(Sample, vegaDataflow.Transform, {
3002
+ transform(_, pulse) {
3003
+ const out = pulse.fork(pulse.NO_SOURCE),
3004
+ mod = _.modified('size'),
3005
+ num = _.size,
3006
+ map = this.value.reduce((m, t) => (m[vegaDataflow.tupleid(t)] = 1, m), {});
3007
+ let res = this.value,
3008
+ cnt = this.count,
3009
+ cap = 0;
3010
+
3011
+ // sample reservoir update function
3012
+ function update(t) {
3013
+ let p, idx;
3014
+ if (res.length < num) {
3015
+ res.push(t);
3016
+ } else {
3017
+ idx = ~~((cnt + 1) * vegaStatistics.random());
3018
+ if (idx < res.length && idx >= cap) {
3019
+ p = res[idx];
3020
+ if (map[vegaDataflow.tupleid(p)]) out.rem.push(p); // eviction
3021
+ res[idx] = t;
3022
+ }
3023
+ }
3024
+ ++cnt;
3025
+ }
3026
+ if (pulse.rem.length) {
3027
+ // find all tuples that should be removed, add to output
3028
+ pulse.visit(pulse.REM, t => {
3029
+ const id = vegaDataflow.tupleid(t);
3030
+ if (map[id]) {
3031
+ map[id] = -1;
3032
+ out.rem.push(t);
3033
+ }
3034
+ --cnt;
3035
+ });
3036
+
3037
+ // filter removed tuples out of the sample reservoir
3038
+ res = res.filter(t => map[vegaDataflow.tupleid(t)] !== -1);
3039
+ }
3040
+ if ((pulse.rem.length || mod) && res.length < num && pulse.source) {
3041
+ // replenish sample if backing data source is available
3042
+ cap = cnt = res.length;
3043
+ pulse.visit(pulse.SOURCE, t => {
3044
+ // update, but skip previously sampled tuples
3045
+ if (!map[vegaDataflow.tupleid(t)]) update(t);
3046
+ });
3047
+ cap = -1;
3048
+ }
3049
+ if (mod && res.length > num) {
3050
+ const n = res.length - num;
3051
+ for (let i = 0; i < n; ++i) {
3052
+ map[vegaDataflow.tupleid(res[i])] = -1;
3053
+ out.rem.push(res[i]);
3054
+ }
3055
+ res = res.slice(n);
3056
+ }
3057
+ if (pulse.mod.length) {
3058
+ // propagate modified tuples in the sample reservoir
3059
+ pulse.visit(pulse.MOD, t => {
3060
+ if (map[vegaDataflow.tupleid(t)]) out.mod.push(t);
3061
+ });
3062
+ }
3063
+ if (pulse.add.length) {
3064
+ // update sample reservoir
3065
+ pulse.visit(pulse.ADD, update);
3066
+ }
3067
+ if (pulse.add.length || cap < 0) {
3068
+ // output newly added tuples
3069
+ out.add = res.filter(t => !map[vegaDataflow.tupleid(t)]);
3070
+ }
3071
+ this.count = cnt;
3072
+ this.value = out.source = res;
3073
+ return out;
3074
+ }
3075
+ });
3076
+
3077
+ /**
3078
+ * Generates data tuples for a specified sequence range of numbers.
3079
+ * @constructor
3080
+ * @param {object} params - The parameters for this operator.
3081
+ * @param {number} params.start - The first number in the sequence.
3082
+ * @param {number} params.stop - The last number (exclusive) in the sequence.
3083
+ * @param {number} [params.step=1] - The step size between numbers in the sequence.
3084
+ */
3085
+ function Sequence(params) {
3086
+ vegaDataflow.Transform.call(this, null, params);
3087
+ }
3088
+ Sequence.Definition = {
3089
+ 'type': 'Sequence',
3090
+ 'metadata': {
3091
+ 'generates': true,
3092
+ 'changes': true
3093
+ },
3094
+ 'params': [{
3095
+ 'name': 'start',
3096
+ 'type': 'number',
3097
+ 'required': true
3098
+ }, {
3099
+ 'name': 'stop',
3100
+ 'type': 'number',
3101
+ 'required': true
3102
+ }, {
3103
+ 'name': 'step',
3104
+ 'type': 'number',
3105
+ 'default': 1
3106
+ }, {
3107
+ 'name': 'as',
3108
+ 'type': 'string',
3109
+ 'default': 'data'
3110
+ }]
3111
+ };
3112
+ vegaUtil.inherits(Sequence, vegaDataflow.Transform, {
3113
+ transform(_, pulse) {
3114
+ if (this.value && !_.modified()) return;
3115
+ const out = pulse.materialize().fork(pulse.MOD),
3116
+ as = _.as || 'data';
3117
+ out.rem = this.value ? pulse.rem.concat(this.value) : pulse.rem;
3118
+ this.value = range.default(_.start, _.stop, _.step || 1).map(v => {
3119
+ const t = {};
3120
+ t[as] = v;
3121
+ return vegaDataflow.ingest(t);
3122
+ });
3123
+ out.add = pulse.add.concat(this.value);
3124
+ return out;
3125
+ }
3126
+ });
3127
+
3128
+ /**
3129
+ * Propagates a new pulse without any tuples so long as the input
3130
+ * pulse contains some added, removed or modified tuples.
3131
+ * @param {object} params - The parameters for this operator.
3132
+ * @constructor
3133
+ */
3134
+ function Sieve(params) {
3135
+ vegaDataflow.Transform.call(this, null, params);
3136
+ this.modified(true); // always treat as modified
3137
+ }
3138
+ vegaUtil.inherits(Sieve, vegaDataflow.Transform, {
3139
+ transform(_, pulse) {
3140
+ this.value = pulse.source;
3141
+ return pulse.changed() ? pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS) : pulse.StopPropagation;
3142
+ }
3143
+ });
3144
+
3145
+ /**
3146
+ * Discretize dates to specific time units.
3147
+ * @constructor
3148
+ * @param {object} params - The parameters for this operator.
3149
+ * @param {function(object): *} params.field - The data field containing date/time values.
3150
+ */
3151
+ function TimeUnit(params) {
3152
+ vegaDataflow.Transform.call(this, null, params);
3153
+ }
3154
+ const OUTPUT = ['unit0', 'unit1'];
3155
+ TimeUnit.Definition = {
3156
+ 'type': 'TimeUnit',
3157
+ 'metadata': {
3158
+ 'modifies': true
3159
+ },
3160
+ 'params': [{
3161
+ 'name': 'field',
3162
+ 'type': 'field',
3163
+ 'required': true
3164
+ }, {
3165
+ 'name': 'interval',
3166
+ 'type': 'boolean',
3167
+ 'default': true
3168
+ }, {
3169
+ 'name': 'units',
3170
+ 'type': 'enum',
3171
+ 'values': vegaTime.TIME_UNITS,
3172
+ 'array': true
3173
+ }, {
3174
+ 'name': 'step',
3175
+ 'type': 'number',
3176
+ 'default': 1
3177
+ }, {
3178
+ 'name': 'maxbins',
3179
+ 'type': 'number',
3180
+ 'default': 40
3181
+ }, {
3182
+ 'name': 'extent',
3183
+ 'type': 'date',
3184
+ 'array': true
3185
+ }, {
3186
+ 'name': 'timezone',
3187
+ 'type': 'enum',
3188
+ 'default': 'local',
3189
+ 'values': ['local', 'utc']
3190
+ }, {
3191
+ 'name': 'as',
3192
+ 'type': 'string',
3193
+ 'array': true,
3194
+ 'length': 2,
3195
+ 'default': OUTPUT
3196
+ }]
3197
+ };
3198
+ vegaUtil.inherits(TimeUnit, vegaDataflow.Transform, {
3199
+ transform(_, pulse) {
3200
+ const field = _.field,
3201
+ band = _.interval !== false,
3202
+ utc = _.timezone === 'utc',
3203
+ floor = this._floor(_, pulse),
3204
+ offset = (utc ? vegaTime.utcInterval : vegaTime.timeInterval)(floor.unit).offset,
3205
+ as = _.as || OUTPUT,
3206
+ u0 = as[0],
3207
+ u1 = as[1],
3208
+ step = floor.step;
3209
+ let min = floor.start || Infinity,
3210
+ max = floor.stop || -Infinity,
3211
+ flag = pulse.ADD;
3212
+ if (_.modified() || pulse.changed(pulse.REM) || pulse.modified(vegaUtil.accessorFields(field))) {
3213
+ pulse = pulse.reflow(true);
3214
+ flag = pulse.SOURCE;
3215
+ min = Infinity;
3216
+ max = -Infinity;
3217
+ }
3218
+ pulse.visit(flag, t => {
3219
+ const v = field(t);
3220
+ let a, b;
3221
+ if (v == null) {
3222
+ t[u0] = null;
3223
+ if (band) t[u1] = null;
3224
+ } else {
3225
+ t[u0] = a = b = floor(v);
3226
+ if (band) t[u1] = b = offset(a, step);
3227
+ if (a < min) min = a;
3228
+ if (b > max) max = b;
3229
+ }
3230
+ });
3231
+ floor.start = min;
3232
+ floor.stop = max;
3233
+ return pulse.modifies(band ? as : u0);
3234
+ },
3235
+ _floor(_, pulse) {
3236
+ const utc = _.timezone === 'utc';
3237
+
3238
+ // get parameters
3239
+ const {
3240
+ units,
3241
+ step
3242
+ } = _.units ? {
3243
+ units: _.units,
3244
+ step: _.step || 1
3245
+ } : vegaTime.timeBin({
3246
+ extent: _.extent || vegaUtil.extent(pulse.materialize(pulse.SOURCE).source, _.field),
3247
+ maxbins: _.maxbins
3248
+ });
3249
+
3250
+ // check / standardize time units
3251
+ const tunits = vegaTime.timeUnits(units),
3252
+ prev = this.value || {},
3253
+ floor = (utc ? vegaTime.utcFloor : vegaTime.timeFloor)(tunits, step);
3254
+ floor.unit = vegaUtil.peek(tunits);
3255
+ floor.units = tunits;
3256
+ floor.step = step;
3257
+ floor.start = prev.start;
3258
+ floor.stop = prev.stop;
3259
+ return this.value = floor;
3260
+ }
3261
+ });
3262
+
3263
+ /**
3264
+ * An index that maps from unique, string-coerced, field values to tuples.
3265
+ * Assumes that the field serves as a unique key with no duplicate values.
3266
+ * @constructor
3267
+ * @param {object} params - The parameters for this operator.
3268
+ * @param {function(object): *} params.field - The field accessor to index.
3269
+ */
3270
+ function TupleIndex(params) {
3271
+ vegaDataflow.Transform.call(this, vegaUtil.fastmap(), params);
3272
+ }
3273
+ vegaUtil.inherits(TupleIndex, vegaDataflow.Transform, {
3274
+ transform(_, pulse) {
3275
+ const df = pulse.dataflow,
3276
+ field = _.field,
3277
+ index = this.value,
3278
+ set = t => index.set(field(t), t);
3279
+ let mod = true;
3280
+ if (_.modified('field') || pulse.modified(field.fields)) {
3281
+ index.clear();
3282
+ pulse.visit(pulse.SOURCE, set);
3283
+ } else if (pulse.changed()) {
3284
+ pulse.visit(pulse.REM, t => index.delete(field(t)));
3285
+ pulse.visit(pulse.ADD, set);
3286
+ } else {
3287
+ mod = false;
3288
+ }
3289
+ this.modified(mod);
3290
+ if (index.empty > df.cleanThreshold) df.runAfter(index.clean);
3291
+ return pulse.fork();
3292
+ }
3293
+ });
3294
+
3295
+ /**
3296
+ * Extracts an array of values. Assumes the source data has already been
3297
+ * reduced as needed (e.g., by an upstream Aggregate transform).
3298
+ * @constructor
3299
+ * @param {object} params - The parameters for this operator.
3300
+ * @param {function(object): *} params.field - The domain field to extract.
3301
+ * @param {function(*,*): number} [params.sort] - An optional
3302
+ * comparator function for sorting the values. The comparator will be
3303
+ * applied to backing tuples prior to value extraction.
3304
+ */
3305
+ function Values(params) {
3306
+ vegaDataflow.Transform.call(this, null, params);
3307
+ }
3308
+ vegaUtil.inherits(Values, vegaDataflow.Transform, {
3309
+ transform(_, pulse) {
3310
+ const run = !this.value || _.modified('field') || _.modified('sort') || pulse.changed() || _.sort && pulse.modified(_.sort.fields);
3311
+ if (run) {
3312
+ this.value = (_.sort ? pulse.source.slice().sort(vegaDataflow.stableCompare(_.sort)) : pulse.source).map(_.field);
3313
+ }
3314
+ }
3315
+ });
3316
+
3317
+ function WindowOp(op, field, param, as) {
3318
+ const fn = WindowOps[op](field, param);
3319
+ return {
3320
+ init: fn.init || vegaUtil.zero,
3321
+ update: function (w, t) {
3322
+ t[as] = fn.next(w);
3323
+ }
3324
+ };
3325
+ }
3326
+ const WindowOps = {
3327
+ row_number: function () {
3328
+ return {
3329
+ next: w => w.index + 1
3330
+ };
3331
+ },
3332
+ rank: function () {
3333
+ let rank;
3334
+ return {
3335
+ init: () => rank = 1,
3336
+ next: w => {
3337
+ const i = w.index,
3338
+ data = w.data;
3339
+ return i && w.compare(data[i - 1], data[i]) ? rank = i + 1 : rank;
3340
+ }
3341
+ };
3342
+ },
3343
+ dense_rank: function () {
3344
+ let drank;
3345
+ return {
3346
+ init: () => drank = 1,
3347
+ next: w => {
3348
+ const i = w.index,
3349
+ d = w.data;
3350
+ return i && w.compare(d[i - 1], d[i]) ? ++drank : drank;
3351
+ }
3352
+ };
3353
+ },
3354
+ percent_rank: function () {
3355
+ const rank = WindowOps.rank(),
3356
+ next = rank.next;
3357
+ return {
3358
+ init: rank.init,
3359
+ next: w => (next(w) - 1) / (w.data.length - 1)
3360
+ };
3361
+ },
3362
+ cume_dist: function () {
3363
+ let cume;
3364
+ return {
3365
+ init: () => cume = 0,
3366
+ next: w => {
3367
+ const d = w.data,
3368
+ c = w.compare;
3369
+ let i = w.index;
3370
+ if (cume < i) {
3371
+ while (i + 1 < d.length && !c(d[i], d[i + 1])) ++i;
3372
+ cume = i;
3373
+ }
3374
+ return (1 + cume) / d.length;
3375
+ }
3376
+ };
3377
+ },
3378
+ ntile: function (field, num) {
3379
+ num = +num;
3380
+ if (!(num > 0)) vegaUtil.error('ntile num must be greater than zero.');
3381
+ const cume = WindowOps.cume_dist(),
3382
+ next = cume.next;
3383
+ return {
3384
+ init: cume.init,
3385
+ next: w => Math.ceil(num * next(w))
3386
+ };
3387
+ },
3388
+ lag: function (field, offset) {
3389
+ offset = +offset || 1;
3390
+ return {
3391
+ next: w => {
3392
+ const i = w.index - offset;
3393
+ return i >= 0 ? field(w.data[i]) : null;
3394
+ }
3395
+ };
3396
+ },
3397
+ lead: function (field, offset) {
3398
+ offset = +offset || 1;
3399
+ return {
3400
+ next: w => {
3401
+ const i = w.index + offset,
3402
+ d = w.data;
3403
+ return i < d.length ? field(d[i]) : null;
3404
+ }
3405
+ };
3406
+ },
3407
+ first_value: function (field) {
3408
+ return {
3409
+ next: w => field(w.data[w.i0])
3410
+ };
3411
+ },
3412
+ last_value: function (field) {
3413
+ return {
3414
+ next: w => field(w.data[w.i1 - 1])
3415
+ };
3416
+ },
3417
+ nth_value: function (field, nth) {
3418
+ nth = +nth;
3419
+ if (!(nth > 0)) vegaUtil.error('nth_value nth must be greater than zero.');
3420
+ return {
3421
+ next: w => {
3422
+ const i = w.i0 + (nth - 1);
3423
+ return i < w.i1 ? field(w.data[i]) : null;
3424
+ }
3425
+ };
3426
+ },
3427
+ prev_value: function (field) {
3428
+ let prev;
3429
+ return {
3430
+ init: () => prev = null,
3431
+ next: w => {
3432
+ const v = field(w.data[w.index]);
3433
+ return v != null ? prev = v : prev;
3434
+ }
3435
+ };
3436
+ },
3437
+ next_value: function (field) {
3438
+ let v, i;
3439
+ return {
3440
+ init: () => (v = null, i = -1),
3441
+ next: w => {
3442
+ const d = w.data;
3443
+ return w.index <= i ? v : (i = find(field, d, w.index)) < 0 ? (i = d.length, v = null) : v = field(d[i]);
3444
+ }
3445
+ };
3446
+ }
3447
+ };
3448
+ function find(field, data, index) {
3449
+ for (let n = data.length; index < n; ++index) {
3450
+ const v = field(data[index]);
3451
+ if (v != null) return index;
3452
+ }
3453
+ return -1;
3454
+ }
3455
+ const ValidWindowOps = Object.keys(WindowOps);
3456
+
3457
+ function WindowState(_) {
3458
+ const ops = vegaUtil.array(_.ops),
3459
+ fields = vegaUtil.array(_.fields),
3460
+ params = vegaUtil.array(_.params),
3461
+ aggregate_params = vegaUtil.array(_.aggregate_params),
3462
+ as = vegaUtil.array(_.as),
3463
+ outputs = this.outputs = [],
3464
+ windows = this.windows = [],
3465
+ inputs = {},
3466
+ map = {},
3467
+ counts = [],
3468
+ measures = [];
3469
+ let countOnly = true;
3470
+ function visitInputs(f) {
3471
+ vegaUtil.array(vegaUtil.accessorFields(f)).forEach(_ => inputs[_] = 1);
3472
+ }
3473
+ visitInputs(_.sort);
3474
+ ops.forEach((op, i) => {
3475
+ const field = fields[i],
3476
+ param = params[i],
3477
+ aggregate_param = aggregate_params[i] || null,
3478
+ mname = vegaUtil.accessorName(field),
3479
+ name = measureName(op, mname, as[i]);
3480
+ visitInputs(field);
3481
+ outputs.push(name);
3482
+
3483
+ // Window operation
3484
+ if (vegaUtil.hasOwnProperty(WindowOps, op)) {
3485
+ windows.push(WindowOp(op, field, param, name));
3486
+ }
3487
+
3488
+ // Aggregate operation
3489
+ else {
3490
+ if (field == null && op !== 'count') {
3491
+ vegaUtil.error('Null aggregate field specified.');
3492
+ }
3493
+ if (op === 'count') {
3494
+ counts.push(name);
3495
+ return;
3496
+ }
3497
+ countOnly = false;
3498
+ let m = map[mname];
3499
+ if (!m) {
3500
+ m = map[mname] = [];
3501
+ m.field = field;
3502
+ measures.push(m);
3503
+ }
3504
+ m.push(createMeasure(op, aggregate_param, name));
3505
+ }
3506
+ });
3507
+ if (counts.length || measures.length) {
3508
+ this.cell = cell(measures, counts, countOnly);
3509
+ }
3510
+ this.inputs = Object.keys(inputs);
3511
+ }
3512
+ const prototype = WindowState.prototype;
3513
+ prototype.init = function () {
3514
+ this.windows.forEach(_ => _.init());
3515
+ if (this.cell) this.cell.init();
3516
+ };
3517
+ prototype.update = function (w, t) {
3518
+ const cell = this.cell,
3519
+ wind = this.windows,
3520
+ data = w.data,
3521
+ m = wind && wind.length;
3522
+ let j;
3523
+ if (cell) {
3524
+ for (j = w.p0; j < w.i0; ++j) cell.rem(data[j]);
3525
+ for (j = w.p1; j < w.i1; ++j) cell.add(data[j]);
3526
+ cell.set(t);
3527
+ }
3528
+ for (j = 0; j < m; ++j) wind[j].update(w, t);
3529
+ };
3530
+ function cell(measures, counts, countOnly) {
3531
+ measures = measures.map(m => compileMeasures(m, m.field));
3532
+ const cell = {
3533
+ num: 0,
3534
+ agg: null,
3535
+ store: false,
3536
+ count: counts
3537
+ };
3538
+ if (!countOnly) {
3539
+ var n = measures.length,
3540
+ a = cell.agg = Array(n),
3541
+ i = 0;
3542
+ for (; i < n; ++i) a[i] = new measures[i](cell);
3543
+ }
3544
+ if (cell.store) {
3545
+ var store = cell.data = new TupleStore();
3546
+ }
3547
+ cell.add = function (t) {
3548
+ cell.num += 1;
3549
+ if (countOnly) return;
3550
+ if (store) store.add(t);
3551
+ for (let i = 0; i < n; ++i) {
3552
+ a[i].add(a[i].get(t), t);
3553
+ }
3554
+ };
3555
+ cell.rem = function (t) {
3556
+ cell.num -= 1;
3557
+ if (countOnly) return;
3558
+ if (store) store.rem(t);
3559
+ for (let i = 0; i < n; ++i) {
3560
+ a[i].rem(a[i].get(t), t);
3561
+ }
3562
+ };
3563
+ cell.set = function (t) {
3564
+ let i, n;
3565
+
3566
+ // consolidate stored values
3567
+ if (store) store.values();
3568
+
3569
+ // update tuple properties
3570
+ for (i = 0, n = counts.length; i < n; ++i) t[counts[i]] = cell.num;
3571
+ if (!countOnly) for (i = 0, n = a.length; i < n; ++i) a[i].set(t);
3572
+ };
3573
+ cell.init = function () {
3574
+ cell.num = 0;
3575
+ if (store) store.reset();
3576
+ for (let i = 0; i < n; ++i) a[i].init();
3577
+ };
3578
+ return cell;
3579
+ }
3580
+
3581
+ /**
3582
+ * Perform window calculations and write results to the input stream.
3583
+ * @constructor
3584
+ * @param {object} params - The parameters for this operator.
3585
+ * @param {function(*,*): number} [params.sort] - A comparator function for sorting tuples within a window.
3586
+ * @param {Array<function(object): *>} [params.groupby] - An array of accessors by which to partition tuples into separate windows.
3587
+ * @param {Array<string>} params.ops - An array of strings indicating window operations to perform.
3588
+ * @param {Array<function(object): *>} [params.fields] - An array of accessors
3589
+ * for data fields to use as inputs to window operations.
3590
+ * @param {Array<*>} [params.params] - An array of parameter values for window operations.
3591
+ * @param {Array<number>} [params.aggregate_params] - An optional array of parameter values for aggregation operations.
3592
+ * @param {Array<string>} [params.as] - An array of output field names for window operations.
3593
+ * @param {Array<number>} [params.frame] - Window frame definition as two-element array.
3594
+ * @param {boolean} [params.ignorePeers=false] - If true, base window frame boundaries on row
3595
+ * number alone, ignoring peers with identical sort values. If false (default),
3596
+ * the window boundaries will be adjusted to include peer values.
3597
+ */
3598
+ function Window(params) {
3599
+ vegaDataflow.Transform.call(this, {}, params);
3600
+ this._mlen = 0;
3601
+ this._mods = [];
3602
+ }
3603
+ Window.Definition = {
3604
+ 'type': 'Window',
3605
+ 'metadata': {
3606
+ 'modifies': true
3607
+ },
3608
+ 'params': [{
3609
+ 'name': 'sort',
3610
+ 'type': 'compare'
3611
+ }, {
3612
+ 'name': 'groupby',
3613
+ 'type': 'field',
3614
+ 'array': true
3615
+ }, {
3616
+ 'name': 'ops',
3617
+ 'type': 'enum',
3618
+ 'array': true,
3619
+ 'values': ValidWindowOps.concat(ValidAggregateOps)
3620
+ }, {
3621
+ 'name': 'params',
3622
+ 'type': 'number',
3623
+ 'null': true,
3624
+ 'array': true
3625
+ }, {
3626
+ 'name': 'aggregate_params',
3627
+ 'type': 'number',
3628
+ 'null': true,
3629
+ 'array': true
3630
+ }, {
3631
+ 'name': 'fields',
3632
+ 'type': 'field',
3633
+ 'null': true,
3634
+ 'array': true
3635
+ }, {
3636
+ 'name': 'as',
3637
+ 'type': 'string',
3638
+ 'null': true,
3639
+ 'array': true
3640
+ }, {
3641
+ 'name': 'frame',
3642
+ 'type': 'number',
3643
+ 'null': true,
3644
+ 'array': true,
3645
+ 'length': 2,
3646
+ 'default': [null, 0]
3647
+ }, {
3648
+ 'name': 'ignorePeers',
3649
+ 'type': 'boolean',
3650
+ 'default': false
3651
+ }]
3652
+ };
3653
+ vegaUtil.inherits(Window, vegaDataflow.Transform, {
3654
+ transform(_, pulse) {
3655
+ this.stamp = pulse.stamp;
3656
+ const mod = _.modified(),
3657
+ cmp = vegaDataflow.stableCompare(_.sort),
3658
+ key = groupkey(_.groupby),
3659
+ group = t => this.group(key(t));
3660
+
3661
+ // initialize window state
3662
+ let state = this.state;
3663
+ if (!state || mod) {
3664
+ state = this.state = new WindowState(_);
3665
+ }
3666
+
3667
+ // partition input tuples
3668
+ if (mod || pulse.modified(state.inputs)) {
3669
+ this.value = {};
3670
+ pulse.visit(pulse.SOURCE, t => group(t).add(t));
3671
+ } else {
3672
+ pulse.visit(pulse.REM, t => group(t).remove(t));
3673
+ pulse.visit(pulse.ADD, t => group(t).add(t));
3674
+ }
3675
+
3676
+ // perform window calculations for each modified partition
3677
+ for (let i = 0, n = this._mlen; i < n; ++i) {
3678
+ processPartition(this._mods[i], state, cmp, _);
3679
+ }
3680
+ this._mlen = 0;
3681
+ this._mods = [];
3682
+
3683
+ // TODO don't reflow everything?
3684
+ return pulse.reflow(mod).modifies(state.outputs);
3685
+ },
3686
+ group(key) {
3687
+ let group = this.value[key];
3688
+ if (!group) {
3689
+ group = this.value[key] = SortedList(vegaDataflow.tupleid);
3690
+ group.stamp = -1;
3691
+ }
3692
+ if (group.stamp < this.stamp) {
3693
+ group.stamp = this.stamp;
3694
+ this._mods[this._mlen++] = group;
3695
+ }
3696
+ return group;
3697
+ }
3698
+ });
3699
+ function processPartition(list, state, cmp, _) {
3700
+ const sort = _.sort,
3701
+ range = sort && !_.ignorePeers,
3702
+ frame = _.frame || [null, 0],
3703
+ data = list.data(cmp),
3704
+ // use cmp for stable sort
3705
+ n = data.length,
3706
+ b = range ? bisector.default(sort) : null,
3707
+ w = {
3708
+ i0: 0,
3709
+ i1: 0,
3710
+ p0: 0,
3711
+ p1: 0,
3712
+ index: 0,
3713
+ data: data,
3714
+ compare: sort || vegaUtil.constant(-1)
3715
+ };
3716
+ state.init();
3717
+ for (let i = 0; i < n; ++i) {
3718
+ setWindow(w, frame, i, n);
3719
+ if (range) adjustRange(w, b);
3720
+ state.update(w, data[i]);
3721
+ }
3722
+ }
3723
+ function setWindow(w, f, i, n) {
3724
+ w.p0 = w.i0;
3725
+ w.p1 = w.i1;
3726
+ w.i0 = f[0] == null ? 0 : Math.max(0, i - Math.abs(f[0]));
3727
+ w.i1 = f[1] == null ? n : Math.min(n, i + Math.abs(f[1]) + 1);
3728
+ w.index = i;
3729
+ }
3730
+
3731
+ // if frame type is 'range', adjust window for peer values
3732
+ function adjustRange(w, bisect) {
3733
+ const r0 = w.i0,
3734
+ r1 = w.i1 - 1,
3735
+ c = w.compare,
3736
+ d = w.data,
3737
+ n = d.length - 1;
3738
+ if (r0 > 0 && !c(d[r0], d[r0 - 1])) w.i0 = bisect.left(d, d[r0]);
3739
+ if (r1 < n && !c(d[r1], d[r1 + 1])) w.i1 = bisect.right(d, d[r1]);
3740
+ }
3741
+
3742
+ exports.aggregate = Aggregate;
3743
+ exports.bin = Bin;
3744
+ exports.collect = Collect;
3745
+ exports.compare = Compare;
3746
+ exports.countpattern = CountPattern;
3747
+ exports.cross = Cross;
3748
+ exports.density = Density;
3749
+ exports.dotbin = DotBin;
3750
+ exports.expression = Expression;
3751
+ exports.extent = Extent;
3752
+ exports.facet = Facet;
3753
+ exports.field = Field;
3754
+ exports.filter = Filter;
3755
+ exports.flatten = Flatten;
3756
+ exports.fold = Fold;
3757
+ exports.formula = Formula;
3758
+ exports.generate = Generate;
3759
+ exports.impute = Impute;
3760
+ exports.joinaggregate = JoinAggregate;
3761
+ exports.kde = KDE;
3762
+ exports.key = Key;
3763
+ exports.load = Load;
3764
+ exports.lookup = Lookup;
3765
+ exports.multiextent = MultiExtent;
3766
+ exports.multivalues = MultiValues;
3767
+ exports.params = Params;
3768
+ exports.pivot = Pivot;
3769
+ exports.prefacet = PreFacet;
3770
+ exports.project = Project;
3771
+ exports.proxy = Proxy;
3772
+ exports.quantile = Quantile;
3773
+ exports.relay = Relay;
3774
+ exports.sample = Sample;
3775
+ exports.sequence = Sequence;
3776
+ exports.sieve = Sieve;
3777
+ exports.subflow = Subflow;
3778
+ exports.timeunit = TimeUnit;
3779
+ exports.tupleindex = TupleIndex;
3780
+ exports.values = Values;
3781
+ exports.window = Window;