@uwdata/mosaic-sql 0.17.0 → 0.19.0

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 (429) hide show
  1. package/LICENSE +47 -0
  2. package/README.md +0 -2
  3. package/dist/src/ast/aggregate.d.ts +82 -0
  4. package/dist/src/ast/aggregate.d.ts.map +1 -0
  5. package/dist/src/ast/aggregate.js +180 -0
  6. package/dist/src/ast/aggregate.js.map +1 -0
  7. package/dist/src/ast/between-op.d.ts +46 -0
  8. package/dist/src/ast/between-op.d.ts.map +1 -0
  9. package/dist/src/ast/between-op.js +60 -0
  10. package/dist/src/ast/between-op.js.map +1 -0
  11. package/dist/src/ast/binary-op.d.ts +21 -0
  12. package/dist/src/ast/binary-op.d.ts.map +1 -0
  13. package/dist/src/ast/binary-op.js +29 -0
  14. package/dist/src/ast/binary-op.js.map +1 -0
  15. package/dist/src/ast/case.d.ts +53 -0
  16. package/dist/src/ast/case.d.ts.map +1 -0
  17. package/dist/src/ast/case.js +75 -0
  18. package/dist/src/ast/case.js.map +1 -0
  19. package/dist/src/ast/cast.d.ts +18 -0
  20. package/dist/src/ast/cast.d.ts.map +1 -0
  21. package/dist/src/ast/cast.js +26 -0
  22. package/dist/src/ast/cast.js.map +1 -0
  23. package/dist/src/ast/collate.d.ts +18 -0
  24. package/dist/src/ast/collate.d.ts.map +1 -0
  25. package/dist/src/ast/collate.js +25 -0
  26. package/dist/src/ast/collate.js.map +1 -0
  27. package/dist/src/ast/column-param.d.ts +23 -0
  28. package/dist/src/ast/column-param.d.ts.map +1 -0
  29. package/dist/src/ast/column-param.js +29 -0
  30. package/dist/src/ast/column-param.js.map +1 -0
  31. package/dist/src/ast/column-ref.d.ts +40 -0
  32. package/dist/src/ast/column-ref.d.ts.map +1 -0
  33. package/dist/src/ast/column-ref.js +58 -0
  34. package/dist/src/ast/column-ref.js.map +1 -0
  35. package/dist/src/ast/fragment.d.ts +20 -0
  36. package/dist/src/ast/fragment.d.ts.map +1 -0
  37. package/dist/src/ast/fragment.js +26 -0
  38. package/dist/src/ast/fragment.js.map +1 -0
  39. package/dist/src/ast/from.d.ts +22 -0
  40. package/dist/src/ast/from.d.ts.map +1 -0
  41. package/dist/src/ast/from.js +37 -0
  42. package/dist/src/ast/from.js.map +1 -0
  43. package/dist/src/ast/function.d.ts +18 -0
  44. package/dist/src/ast/function.d.ts.map +1 -0
  45. package/dist/src/ast/function.js +26 -0
  46. package/dist/src/ast/function.js.map +1 -0
  47. package/dist/src/ast/in-op.d.ts +18 -0
  48. package/dist/src/ast/in-op.d.ts.map +1 -0
  49. package/dist/src/ast/in-op.js +25 -0
  50. package/dist/src/ast/in-op.js.map +1 -0
  51. package/dist/src/ast/interval.d.ts +18 -0
  52. package/dist/src/ast/interval.d.ts.map +1 -0
  53. package/dist/src/ast/interval.js +25 -0
  54. package/dist/src/ast/interval.js.map +1 -0
  55. package/dist/src/ast/list.d.ts +15 -0
  56. package/dist/src/ast/list.d.ts.map +1 -0
  57. package/dist/src/ast/list.js +21 -0
  58. package/dist/src/ast/list.js.map +1 -0
  59. package/dist/src/ast/literal.d.ts +16 -0
  60. package/dist/src/ast/literal.d.ts.map +1 -0
  61. package/dist/src/ast/literal.js +53 -0
  62. package/dist/src/ast/literal.js.map +1 -0
  63. package/dist/src/ast/logical-op.d.ts +32 -0
  64. package/dist/src/ast/logical-op.d.ts.map +1 -0
  65. package/dist/src/ast/logical-op.js +46 -0
  66. package/dist/src/ast/logical-op.js.map +1 -0
  67. package/dist/src/ast/node.d.ts +25 -0
  68. package/dist/src/ast/node.d.ts.map +1 -0
  69. package/dist/src/ast/node.js +36 -0
  70. package/dist/src/ast/node.js.map +1 -0
  71. package/dist/src/ast/order-by.d.ts +21 -0
  72. package/dist/src/ast/order-by.d.ts.map +1 -0
  73. package/dist/src/ast/order-by.js +36 -0
  74. package/dist/src/ast/order-by.js.map +1 -0
  75. package/dist/src/ast/param.d.ts +20 -0
  76. package/dist/src/ast/param.d.ts.map +1 -0
  77. package/dist/src/ast/param.js +28 -0
  78. package/dist/src/ast/param.js.map +1 -0
  79. package/dist/src/ast/query.d.ts +334 -0
  80. package/dist/src/ast/query.d.ts.map +1 -0
  81. package/dist/src/ast/query.js +640 -0
  82. package/dist/src/ast/query.js.map +1 -0
  83. package/dist/src/ast/sample.d.ts +27 -0
  84. package/dist/src/ast/sample.d.ts.map +1 -0
  85. package/dist/src/ast/sample.js +38 -0
  86. package/dist/src/ast/sample.js.map +1 -0
  87. package/dist/src/ast/select.d.ts +19 -0
  88. package/dist/src/ast/select.d.ts.map +1 -0
  89. package/dist/src/ast/select.js +35 -0
  90. package/dist/src/ast/select.js.map +1 -0
  91. package/dist/src/ast/subquery.d.ts +16 -0
  92. package/dist/src/ast/subquery.d.ts.map +1 -0
  93. package/dist/src/ast/subquery.js +21 -0
  94. package/dist/src/ast/subquery.js.map +1 -0
  95. package/dist/src/ast/table-ref.d.ts +24 -0
  96. package/dist/src/ast/table-ref.d.ts.map +1 -0
  97. package/dist/src/ast/table-ref.js +35 -0
  98. package/dist/src/ast/table-ref.js.map +1 -0
  99. package/dist/src/ast/unary-op.d.ts +40 -0
  100. package/dist/src/ast/unary-op.d.ts.map +1 -0
  101. package/dist/src/ast/unary-op.js +52 -0
  102. package/dist/src/ast/unary-op.js.map +1 -0
  103. package/dist/src/ast/unnest.d.ts +19 -0
  104. package/dist/src/ast/unnest.d.ts.map +1 -0
  105. package/dist/src/ast/unnest.js +29 -0
  106. package/dist/src/ast/unnest.js.map +1 -0
  107. package/dist/src/ast/verbatim.d.ts +18 -0
  108. package/dist/src/ast/verbatim.d.ts.map +1 -0
  109. package/dist/src/ast/verbatim.js +25 -0
  110. package/dist/src/ast/verbatim.js.map +1 -0
  111. package/dist/src/ast/window-frame.d.ts +54 -0
  112. package/dist/src/ast/window-frame.d.ts.map +1 -0
  113. package/dist/src/ast/window-frame.js +79 -0
  114. package/dist/src/ast/window-frame.js.map +1 -0
  115. package/dist/src/ast/window.d.ts +128 -0
  116. package/dist/src/ast/window.d.ts.map +1 -0
  117. package/dist/src/ast/window.js +194 -0
  118. package/dist/src/ast/window.js.map +1 -0
  119. package/dist/src/ast/with.d.ts +25 -0
  120. package/dist/src/ast/with.d.ts.map +1 -0
  121. package/dist/src/ast/with.js +36 -0
  122. package/dist/src/ast/with.js.map +1 -0
  123. package/dist/src/constants.d.ts +40 -0
  124. package/dist/src/constants.d.ts.map +1 -0
  125. package/dist/src/constants.js +40 -0
  126. package/dist/src/constants.js.map +1 -0
  127. package/dist/src/functions/aggregate.d.ts +236 -0
  128. package/dist/src/functions/aggregate.d.ts.map +1 -0
  129. package/dist/src/functions/aggregate.js +308 -0
  130. package/dist/src/functions/aggregate.js.map +1 -0
  131. package/dist/src/functions/case.d.ts +13 -0
  132. package/dist/src/functions/case.d.ts.map +1 -0
  133. package/dist/src/functions/case.js +17 -0
  134. package/dist/src/functions/case.js.map +1 -0
  135. package/dist/src/functions/cast.d.ts +23 -0
  136. package/dist/src/functions/cast.d.ts.map +1 -0
  137. package/dist/src/functions/cast.js +32 -0
  138. package/dist/src/functions/cast.js.map +1 -0
  139. package/dist/src/functions/collate.d.ts +10 -0
  140. package/dist/src/functions/collate.d.ts.map +1 -0
  141. package/dist/src/functions/collate.js +12 -0
  142. package/dist/src/functions/collate.js.map +1 -0
  143. package/dist/src/functions/column.d.ts +10 -0
  144. package/dist/src/functions/column.d.ts.map +1 -0
  145. package/dist/src/functions/column.js +17 -0
  146. package/dist/src/functions/column.js.map +1 -0
  147. package/dist/src/functions/cte.d.ts +13 -0
  148. package/dist/src/functions/cte.d.ts.map +1 -0
  149. package/dist/src/functions/cte.js +14 -0
  150. package/dist/src/functions/cte.js.map +1 -0
  151. package/dist/src/functions/datetime.d.ts +32 -0
  152. package/dist/src/functions/datetime.d.ts.map +1 -0
  153. package/dist/src/functions/datetime.js +45 -0
  154. package/dist/src/functions/datetime.js.map +1 -0
  155. package/dist/src/functions/interval.d.ts +48 -0
  156. package/dist/src/functions/interval.d.ts.map +1 -0
  157. package/dist/src/functions/interval.js +66 -0
  158. package/dist/src/functions/interval.js.map +1 -0
  159. package/dist/src/functions/list.d.ts +31 -0
  160. package/dist/src/functions/list.d.ts.map +1 -0
  161. package/dist/src/functions/list.js +49 -0
  162. package/dist/src/functions/list.js.map +1 -0
  163. package/dist/src/functions/literal.d.ts +16 -0
  164. package/dist/src/functions/literal.d.ts.map +1 -0
  165. package/dist/src/functions/literal.js +20 -0
  166. package/dist/src/functions/literal.js.map +1 -0
  167. package/dist/src/functions/numeric.d.ts +80 -0
  168. package/dist/src/functions/numeric.d.ts.map +1 -0
  169. package/dist/src/functions/numeric.js +110 -0
  170. package/dist/src/functions/numeric.js.map +1 -0
  171. package/dist/src/functions/operators.d.ts +169 -0
  172. package/dist/src/functions/operators.d.ts.map +1 -0
  173. package/dist/src/functions/operators.js +235 -0
  174. package/dist/src/functions/operators.js.map +1 -0
  175. package/dist/src/functions/order-by.d.ts +15 -0
  176. package/dist/src/functions/order-by.d.ts.map +1 -0
  177. package/dist/src/functions/order-by.js +19 -0
  178. package/dist/src/functions/order-by.js.map +1 -0
  179. package/dist/src/functions/spatial.d.ts +32 -0
  180. package/dist/src/functions/spatial.d.ts.map +1 -0
  181. package/dist/src/functions/spatial.js +44 -0
  182. package/dist/src/functions/spatial.js.map +1 -0
  183. package/dist/src/functions/sql-template-tag.d.ts +13 -0
  184. package/dist/src/functions/sql-template-tag.d.ts.map +1 -0
  185. package/dist/src/functions/sql-template-tag.js +44 -0
  186. package/dist/src/functions/sql-template-tag.js.map +1 -0
  187. package/dist/src/functions/string.d.ts +49 -0
  188. package/dist/src/functions/string.d.ts.map +1 -0
  189. package/dist/src/functions/string.js +67 -0
  190. package/dist/src/functions/string.js.map +1 -0
  191. package/dist/src/functions/table-ref.d.ts +10 -0
  192. package/dist/src/functions/table-ref.d.ts.map +1 -0
  193. package/dist/src/functions/table-ref.js +13 -0
  194. package/dist/src/functions/table-ref.js.map +1 -0
  195. package/dist/src/functions/unnest.d.ts +10 -0
  196. package/dist/src/functions/unnest.d.ts.map +1 -0
  197. package/dist/src/functions/unnest.js +12 -0
  198. package/dist/src/functions/unnest.js.map +1 -0
  199. package/dist/src/functions/util.d.ts +7 -0
  200. package/dist/src/functions/util.d.ts.map +1 -0
  201. package/dist/src/functions/util.js +9 -0
  202. package/dist/src/functions/util.js.map +1 -0
  203. package/dist/src/functions/window-frame.d.ts +41 -0
  204. package/dist/src/functions/window-frame.d.ts.map +1 -0
  205. package/dist/src/functions/window-frame.js +52 -0
  206. package/dist/src/functions/window-frame.js.map +1 -0
  207. package/dist/src/functions/window.d.ts +74 -0
  208. package/dist/src/functions/window.d.ts.map +1 -0
  209. package/dist/src/functions/window.js +96 -0
  210. package/dist/src/functions/window.js.map +1 -0
  211. package/dist/src/index.d.ts +73 -0
  212. package/dist/src/index.d.ts.map +1 -0
  213. package/{src → dist/src}/index.js +8 -8
  214. package/dist/src/index.js.map +1 -0
  215. package/dist/src/load/create.d.ts +10 -0
  216. package/dist/src/load/create.d.ts.map +1 -0
  217. package/dist/src/load/create.js +14 -0
  218. package/dist/src/load/create.js.map +1 -0
  219. package/dist/src/load/extension.d.ts +2 -0
  220. package/dist/src/load/extension.d.ts.map +1 -0
  221. package/dist/src/load/extension.js +4 -0
  222. package/dist/src/load/extension.js.map +1 -0
  223. package/dist/src/load/load.d.ts +18 -0
  224. package/dist/src/load/load.d.ts.map +1 -0
  225. package/dist/src/load/load.js +80 -0
  226. package/dist/src/load/load.js.map +1 -0
  227. package/dist/src/load/sql-from.d.ts +14 -0
  228. package/dist/src/load/sql-from.d.ts.map +1 -0
  229. package/dist/src/load/sql-from.js +29 -0
  230. package/dist/src/load/sql-from.js.map +1 -0
  231. package/dist/src/transforms/bin-1d.d.ts +16 -0
  232. package/dist/src/transforms/bin-1d.d.ts.map +1 -0
  233. package/dist/src/transforms/bin-1d.js +21 -0
  234. package/dist/src/transforms/bin-1d.js.map +1 -0
  235. package/dist/src/transforms/bin-2d.d.ts +19 -0
  236. package/dist/src/transforms/bin-2d.d.ts.map +1 -0
  237. package/dist/src/transforms/bin-2d.js +27 -0
  238. package/dist/src/transforms/bin-2d.js.map +1 -0
  239. package/dist/src/transforms/bin-date.d.ts +31 -0
  240. package/dist/src/transforms/bin-date.d.ts.map +1 -0
  241. package/dist/src/transforms/bin-date.js +20 -0
  242. package/dist/src/transforms/bin-date.js.map +1 -0
  243. package/dist/src/transforms/bin-histogram.d.ts +37 -0
  244. package/dist/src/transforms/bin-histogram.d.ts.map +1 -0
  245. package/dist/src/transforms/bin-histogram.js +32 -0
  246. package/dist/src/transforms/bin-histogram.js.map +1 -0
  247. package/dist/src/transforms/bin-linear-1d.d.ts +11 -0
  248. package/dist/src/transforms/bin-linear-1d.d.ts.map +1 -0
  249. package/dist/src/transforms/bin-linear-1d.js +25 -0
  250. package/dist/src/transforms/bin-linear-1d.js.map +1 -0
  251. package/dist/src/transforms/bin-linear-2d.d.ts +20 -0
  252. package/dist/src/transforms/bin-linear-2d.d.ts.map +1 -0
  253. package/dist/src/transforms/bin-linear-2d.js +49 -0
  254. package/dist/src/transforms/bin-linear-2d.js.map +1 -0
  255. package/dist/src/transforms/filter-query.d.ts +12 -0
  256. package/dist/src/transforms/filter-query.d.ts.map +1 -0
  257. package/dist/src/transforms/filter-query.js +39 -0
  258. package/dist/src/transforms/filter-query.js.map +1 -0
  259. package/dist/src/transforms/line-density.d.ts +24 -0
  260. package/dist/src/transforms/line-density.d.ts.map +1 -0
  261. package/dist/src/transforms/line-density.js +98 -0
  262. package/dist/src/transforms/line-density.js.map +1 -0
  263. package/dist/src/transforms/m4.d.ts +19 -0
  264. package/dist/src/transforms/m4.d.ts.map +1 -0
  265. package/dist/src/transforms/m4.js +38 -0
  266. package/dist/src/transforms/m4.js.map +1 -0
  267. package/dist/src/transforms/scales.d.ts +30 -0
  268. package/dist/src/transforms/scales.d.ts.map +1 -0
  269. package/dist/src/transforms/scales.js +103 -0
  270. package/dist/src/transforms/scales.js.map +1 -0
  271. package/dist/src/transforms/util/bin-step.d.ts +50 -0
  272. package/dist/src/transforms/util/bin-step.d.ts.map +1 -0
  273. package/dist/src/transforms/util/bin-step.js +53 -0
  274. package/dist/src/transforms/util/bin-step.js.map +1 -0
  275. package/dist/src/transforms/util/time-interval.d.ts +14 -0
  276. package/dist/src/transforms/util/time-interval.d.ts.map +1 -0
  277. package/dist/src/transforms/util/time-interval.js +88 -0
  278. package/dist/src/transforms/util/time-interval.js.map +1 -0
  279. package/dist/src/types.d.ts +49 -0
  280. package/dist/src/types.d.ts.map +1 -0
  281. package/dist/src/types.js +2 -0
  282. package/dist/src/types.js.map +1 -0
  283. package/dist/src/util/ast.d.ts +62 -0
  284. package/dist/src/util/ast.d.ts.map +1 -0
  285. package/{src → dist/src}/util/ast.js +36 -41
  286. package/dist/src/util/ast.js.map +1 -0
  287. package/dist/src/util/function.d.ts +56 -0
  288. package/dist/src/util/function.d.ts.map +1 -0
  289. package/dist/src/util/function.js +73 -0
  290. package/dist/src/util/function.js.map +1 -0
  291. package/dist/src/util/identity.d.ts +6 -0
  292. package/dist/src/util/identity.d.ts.map +1 -0
  293. package/dist/src/util/identity.js +8 -0
  294. package/dist/src/util/identity.js.map +1 -0
  295. package/dist/src/util/string.d.ts +4 -0
  296. package/dist/src/util/string.d.ts.map +1 -0
  297. package/dist/src/util/string.js +14 -0
  298. package/dist/src/util/string.js.map +1 -0
  299. package/dist/src/util/type-check.d.ts +17 -0
  300. package/dist/src/util/type-check.d.ts.map +1 -0
  301. package/dist/src/util/type-check.js +28 -0
  302. package/dist/src/util/type-check.js.map +1 -0
  303. package/dist/src/visit/clone.d.ts +7 -0
  304. package/dist/src/visit/clone.d.ts.map +1 -0
  305. package/dist/src/visit/clone.js +52 -0
  306. package/dist/src/visit/clone.js.map +1 -0
  307. package/dist/src/visit/recurse.d.ts +2 -0
  308. package/dist/src/visit/recurse.d.ts.map +1 -0
  309. package/dist/src/visit/recurse.js +37 -0
  310. package/dist/src/visit/recurse.js.map +1 -0
  311. package/dist/src/visit/rewrite.d.ts +9 -0
  312. package/dist/src/visit/rewrite.d.ts.map +1 -0
  313. package/dist/src/visit/rewrite.js +39 -0
  314. package/dist/src/visit/rewrite.js.map +1 -0
  315. package/dist/src/visit/visitors.d.ts +32 -0
  316. package/dist/src/visit/visitors.d.ts.map +1 -0
  317. package/dist/src/visit/visitors.js +95 -0
  318. package/dist/src/visit/visitors.js.map +1 -0
  319. package/dist/src/visit/walk.d.ts +21 -0
  320. package/dist/src/visit/walk.d.ts.map +1 -0
  321. package/dist/src/visit/walk.js +32 -0
  322. package/dist/src/visit/walk.js.map +1 -0
  323. package/package.json +13 -7
  324. package/src/ast/{aggregate.js → aggregate.ts} +49 -60
  325. package/src/ast/{between-op.js → between-op.ts} +19 -26
  326. package/src/ast/binary-op.ts +31 -0
  327. package/src/ast/{case.js → case.ts} +29 -44
  328. package/src/ast/{cast.js → cast.ts} +8 -14
  329. package/src/ast/{collate.js → collate.ts} +8 -14
  330. package/src/ast/column-param.ts +34 -0
  331. package/src/ast/{column-ref.js → column-ref.ts} +16 -25
  332. package/src/ast/fragment.ts +28 -0
  333. package/src/ast/{from.js → from.ts} +12 -21
  334. package/src/ast/{function.js → function.ts} +8 -14
  335. package/src/ast/{in-op.js → in-op.ts} +8 -14
  336. package/src/ast/{interval.js → interval.ts} +8 -14
  337. package/src/ast/list.ts +23 -0
  338. package/src/ast/{literal.js → literal.ts} +6 -9
  339. package/src/ast/logical-op.ts +50 -0
  340. package/src/ast/{node.js → node.ts} +10 -13
  341. package/src/ast/order-by.ts +38 -0
  342. package/src/ast/{param.js → param.ts} +6 -12
  343. package/src/ast/{query.js → query.ts} +224 -204
  344. package/src/ast/sample.ts +47 -0
  345. package/src/ast/{select.js → select.ts} +10 -16
  346. package/src/ast/{subquery.js → subquery.ts} +9 -8
  347. package/src/ast/{table-ref.js → table-ref.ts} +7 -12
  348. package/src/ast/{unary-op.js → unary-op.ts} +16 -23
  349. package/src/ast/unnest.ts +31 -0
  350. package/src/ast/verbatim.ts +27 -0
  351. package/src/ast/{window-frame.js → window-frame.ts} +37 -47
  352. package/src/ast/window.ts +246 -0
  353. package/src/ast/{with.js → with.ts} +19 -20
  354. package/src/{constants.js → constants.ts} +2 -0
  355. package/src/functions/aggregate.ts +344 -0
  356. package/src/functions/{case.js → case.ts} +5 -8
  357. package/src/functions/{cast.js → cast.ts} +9 -13
  358. package/src/functions/{collate.js → collate.ts} +4 -7
  359. package/src/functions/{column.js → column.ts} +9 -10
  360. package/src/functions/{cte.js → cte.ts} +9 -6
  361. package/src/functions/{datetime.js → datetime.ts} +12 -20
  362. package/src/functions/interval.ts +74 -0
  363. package/src/functions/list.ts +63 -0
  364. package/src/functions/{literal.js → literal.ts} +5 -7
  365. package/src/functions/numeric.ts +125 -0
  366. package/src/functions/operators.ts +272 -0
  367. package/src/functions/order-by.ts +21 -0
  368. package/src/functions/spatial.ts +50 -0
  369. package/src/functions/{sql-template-tag.js → sql-template-tag.ts} +16 -13
  370. package/src/functions/string.ts +79 -0
  371. package/src/functions/{table-ref.js → table-ref.ts} +4 -4
  372. package/src/functions/unnest.ts +13 -0
  373. package/src/functions/util.ts +10 -0
  374. package/src/functions/window-frame.ts +58 -0
  375. package/src/functions/{window.js → window.ts} +18 -35
  376. package/src/index.ts +79 -0
  377. package/src/load/{create.js → create.ts} +9 -3
  378. package/src/load/extension.ts +3 -0
  379. package/src/load/{load.js → load.ts} +25 -10
  380. package/src/load/{sql-from.js → sql-from.ts} +14 -7
  381. package/src/transforms/{bin-1d.js → bin-1d.ts} +13 -9
  382. package/src/transforms/{bin-2d.js → bin-2d.ts} +17 -13
  383. package/src/transforms/bin-date.ts +48 -0
  384. package/src/transforms/bin-histogram.ts +61 -0
  385. package/src/transforms/{bin-linear-1d.js → bin-linear-1d.ts} +16 -11
  386. package/src/transforms/{bin-linear-2d.js → bin-linear-2d.ts} +23 -35
  387. package/src/transforms/{filter-query.js → filter-query.ts} +10 -14
  388. package/src/transforms/{line-density.js → line-density.ts} +19 -17
  389. package/src/transforms/{m4.js → m4.ts} +17 -14
  390. package/src/transforms/{scales.js → scales.ts} +57 -14
  391. package/src/transforms/util/bin-step.ts +100 -0
  392. package/src/transforms/util/{time-interval.js → time-interval.ts} +32 -21
  393. package/src/types.ts +5 -39
  394. package/src/util/ast.ts +104 -0
  395. package/src/util/{function.js → function.ts} +40 -31
  396. package/src/util/identity.ts +7 -0
  397. package/src/util/{string.js → string.ts} +4 -4
  398. package/src/util/type-check.ts +31 -0
  399. package/src/visit/{clone.js → clone.ts} +10 -10
  400. package/src/visit/{recurse.js → recurse.ts} +3 -1
  401. package/src/visit/{rewrite.js → rewrite.ts} +7 -7
  402. package/src/visit/{visitors.js → visitors.ts} +22 -30
  403. package/src/visit/walk.ts +46 -0
  404. package/src/ast/binary-op.js +0 -40
  405. package/src/ast/column-param.js +0 -40
  406. package/src/ast/fragment.js +0 -26
  407. package/src/ast/logical-op.js +0 -67
  408. package/src/ast/order-by.js +0 -48
  409. package/src/ast/sample.js +0 -53
  410. package/src/ast/verbatim.js +0 -33
  411. package/src/ast/window.js +0 -260
  412. package/src/functions/aggregate.js +0 -347
  413. package/src/functions/interval.js +0 -83
  414. package/src/functions/numeric.js +0 -143
  415. package/src/functions/operators.js +0 -301
  416. package/src/functions/order-by.js +0 -27
  417. package/src/functions/spatial.js +0 -59
  418. package/src/functions/string.js +0 -85
  419. package/src/functions/util.js +0 -14
  420. package/src/functions/window-frame.js +0 -61
  421. package/src/index-types.ts +0 -2
  422. package/src/load/extension.js +0 -3
  423. package/src/transforms/bin-date.js +0 -38
  424. package/src/transforms/bin-histogram.js +0 -52
  425. package/src/transforms/util/bin-step.js +0 -79
  426. package/src/util/type-check.js +0 -33
  427. package/src/visit/walk.js +0 -34
  428. package/tsconfig.json +0 -8
  429. package/vitest.config.ts +0 -3
@@ -0,0 +1,48 @@
1
+ import type { ExprNode } from '../ast/node.js';
2
+ import type { ExprValue } from '../types.js';
3
+ import { dateBin } from '../functions/datetime.js';
4
+ import { interval } from '../functions/interval.js';
5
+ import { add } from '../functions/operators.js';
6
+ import { timeInterval, type DateTimeValue, type TimeUnit } from './util/time-interval.js';
7
+
8
+ export interface BinDateOptions {
9
+ /**
10
+ * A string indicating a time interval unit,
11
+ * such as 'year', 'day', or 'hour'.
12
+ */
13
+ interval?: TimeUnit;
14
+ /**
15
+ * The number of time interval steps to take, such as 2 years or 3 months.
16
+ */
17
+ step?: number;
18
+ /**
19
+ * The number of bin steps (default 0) by which to offset the result.
20
+ */
21
+ offset?: number;
22
+ /**
23
+ * The desired number of binning steps. This value is a hint,
24
+ * it does not guarantee an exact number of steps.
25
+ */
26
+ steps?: number;
27
+ }
28
+
29
+ /**
30
+ * Return a SQL expression for date/time bins.
31
+ * @param field The column or expression to bin.
32
+ * @param extent The min/max extent over which to bin.
33
+ * @param options Datetime binning options.
34
+ */
35
+ export function binDate(
36
+ field: ExprValue,
37
+ extent: [DateTimeValue, DateTimeValue],
38
+ options: BinDateOptions = {}
39
+ ): ExprNode {
40
+ const { offset = 0 } = options;
41
+
42
+ // use interval if provided, otherwise determine from extent
43
+ const { unit, step = 1 } = options.interval
44
+ ? { unit: options.interval, step: options.step }
45
+ : timeInterval(extent[0], extent[1], options.steps || 40);
46
+ const bin = dateBin(field, unit, step);
47
+ return offset ? add(bin, interval(unit, offset * step)) : bin;
48
+ }
@@ -0,0 +1,61 @@
1
+ import type { ExprNode } from '../ast/node.js';
2
+ import type { ExprValue } from '../types.js';
3
+ import { float64 } from '../functions/cast.js';
4
+ import { floor } from '../functions/numeric.js';
5
+ import { add, div, mul, sub } from '../functions/operators.js';
6
+ import { binSpec } from './util/bin-step.js';
7
+ import { Scale, scaleTransform } from './scales.js';
8
+
9
+ export interface BinHistogramOptions {
10
+ /** An exact binning step to use. */
11
+ step?: number;
12
+ /**
13
+ * The desired number of binning steps. This value is a hint,
14
+ * it does not guarantee an exact number of steps.
15
+ */
16
+ steps?: number;
17
+ /**
18
+ * A minimum binning step value. No generated
19
+ * step can be less than this value.
20
+ */
21
+ minstep?: number;
22
+ /**
23
+ * A boolean flag (default true) indicating if bin extents should be
24
+ * snapped to "nice" numbers such as multiples of 5 or 10.
25
+ */
26
+ nice?: boolean;
27
+ /**
28
+ * The number of bin steps (default 0) by which to offset the result.
29
+ */
30
+ offset?: number;
31
+ }
32
+
33
+ /**
34
+ * Return a SQL expression for histogram bins.
35
+ * @param field The column or expression to bin.
36
+ * @param extent The min/max extent over which to bin.
37
+ * @param options Binning options.
38
+ * @param transform Scale transforms to apply to create
39
+ * (potentially non-linear) binning intervals.
40
+ * @returns The resulting SQL expression
41
+ */
42
+ export function binHistogram(
43
+ field: ExprValue,
44
+ extent: [number, number],
45
+ options: BinHistogramOptions = {},
46
+ transform: Scale<number> = scaleTransform({ type: 'linear' })!
47
+ ): ExprNode {
48
+ const [min, max] = extent;
49
+ const { offset = 0 } = options;
50
+ const { apply, sqlApply, sqlInvert } = transform;
51
+ const b = binSpec(apply(min), apply(max), options);
52
+ const col = sqlApply(field);
53
+ const alpha = (b.max - b.min) / b.steps;
54
+
55
+ let expr = b.min === 0 ? col : sub(col, b.min);
56
+ if (alpha !== 1) expr = div(expr, float64(alpha));
57
+ expr = floor(offset ? add(offset, expr) : expr);
58
+ if (alpha !== 1) expr = mul(alpha, expr);
59
+ if (b.min !== 0) expr = add(b.min, expr);
60
+ return sqlInvert(expr);
61
+ }
@@ -1,7 +1,6 @@
1
- /**
2
- * @import { SelectQuery } from '../ast/query.js'
3
- * @import { ExprValue } from '../types.js'
4
- */
1
+ import type { ExprNode } from '../ast/node.js';
2
+ import type { SelectQuery } from '../ast/query.js';
3
+ import type { ExprValue } from '../types.js';
5
4
  import { Query } from '../ast/query.js';
6
5
  import { sum } from '../functions/aggregate.js';
7
6
  import { int32 } from '../functions/cast.js';
@@ -10,14 +9,20 @@ import { add, mul, neq, sub } from '../functions/operators.js';
10
9
 
11
10
  /**
12
11
  * Perform linear binning in one dimension.
13
- * @param {SelectQuery} query The base query to bin.
14
- * @param {ExprValue} x The expression to bin.
15
- * @param {ExprValue} [weight] The expression to weight by.
16
- * @param {string[]} [groupby] Group by expressions.
17
- * @returns {Query}
12
+ * @param query The base query to bin.
13
+ * @param x The expression to bin.
14
+ * @param weight The expression to weight by.
15
+ * @param groupby Group by expressions.
18
16
  */
19
- export function binLinear1d(query, x, weight = undefined, groupby = []) {
20
- const w = weight ? (x => mul(x, weight)) : (x => x);
17
+ export function binLinear1d(
18
+ query: SelectQuery,
19
+ x: ExprValue,
20
+ weight: ExprValue | undefined = undefined,
21
+ groupby: string[] = []
22
+ ) {
23
+ const w = weight
24
+ ? ((x: ExprNode) => mul(x, weight))
25
+ : ((x: ExprNode) => x);
21
26
  const p0 = floor(x);
22
27
  const p1 = add(p0, 1);
23
28
  return Query
@@ -1,22 +1,12 @@
1
- /**
2
- * @import { SelectQuery } from '../ast/query.js'
3
- * @import { ExprValue } from '../types.js'
4
- */
1
+ import type { ExprNode } from '../ast/node.js';
2
+ import type { SelectQuery } from '../ast/query.js';
3
+ import type { ExprValue } from '../types.js';
5
4
  import { Query } from '../ast/query.js';
6
5
  import { sum } from '../functions/aggregate.js';
7
6
  import { int32 } from '../functions/cast.js';
8
7
  import { floor } from '../functions/numeric.js';
9
8
  import { add, mul, neq, sub } from '../functions/operators.js';
10
-
11
- /**
12
- * Identity function.
13
- * @template T
14
- * @param {T} x
15
- * @returns {T}
16
- */
17
- function identity(x) {
18
- return x;
19
- }
9
+ import { identity } from '../util/identity.js';
20
10
 
21
11
  /**
22
12
  * Compute densities over a 2D domain using linear binning. The weight of
@@ -24,30 +14,28 @@ function identity(x) {
24
14
  * a better base for subsequent kernel density estimation. This method takes
25
15
  * expressions for the (non-truncated) x and y bin values; these expressions
26
16
  * should be in units of grid indices, but can contain fractional components.
27
- * @param {SelectQuery} q The input query. The FROM and WHERE clauses should
17
+ * @param q The input query. The FROM and WHERE clauses should
28
18
  * be added to the query separately, before this method is invoked.
29
- * @param {ExprValue} xp The x grid bin expression
30
- * @param {ExprValue} yp The y grid bin expression
31
- * @param {ExprValue | undefined} weight Point weights.
32
- * @param {number} xn The number of x grid bins.
33
- * @param {string[]} [groupby] Group by expressions.
34
- * @returns {SelectQuery} A linear binning query for bin `index` and
35
- * aggregate `density` columns, in addition to any group by expressions.
19
+ * @param xp The x grid bin expression
20
+ * @param yp The y grid bin expression
21
+ * @param weight Point weights.
22
+ * @param xn The number of x grid bins.
23
+ * @param groupby Group by expressions.
24
+ * @returns A linear binning query for bin `index` and aggregate `density`
25
+ * columns, in addition to any group by expressions.
36
26
  */
37
- export function binLinear2d(q, xp, yp, weight, xn, groupby = []) {
38
-
39
- const w = weight ? x => mul(x, weight) : identity;
27
+ export function binLinear2d(
28
+ q: SelectQuery,
29
+ xp: ExprValue,
30
+ yp: ExprValue,
31
+ weight: ExprValue | undefined,
32
+ xn: number,
33
+ groupby: string[] = []
34
+ ) {
35
+ const w = weight ? (x: ExprNode) => mul(x, weight) : identity;
40
36
 
41
- /**
42
- * @param {ExprValue} i
43
- * @param {ExprValue} w
44
- */
45
- const subq = (i, w) => q.clone().select({ xp, yp, i, w });
46
- /**
47
- * @param {ExprValue} x
48
- * @param {ExprValue} y
49
- */
50
- const index = (x, y) => add(x, mul(y, xn));
37
+ const subq = (i: ExprValue, w: ExprValue) => q.clone().select({ xp, yp, i, w });
38
+ const index = (x: ExprValue, y: ExprValue) => add(x, mul(y, xn));
51
39
 
52
40
  const xu = int32(floor(xp));
53
41
  const yu = int32(floor(yp));
@@ -1,22 +1,18 @@
1
- /**
2
- * @import { Query } from '../ast/query.js'
3
- * @import { TableRefNode } from '../ast/table-ref.js'
4
- * @import { FilterExpr } from '../types.js'
5
- */
6
- import { isSelectQuery } from '../ast/query.js';
7
- import { isTableRef } from '../ast/table-ref.js';
1
+ import type { FilterExpr } from '../types.js';
2
+ import { isSelectQuery, type Query } from '../ast/query.js';
3
+ import { isTableRef, type TableRefNode } from '../ast/table-ref.js';
8
4
  import { deepClone } from '../visit/clone.js';
9
5
  import { walk } from '../visit/walk.js';
10
6
 
11
7
  /**
12
8
  * Returns a generator function that clones the given query and adds
13
9
  * a WHERE clause for the specified table reference.
14
- * @param {Query} query The query to clone and extend.
15
- * @param {TableRefNode} tableRef The table to filter.
16
- * @returns {(filter: FilterExpr) => Query} The generator function.
10
+ * @param query The query to clone and extend.
11
+ * @param tableRef The table to filter.
12
+ * @returns The generator function.
17
13
  */
18
- export function filterQuery(query, tableRef) {
19
- return (filter) => {
14
+ export function filterQuery(query: Query, tableRef: TableRefNode) {
15
+ return (filter: FilterExpr) => {
20
16
  const clone = deepClone(query);
21
17
  walk(clone, (node) => {
22
18
  if (
@@ -32,12 +28,12 @@ export function filterQuery(query, tableRef) {
32
28
  };
33
29
  }
34
30
 
35
- function arrayEquals(a, b) {
31
+ function arrayEquals(a: unknown[], b: unknown[]) {
36
32
  if (a === b) return true;
37
33
  if (a == null || b == null) return false;
38
34
  if (a.length !== b.length) return false;
39
35
 
40
- for (var i = 0; i < a.length; ++i) {
36
+ for (let i = 0; i < a.length; ++i) {
41
37
  if (a[i] !== b[i]) return false;
42
38
  }
43
39
  return true;
@@ -1,8 +1,5 @@
1
- /**
2
- * @import { SelectQuery } from '../ast/query.js'
3
- * @import { ExprValue } from '../types.js'
4
- */
5
- import { Query } from '../ast/query.js';
1
+ import type { ExprValue } from '../types.js';
2
+ import { Query, type SelectQuery } from '../ast/query.js';
6
3
  import { count, max, sum } from '../functions/aggregate.js';
7
4
  import { int32 } from '../functions/cast.js';
8
5
  import { abs, floor, greatest, round, sign } from '../functions/numeric.js';
@@ -18,24 +15,29 @@ import { over } from '../util/ast.js';
18
15
  * pairs, perform line rasterization in-database, normalize arc lengths,
19
16
  * and then sum results for all line series to produce a density map.
20
17
  * Based on Moritz and Fisher's work: https://arxiv.org/abs/1808.06019
21
- * @param {SelectQuery} q The base query over the data.
22
- * @param {ExprValue} x Bin expression for x dimension.
18
+ * @param q The base query over the data.
19
+ * @param x Bin expression for x dimension.
23
20
  * Provides gridded x coordinates, potentially with a fractional component.
24
- * @param {ExprValue} y Bin expression for x dimension.
21
+ * @param y Bin expression for x dimension.
25
22
  * Provides gridded y coordinates, potentially with a fractional component.
26
- * @param {string[]} z Group by columns that segment data into individual line
23
+ * @param z Group by columns that segment data into individual line
27
24
  * series. An empty array indicates there is only a single line series.
28
- * @param {number} xn The number of grid bins for the x dimension.
29
- * @param {number} yn The number of grid bins for the y dimension.
30
- * @param {string[]} [groupby] Additional group by expressions. Separate
25
+ * @param xn The number of grid bins for the x dimension.
26
+ * @param yn The number of grid bins for the y dimension.
27
+ * @param groupby Additional group by expressions. Separate
31
28
  * line density maps are created for each of these groups.
32
- * @param {boolean} [normalize=true] Flag toggling approximate arc-length
33
- * normalization to improve accuracy and reduce artifacts (default `true`).
34
- * @returns {SelectQuery}
29
+ * @param normalize Flag toggling approximate arc-length normalization to
30
+ * improve accuracy and reduce artifacts (default `true`).
35
31
  */
36
32
  export function lineDensity(
37
- q, x, y, z, xn, yn,
38
- groupby = [], normalize = true
33
+ q: SelectQuery,
34
+ x: ExprValue,
35
+ y: ExprValue,
36
+ z: string[],
37
+ xn: number,
38
+ yn: number,
39
+ groupby: string[] = [],
40
+ normalize: boolean = true
39
41
  ) {
40
42
  // select x, y points binned to the grid
41
43
  q.select({
@@ -1,7 +1,5 @@
1
- /**
2
- * @import { ExprNode } from '../ast/node.js'
3
- * @import { ExprValue, FromExpr } from '../types.js'
4
- */
1
+ import type { ExprValue, FromExpr, SelectExpr } from '../types.js';
2
+ import type { ColumnRefNode } from '../ast/column-ref.js';
5
3
  import { Query, isQuery } from '../ast/query.js';
6
4
  import { argmax, argmin, max, min } from '../functions/aggregate.js';
7
5
  import { int32 } from '../functions/cast.js';
@@ -15,16 +13,21 @@ import { floor } from '../functions/numeric.js';
15
13
  * argmin and argmax, following https://arxiv.org/pdf/2306.03714.pdf.
16
14
  * This method can bin along either the *x* or *y* dimension, as determined
17
15
  * by the caller-provided *bin* expression.
18
- * @param {FromExpr} input The base query or table.
19
- * @param {ExprValue} bin An expression that maps
16
+ * @param input The base query or table.
17
+ * @param bin An expression that maps
20
18
  * time-series values to fractional pixel positions.
21
- * @param {string} x The x dimension column name.
22
- * @param {string} y The y dimension column name.
23
- * @param {ExprNode[]} [groups] Additional
24
- * groupby columns, for example for faceted charts.
25
- * @returns {Query} The resulting M4 query.
19
+ * @param x The x dimension column name.
20
+ * @param y The y dimension column name.
21
+ * @param groups Additional groupby columns, for example for faceted charts.
22
+ * @returns The resulting M4 query.
26
23
  */
27
- export function m4(input, bin, x, y, groups = []) {
24
+ export function m4(
25
+ input: FromExpr,
26
+ bin: ExprValue,
27
+ x: string,
28
+ y: string,
29
+ groups: ColumnRefNode[] = []
30
+ ) {
28
31
  const pixel = int32(floor(bin));
29
32
 
30
33
  // Below, we treat input as a CTE when it is a query. In this case,
@@ -32,10 +35,10 @@ export function m4(input, bin, x, y, groups = []) {
32
35
  const useCTE = isQuery(input);
33
36
  const from = useCTE ? 'input' : input;
34
37
  const query = useCTE
35
- ? Query.with(cte(/** @type {string} */(from), input, true))
38
+ ? Query.with(cte(String(from), input, true))
36
39
  : Query;
37
40
 
38
- const q = (sel) => Query
41
+ const q = (sel: SelectExpr) => Query
39
42
  .from(from)
40
43
  .select(sel)
41
44
  .groupby(pixel, groups);
@@ -1,13 +1,55 @@
1
+ import type { ExprValue } from '../types.js';
1
2
  import { LiteralNode } from '../ast/literal.js';
3
+ import { ExprNode } from '../ast/node.js';
2
4
  import { epoch_ms } from '../functions/datetime.js';
3
5
  import { literal } from '../functions/literal.js';
4
6
  import { abs, exp, ln, log, sign, sqrt } from '../functions/numeric.js';
5
7
  import { add, div, mul, pow, sub } from '../functions/operators.js';
6
8
  import { asNode } from '../util/ast.js';
9
+ import { identity } from '../util/identity.js';
10
+ import { DateTimeValue } from './util/time-interval.js';
7
11
 
8
- const identity = x => x;
12
+ export interface ScaleTransform<T> {
13
+ apply: (value: T) => number;
14
+ invert: (value: number) => T;
15
+ sqlApply: (value: ExprValue) => ExprNode;
16
+ sqlInvert: (value: ExprNode) => ExprNode;
17
+ }
18
+
19
+ export type ScaleType =
20
+ | 'identity'
21
+ | 'linear'
22
+ | 'log'
23
+ | 'symlog'
24
+ | 'sqrt'
25
+ | 'pow'
26
+ | 'time'
27
+ | 'utc'
28
+ ;
29
+
30
+ export type ScaleDomain = [number, number] | [Date, Date];
31
+
32
+ export interface ScaleOptions {
33
+ /** The scale type, such as `'linear'`, `'log'`, etc. */
34
+ type: ScaleType;
35
+ /** The scale domain, as an array of start and end data values. */
36
+ domain?: ScaleDomain;
37
+ /**
38
+ * The scale range, as an array of start and end screen pixels.
39
+ * The range may be omitted for *identity* scales.
40
+ */
41
+ range?: [number, number];
42
+ /** The base of the logarithm. For `'log'` scales only. */
43
+ base?: number;
44
+ /** The constant parameter. For `'symlog'` scales only. */
45
+ constant?: number;
46
+ /** The exponent parameter. For `'pow'` scales only. */
47
+ exponent?: number;
48
+ }
49
+
50
+ export type Scale<T> = ScaleTransform<T> & ScaleOptions;
9
51
 
10
- function scaleLinear() {
52
+ function scaleLinear(): ScaleTransform<number> {
11
53
  return {
12
54
  apply: identity,
13
55
  invert: identity,
@@ -16,7 +58,7 @@ function scaleLinear() {
16
58
  };
17
59
  }
18
60
 
19
- function scaleLog({ base = null } = {}) {
61
+ function scaleLog({ base = null }: {base?: number | null} = { }): ScaleTransform<number> {
20
62
  if (base == null || base === Math.E) {
21
63
  return {
22
64
  apply: Math.log,
@@ -42,7 +84,7 @@ function scaleLog({ base = null } = {}) {
42
84
  }
43
85
  }
44
86
 
45
- function scaleSymlog({ constant = 1 } = {}) {
87
+ function scaleSymlog({ constant = 1 } = {}): ScaleTransform<number> {
46
88
  const _ = +constant;
47
89
  return {
48
90
  apply: x => Math.sign(x) * Math.log1p(Math.abs(x)),
@@ -52,7 +94,7 @@ function scaleSymlog({ constant = 1 } = {}) {
52
94
  };
53
95
  }
54
96
 
55
- function scaleSqrt() {
97
+ function scaleSqrt(): ScaleTransform<number> {
56
98
  return {
57
99
  apply: x => Math.sign(x) * Math.sqrt(Math.abs(x)),
58
100
  invert: x => Math.sign(x) * x * x,
@@ -61,7 +103,7 @@ function scaleSqrt() {
61
103
  };
62
104
  }
63
105
 
64
- function scalePow({ exponent = 1 } = {}) {
106
+ function scalePow({ exponent = 1 } = {}): ScaleTransform<number> {
65
107
  const e = +exponent;
66
108
  return {
67
109
  apply: x => Math.sign(x) * Math.pow(Math.abs(x), e),
@@ -71,12 +113,12 @@ function scalePow({ exponent = 1 } = {}) {
71
113
  };
72
114
  }
73
115
 
74
- function scaleTime() {
116
+ function scaleTime(): ScaleTransform<DateTimeValue> {
75
117
  return {
76
- apply: x => +x,
118
+ apply: x => Number(x),
77
119
  invert: x => new Date(x),
78
120
  sqlApply: c => c instanceof Date ? literal(+c)
79
- : isDateLiteral(c) ? literal(+c.value)
121
+ : isDateLiteral(c) ? literal(Number(c.value))
80
122
  : epoch_ms(c),
81
123
  sqlInvert: identity
82
124
  };
@@ -93,16 +135,17 @@ const scales = {
93
135
  utc: scaleTime
94
136
  };
95
137
 
96
- export function scaleTransform(options) {
138
+ export function scaleTransform<T>(options: ScaleOptions): Scale<T> {
97
139
  const scale = scales[options.type];
98
- return scale ? { ...options, ...scale(options) } : null;
140
+ if (!scale) throw new Error(`Unrecognized scale type: ${options.type}`);
141
+ // @ts-expect-error suppress error, revisit later?
142
+ return { ...options, ...scale(options) };
99
143
  }
100
144
 
101
145
  /**
102
146
  * Check if a value is a date-valued literal SQL AST node.
103
- * @param {*} x The value to test.
104
- * @returns {x is LiteralNode}
147
+ * @param x The value to test.
105
148
  */
106
- function isDateLiteral(x) {
149
+ function isDateLiteral(x: unknown): x is LiteralNode {
107
150
  return x instanceof LiteralNode && x.value instanceof Date;
108
151
  }
@@ -0,0 +1,100 @@
1
+ /** Numerical binning options. */
2
+ export interface BinOptions {
3
+ /**
4
+ * An exact binning step to use.
5
+ */
6
+ step?: number;
7
+ /**
8
+ * The desired number of binning steps. This value is a hint,
9
+ * it does not guarantee an exact number of steps.
10
+ */
11
+ steps?: number;
12
+ /**
13
+ * A minimum binning step value.
14
+ * No generated step can be less than this value.
15
+ */
16
+ minstep?: number;
17
+ /**
18
+ * A boolean flag (default true) indicating if bin extents should be snapped
19
+ * to "nice" numbers such as multiples of 5 or 10.
20
+ */
21
+ nice?: boolean;
22
+ /**
23
+ * A number indicating the the logarithm base to use for automatic step size
24
+ * determination. Defaults to base 10.
25
+ */
26
+ base?: number;
27
+ }
28
+
29
+ /**
30
+ * Generate a numeric binning scheme suitable for a histogram.
31
+ * @param min The minimum value of the extent to bin.
32
+ * @param max The maximum value of the extent to bin.
33
+ * @param options Binning scheme options.
34
+ */
35
+ export function binSpec(min: number, max: number, options: BinOptions) {
36
+ let {
37
+ step,
38
+ steps = 25,
39
+ } = options;
40
+ const {
41
+ minstep = 0,
42
+ nice = true,
43
+ base
44
+ } = options;
45
+
46
+ if (nice !== false) {
47
+ // use span to determine step size
48
+ const span = max - min;
49
+ const logb = base ? Math.log(base) : Math.LN10;
50
+ step = step || binStep(span, steps, minstep, logb);
51
+
52
+ // adjust min/max relative to step
53
+ let v = Math.log(step);
54
+ const precision = v >= 0 ? 0 : ~~(-v / logb) + 1;
55
+ const eps = Math.pow(10, -precision - 1);
56
+ v = Math.floor(min / step + eps) * step;
57
+ min = min < v ? v - step : v;
58
+ max = Math.ceil(max / step) * step;
59
+ steps = Math.round((max - min) / step);
60
+ }
61
+
62
+ return { min, max, steps };
63
+ }
64
+
65
+ /**
66
+ * Determine a bin step interval.
67
+ * @param span The span from maximum to minimum value.
68
+ * @param steps The approximate number of desired bins.
69
+ * @param minstep The minimum acceptable bin step size.
70
+ * @param logb The log base for determining orders of magnitude for step
71
+ * sizes. Defaults to log base 10 (`Math.LN10`). For example to use log
72
+ * base 2, provide the argument `Math.LN2` instead.
73
+ * @returns The bin step interval (bin size).
74
+ */
75
+ export function binStep(
76
+ span: number,
77
+ steps: number,
78
+ minstep: number = 0,
79
+ logb: number = Math.LN10
80
+ ) {
81
+ let v;
82
+
83
+ const level = Math.ceil(Math.log(steps) / logb);
84
+ let step = Math.max(
85
+ minstep,
86
+ Math.pow(10, Math.round(Math.log(span) / logb) - level)
87
+ );
88
+
89
+ // increase step size if too many bins
90
+ while (Math.ceil(span / step) > steps) { step *= 10; }
91
+
92
+ // decrease step size if allowed
93
+ const div = [5, 2];
94
+ for (let i = 0, n = div.length; i < n; ++i) {
95
+ v = step / div[i];
96
+ if (v >= minstep && span / v <= steps) step = v;
97
+ }
98
+
99
+ return step;
100
+ }