@genome-spy/core 0.36.0 → 0.37.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 (523) hide show
  1. package/README.md +1 -0
  2. package/dist/{index.es.js → bundled/index.es.js} +4227 -4085
  3. package/dist/{index.js → bundled/index.js} +191 -55
  4. package/dist/src/data/collector.d.ts +36 -0
  5. package/dist/src/data/collector.d.ts.map +1 -0
  6. package/dist/src/data/collector.js +184 -0
  7. package/dist/src/data/collector.test.js +84 -0
  8. package/dist/src/data/dataFlow.d.ts +65 -0
  9. package/dist/src/data/dataFlow.d.ts.map +1 -0
  10. package/dist/src/data/dataFlow.js +142 -0
  11. package/dist/src/data/dataFlow.test.js +5 -0
  12. package/dist/src/data/facetNode.d.ts +17 -0
  13. package/dist/src/data/facetNode.d.ts.map +1 -0
  14. package/dist/src/data/facetNode.js +17 -0
  15. package/dist/src/data/flow.test.js +72 -0
  16. package/dist/src/data/flowNode.d.ts +136 -0
  17. package/dist/src/data/flowNode.d.ts.map +1 -0
  18. package/dist/src/data/flowNode.js +286 -0
  19. package/dist/src/data/flowNode.test.js +50 -0
  20. package/dist/src/data/flowOptimizer.d.ts +27 -0
  21. package/dist/src/data/flowOptimizer.d.ts.map +1 -0
  22. package/dist/src/data/flowOptimizer.js +133 -0
  23. package/dist/src/data/flowOptimizer.test.js +193 -0
  24. package/dist/src/data/flowTestUtils.d.ts +30 -0
  25. package/dist/src/data/flowTestUtils.d.ts.map +1 -0
  26. package/dist/src/data/flowTestUtils.js +63 -0
  27. package/dist/src/data/formats/fasta.d.ts +20 -0
  28. package/dist/src/data/formats/fasta.d.ts.map +1 -0
  29. package/dist/src/data/formats/fasta.js +32 -0
  30. package/dist/src/data/formats/fasta.test.js +27 -0
  31. package/dist/src/data/sources/dataSource.d.ts +12 -0
  32. package/dist/src/data/sources/dataSource.d.ts.map +1 -0
  33. package/dist/src/data/sources/dataSource.js +25 -0
  34. package/dist/src/data/sources/dataSourceFactory.d.ts +16 -0
  35. package/dist/src/data/sources/dataSourceFactory.d.ts.map +1 -0
  36. package/dist/src/data/sources/dataSourceFactory.js +127 -0
  37. package/dist/src/data/sources/dataUtils.d.ts +50 -0
  38. package/dist/src/data/sources/dataUtils.d.ts.map +1 -0
  39. package/dist/src/data/sources/dataUtils.js +83 -0
  40. package/dist/src/data/sources/dynamic/README.md +3 -0
  41. package/dist/src/data/sources/dynamic/axisGenomeSource.d.ts +13 -0
  42. package/dist/src/data/sources/dynamic/axisGenomeSource.d.ts.map +1 -0
  43. package/dist/src/data/sources/dynamic/axisGenomeSource.js +19 -0
  44. package/dist/src/data/sources/dynamic/axisTickSource.d.ts +18 -0
  45. package/dist/src/data/sources/dynamic/axisTickSource.d.ts.map +1 -0
  46. package/dist/src/data/sources/dynamic/axisTickSource.js +73 -0
  47. package/dist/src/data/sources/dynamic/bamSource.d.ts +46 -0
  48. package/dist/src/data/sources/dynamic/bamSource.d.ts.map +1 -0
  49. package/dist/src/data/sources/dynamic/bamSource.js +115 -0
  50. package/dist/src/data/sources/dynamic/bigBedSource.d.ts +51 -0
  51. package/dist/src/data/sources/dynamic/bigBedSource.d.ts.map +1 -0
  52. package/dist/src/data/sources/dynamic/bigBedSource.js +128 -0
  53. package/dist/src/data/sources/dynamic/bigWigSource.d.ts +58 -0
  54. package/dist/src/data/sources/dynamic/bigWigSource.d.ts.map +1 -0
  55. package/dist/src/data/sources/dynamic/bigWigSource.js +166 -0
  56. package/dist/src/data/sources/dynamic/gff3Source.d.ts +8 -0
  57. package/dist/src/data/sources/dynamic/gff3Source.d.ts.map +1 -0
  58. package/dist/src/data/sources/dynamic/gff3Source.js +19 -0
  59. package/dist/src/data/sources/dynamic/indexedFastaSource.d.ts +30 -0
  60. package/dist/src/data/sources/dynamic/indexedFastaSource.d.ts.map +1 -0
  61. package/dist/src/data/sources/dynamic/indexedFastaSource.js +86 -0
  62. package/dist/src/data/sources/dynamic/singleAxisLazySource.d.ts +42 -0
  63. package/dist/src/data/sources/dynamic/singleAxisLazySource.d.ts.map +1 -0
  64. package/dist/src/data/sources/dynamic/singleAxisLazySource.js +129 -0
  65. package/dist/src/data/sources/dynamic/tabixSource.d.ts +54 -0
  66. package/dist/src/data/sources/dynamic/tabixSource.d.ts.map +1 -0
  67. package/dist/src/data/sources/dynamic/tabixSource.js +140 -0
  68. package/dist/src/data/sources/dynamic/windowedMixin.d.ts +32 -0
  69. package/dist/src/data/sources/dynamic/windowedMixin.d.ts.map +1 -0
  70. package/dist/src/data/sources/dynamic/windowedMixin.js +53 -0
  71. package/dist/src/data/sources/inlineSource.d.ts +16 -0
  72. package/dist/src/data/sources/inlineSource.d.ts.map +1 -0
  73. package/dist/src/data/sources/inlineSource.js +68 -0
  74. package/dist/src/data/sources/inlineSource.test.js +56 -0
  75. package/dist/src/data/sources/namedSource.d.ts +25 -0
  76. package/dist/src/data/sources/namedSource.d.ts.map +1 -0
  77. package/dist/src/data/sources/namedSource.js +80 -0
  78. package/dist/src/data/sources/sequenceSource.d.ts +17 -0
  79. package/dist/src/data/sources/sequenceSource.d.ts.map +1 -0
  80. package/dist/src/data/sources/sequenceSource.js +47 -0
  81. package/dist/src/data/sources/sequenceSource.test.js +46 -0
  82. package/dist/src/data/sources/urlSource.d.ts +16 -0
  83. package/dist/src/data/sources/urlSource.d.ts.map +1 -0
  84. package/dist/src/data/sources/urlSource.js +74 -0
  85. package/dist/src/data/transforms/aggregate.d.ts +18 -0
  86. package/dist/src/data/transforms/aggregate.d.ts.map +1 -0
  87. package/dist/src/data/transforms/aggregate.js +67 -0
  88. package/dist/src/data/transforms/clone.d.ts +15 -0
  89. package/dist/src/data/transforms/clone.d.ts.map +1 -0
  90. package/dist/src/data/transforms/clone.js +40 -0
  91. package/dist/src/data/transforms/clone.test.js +11 -0
  92. package/dist/src/data/transforms/coverage.d.ts +30 -0
  93. package/dist/src/data/transforms/coverage.d.ts.map +1 -0
  94. package/dist/src/data/transforms/coverage.js +183 -0
  95. package/dist/src/data/transforms/coverage.test.js +123 -0
  96. package/dist/src/data/transforms/filter.d.ts +12 -0
  97. package/dist/src/data/transforms/filter.d.ts.map +1 -0
  98. package/dist/src/data/transforms/filter.js +33 -0
  99. package/dist/src/data/transforms/filter.test.js +18 -0
  100. package/dist/src/data/transforms/filterScoredLabels.d.ts +29 -0
  101. package/dist/src/data/transforms/filterScoredLabels.d.ts.map +1 -0
  102. package/dist/src/data/transforms/filterScoredLabels.js +134 -0
  103. package/dist/src/data/transforms/flatten.d.ts +10 -0
  104. package/dist/src/data/transforms/flatten.d.ts.map +1 -0
  105. package/dist/src/data/transforms/flatten.js +68 -0
  106. package/dist/src/data/transforms/flatten.test.js +93 -0
  107. package/dist/src/data/transforms/flattenCompressedExons.d.ts +19 -0
  108. package/dist/src/data/transforms/flattenCompressedExons.d.ts.map +1 -0
  109. package/dist/src/data/transforms/flattenCompressedExons.js +53 -0
  110. package/dist/src/data/transforms/flattenDelimited.d.ts +10 -0
  111. package/dist/src/data/transforms/flattenDelimited.d.ts.map +1 -0
  112. package/dist/src/data/transforms/flattenDelimited.js +66 -0
  113. package/dist/src/data/transforms/flattenDelimited.test.js +87 -0
  114. package/dist/src/data/transforms/flattenSequence.d.ts +11 -0
  115. package/dist/src/data/transforms/flattenSequence.d.ts.map +1 -0
  116. package/dist/src/data/transforms/flattenSequence.js +35 -0
  117. package/dist/src/data/transforms/flattenSequence.test.js +34 -0
  118. package/dist/src/data/transforms/formula.d.ts +13 -0
  119. package/dist/src/data/transforms/formula.d.ts.map +1 -0
  120. package/dist/src/data/transforms/formula.js +35 -0
  121. package/dist/src/data/transforms/formula.test.js +19 -0
  122. package/dist/src/data/transforms/identifier.d.ts +40 -0
  123. package/dist/src/data/transforms/identifier.d.ts.map +1 -0
  124. package/dist/src/data/transforms/identifier.js +106 -0
  125. package/dist/src/data/transforms/identifier.test.js +83 -0
  126. package/dist/src/data/transforms/linearizeGenomicCoordinate.d.ts +10 -0
  127. package/dist/src/data/transforms/linearizeGenomicCoordinate.d.ts.map +1 -0
  128. package/dist/src/data/transforms/linearizeGenomicCoordinate.js +97 -0
  129. package/dist/src/data/transforms/measureText.d.ts +18 -0
  130. package/dist/src/data/transforms/measureText.d.ts.map +1 -0
  131. package/dist/src/data/transforms/measureText.js +42 -0
  132. package/dist/src/data/transforms/pileup.d.ts +10 -0
  133. package/dist/src/data/transforms/pileup.d.ts.map +1 -0
  134. package/dist/src/data/transforms/pileup.js +126 -0
  135. package/dist/src/data/transforms/pileup.test.js +70 -0
  136. package/dist/src/data/transforms/project.d.ts +13 -0
  137. package/dist/src/data/transforms/project.d.ts.map +1 -0
  138. package/dist/src/data/transforms/project.js +38 -0
  139. package/dist/src/data/transforms/project.test.js +32 -0
  140. package/dist/src/data/transforms/regexExtract.d.ts +13 -0
  141. package/dist/src/data/transforms/regexExtract.d.ts.map +1 -0
  142. package/dist/src/data/transforms/regexExtract.js +57 -0
  143. package/dist/src/data/transforms/regexExtract.test.js +67 -0
  144. package/dist/src/data/transforms/regexFold.d.ts +14 -0
  145. package/dist/src/data/transforms/regexFold.d.ts.map +1 -0
  146. package/dist/src/data/transforms/regexFold.js +139 -0
  147. package/dist/src/data/transforms/regexFold.test.js +160 -0
  148. package/dist/src/data/transforms/sample.d.ts +42 -0
  149. package/dist/src/data/transforms/sample.d.ts.map +1 -0
  150. package/dist/src/data/transforms/sample.js +99 -0
  151. package/dist/src/data/transforms/sample.test.js +38 -0
  152. package/dist/src/data/transforms/stack.d.ts +11 -0
  153. package/dist/src/data/transforms/stack.d.ts.map +1 -0
  154. package/dist/src/data/transforms/stack.js +134 -0
  155. package/dist/src/data/transforms/stack.test.js +91 -0
  156. package/dist/src/data/transforms/transformFactory.d.ts +12 -0
  157. package/dist/src/data/transforms/transformFactory.d.ts.map +1 -0
  158. package/dist/src/data/transforms/transformFactory.js +59 -0
  159. package/dist/src/encoder/accessor.d.ts +15 -0
  160. package/dist/src/encoder/accessor.d.ts.map +1 -0
  161. package/dist/src/encoder/accessor.js +76 -0
  162. package/dist/src/encoder/accessor.test.js +47 -0
  163. package/dist/src/encoder/encoder.d.ts +144 -0
  164. package/dist/src/encoder/encoder.d.ts.map +1 -0
  165. package/dist/src/encoder/encoder.js +400 -0
  166. package/dist/src/encoder/encoder.test.js +98 -0
  167. package/dist/src/fonts/Lato-Regular.json +1267 -0
  168. package/dist/src/fonts/Lato-Regular.png +0 -0
  169. package/dist/src/fonts/OFL.txt +93 -0
  170. package/dist/src/fonts/README.md +3 -0
  171. package/dist/src/fonts/bmFontManager.d.ts +182 -0
  172. package/dist/src/fonts/bmFontManager.d.ts.map +1 -0
  173. package/dist/src/fonts/bmFontManager.js +359 -0
  174. package/dist/src/fonts/bmFontMetrics.d.ts +45 -0
  175. package/dist/src/fonts/bmFontMetrics.d.ts.map +1 -0
  176. package/dist/src/fonts/bmFontMetrics.js +108 -0
  177. package/dist/src/genome/genome.d.ts +172 -0
  178. package/dist/src/genome/genome.d.ts.map +1 -0
  179. package/dist/src/genome/genome.js +379 -0
  180. package/dist/src/genome/genome.test.js +226 -0
  181. package/dist/src/genome/genomeStore.d.ts +20 -0
  182. package/dist/src/genome/genomeStore.d.ts.map +1 -0
  183. package/dist/src/genome/genomeStore.js +54 -0
  184. package/dist/src/genome/locusFormat.d.ts +14 -0
  185. package/dist/src/genome/locusFormat.d.ts.map +1 -0
  186. package/dist/src/genome/locusFormat.js +37 -0
  187. package/dist/src/genome/scaleIndex.d.ts +6 -0
  188. package/dist/src/genome/scaleIndex.d.ts.map +1 -0
  189. package/dist/src/genome/scaleIndex.js +165 -0
  190. package/dist/src/genome/scaleIndex.test.js +78 -0
  191. package/dist/src/genome/scaleLocus.d.ts +3 -0
  192. package/dist/src/genome/scaleLocus.d.ts.map +1 -0
  193. package/dist/src/genome/scaleLocus.js +101 -0
  194. package/dist/src/genome/scaleLocus.test.js +4 -0
  195. package/dist/src/genomeSpy.d.ts +141 -0
  196. package/dist/src/genomeSpy.d.ts.map +1 -0
  197. package/dist/src/genomeSpy.js +788 -0
  198. package/dist/src/gl/arrayBuilder.d.ts +71 -0
  199. package/dist/src/gl/arrayBuilder.d.ts.map +1 -0
  200. package/dist/src/gl/arrayBuilder.js +199 -0
  201. package/dist/src/gl/dataToVertices.d.ts +194 -0
  202. package/dist/src/gl/dataToVertices.d.ts.map +1 -0
  203. package/dist/src/gl/dataToVertices.js +639 -0
  204. package/dist/src/gl/includes/common.glsl.js +2 -0
  205. package/dist/src/gl/includes/picking.fragment.glsl.js +2 -0
  206. package/dist/src/gl/includes/picking.vertex.glsl.js +2 -0
  207. package/dist/src/gl/includes/sampleFacet.glsl.js +2 -0
  208. package/dist/src/gl/includes/scales.glsl.js +2 -0
  209. package/dist/src/gl/link.fragment.glsl.js +2 -0
  210. package/dist/src/gl/link.vertex.glsl.js +2 -0
  211. package/dist/src/gl/point.fragment.glsl.js +2 -0
  212. package/dist/src/gl/point.vertex.glsl.js +2 -0
  213. package/dist/src/gl/rect.fragment.glsl.js +2 -0
  214. package/dist/src/gl/rect.vertex.glsl.js +2 -0
  215. package/dist/src/gl/rule.fragment.glsl.js +2 -0
  216. package/dist/src/gl/rule.vertex.glsl.js +2 -0
  217. package/dist/src/gl/text.fragment.glsl.js +2 -0
  218. package/dist/src/gl/text.vertex.glsl.js +2 -0
  219. package/dist/src/gl/webGLHelper.d.ts +118 -0
  220. package/dist/src/gl/webGLHelper.d.ts.map +1 -0
  221. package/dist/src/gl/webGLHelper.js +513 -0
  222. package/dist/src/img/bowtie.svg +1 -0
  223. package/dist/src/img/genomespy-favicon.svg +34 -0
  224. package/dist/src/index.d.ts +15 -0
  225. package/dist/src/index.d.ts.map +1 -0
  226. package/dist/src/index.html +11 -0
  227. package/dist/src/index.js +129 -0
  228. package/dist/src/marks/link.d.ts +11 -0
  229. package/dist/src/marks/link.d.ts.map +1 -0
  230. package/dist/src/marks/link.js +175 -0
  231. package/dist/src/marks/mark.d.ts +226 -0
  232. package/dist/src/marks/mark.d.ts.map +1 -0
  233. package/dist/src/marks/mark.js +1004 -0
  234. package/dist/src/marks/markUtils.d.ts +23 -0
  235. package/dist/src/marks/markUtils.d.ts.map +1 -0
  236. package/dist/src/marks/markUtils.js +125 -0
  237. package/dist/src/marks/pointMark.d.ts +11 -0
  238. package/dist/src/marks/pointMark.d.ts.map +1 -0
  239. package/dist/src/marks/pointMark.js +251 -0
  240. package/dist/src/marks/rectMark.d.ts +18 -0
  241. package/dist/src/marks/rectMark.d.ts.map +1 -0
  242. package/dist/src/marks/rectMark.js +255 -0
  243. package/dist/src/marks/rule.d.ts +6 -0
  244. package/dist/src/marks/rule.d.ts.map +1 -0
  245. package/dist/src/marks/rule.js +250 -0
  246. package/dist/src/marks/text.d.ts +13 -0
  247. package/dist/src/marks/text.d.ts.map +1 -0
  248. package/dist/src/marks/text.js +279 -0
  249. package/dist/src/scale/colorUtils.d.ts +34 -0
  250. package/dist/src/scale/colorUtils.d.ts.map +1 -0
  251. package/dist/src/scale/colorUtils.js +184 -0
  252. package/dist/src/scale/glslScaleGenerator.d.ts +45 -0
  253. package/dist/src/scale/glslScaleGenerator.d.ts.map +1 -0
  254. package/dist/src/scale/glslScaleGenerator.js +506 -0
  255. package/dist/src/scale/scale.d.ts +10 -0
  256. package/dist/src/scale/scale.d.ts.map +1 -0
  257. package/dist/src/scale/scale.js +456 -0
  258. package/dist/src/scale/scale.test.js +324 -0
  259. package/dist/src/scale/ticks.d.ts +47 -0
  260. package/dist/src/scale/ticks.d.ts.map +1 -0
  261. package/dist/src/scale/ticks.js +203 -0
  262. package/dist/src/scale/ticks.test.js +40 -0
  263. package/dist/src/singlePageApp.d.ts +2 -0
  264. package/dist/src/singlePageApp.d.ts.map +1 -0
  265. package/dist/src/singlePageApp.js +13 -0
  266. package/dist/src/spec/axis.d.ts +402 -0
  267. package/dist/src/spec/channel.d.ts +440 -0
  268. package/dist/src/spec/data.d.ts +370 -0
  269. package/dist/src/spec/font.d.ts +15 -0
  270. package/dist/src/spec/genome.d.ts +35 -0
  271. package/dist/src/spec/mark.d.ts +435 -0
  272. package/dist/src/spec/root.d.ts +22 -0
  273. package/dist/src/spec/sampleView.d.ts +185 -0
  274. package/dist/src/spec/scale.d.ts +273 -0
  275. package/dist/src/spec/title.d.ts +102 -0
  276. package/dist/src/spec/tooltip.d.ts +9 -0
  277. package/dist/src/spec/transform.d.ts +504 -0
  278. package/dist/src/spec/view.d.ts +214 -0
  279. package/dist/src/styles/genome-spy.css.d.ts +3 -0
  280. package/dist/src/styles/genome-spy.css.d.ts.map +1 -0
  281. package/dist/src/styles/genome-spy.css.js +114 -0
  282. package/dist/src/styles/genome-spy.scss +153 -0
  283. package/dist/src/tooltip/dataTooltipHandler.d.ts +2 -0
  284. package/dist/src/tooltip/dataTooltipHandler.d.ts.map +1 -0
  285. package/dist/src/tooltip/dataTooltipHandler.js +64 -0
  286. package/dist/src/tooltip/refseqGeneTooltipHandler.d.ts +2 -0
  287. package/dist/src/tooltip/refseqGeneTooltipHandler.d.ts.map +1 -0
  288. package/dist/src/tooltip/refseqGeneTooltipHandler.js +78 -0
  289. package/dist/src/tooltip/tooltipHandler.d.ts +9 -0
  290. package/dist/src/tooltip/tooltipHandler.d.ts.map +1 -0
  291. package/dist/src/tooltip/tooltipHandler.ts +12 -0
  292. package/dist/src/types/bmFont.d.ts +58 -0
  293. package/dist/src/types/embedApi.d.ts +67 -0
  294. package/dist/src/types/encoder.d.ts +84 -0
  295. package/dist/src/types/flowBatch.d.ts +40 -0
  296. package/dist/src/types/rendering.d.ts +65 -0
  297. package/dist/src/types/scaleResolutionApi.d.ts +40 -0
  298. package/dist/src/types/viewContext.d.ts +85 -0
  299. package/dist/src/utils/addBaseUrl.d.ts +6 -0
  300. package/dist/src/utils/addBaseUrl.d.ts.map +1 -0
  301. package/dist/src/utils/addBaseUrl.js +19 -0
  302. package/dist/src/utils/addBaseUrl.test.js +22 -0
  303. package/dist/src/utils/animator.d.ts +41 -0
  304. package/dist/src/utils/animator.d.ts.map +1 -0
  305. package/dist/src/utils/animator.js +83 -0
  306. package/dist/src/utils/arrayUtils.d.ts +34 -0
  307. package/dist/src/utils/arrayUtils.d.ts.map +1 -0
  308. package/dist/src/utils/arrayUtils.js +61 -0
  309. package/dist/src/utils/binnedIndex.d.ts +23 -0
  310. package/dist/src/utils/binnedIndex.d.ts.map +1 -0
  311. package/dist/src/utils/binnedIndex.js +167 -0
  312. package/dist/src/utils/binnedIndex.test.js +155 -0
  313. package/dist/src/utils/clamp.d.ts +7 -0
  314. package/dist/src/utils/clamp.d.ts.map +1 -0
  315. package/dist/src/utils/clamp.js +8 -0
  316. package/dist/src/utils/cloner.d.ts +16 -0
  317. package/dist/src/utils/cloner.d.ts.map +1 -0
  318. package/dist/src/utils/cloner.js +34 -0
  319. package/dist/src/utils/cloner.test.js +24 -0
  320. package/dist/src/utils/coalesce.d.ts +6 -0
  321. package/dist/src/utils/coalesce.d.ts.map +1 -0
  322. package/dist/src/utils/coalesce.js +11 -0
  323. package/dist/src/utils/coalesce.test.js +16 -0
  324. package/dist/src/utils/concatIterables.d.ts +8 -0
  325. package/dist/src/utils/concatIterables.d.ts.map +1 -0
  326. package/dist/src/utils/concatIterables.js +26 -0
  327. package/dist/src/utils/concatIterables.test.js +8 -0
  328. package/dist/src/utils/debounce.d.ts +8 -0
  329. package/dist/src/utils/debounce.d.ts.map +1 -0
  330. package/dist/src/utils/debounce.js +37 -0
  331. package/dist/src/utils/domainArray.d.ts +61 -0
  332. package/dist/src/utils/domainArray.d.ts.map +1 -0
  333. package/dist/src/utils/domainArray.js +216 -0
  334. package/dist/src/utils/domainArray.test.js +130 -0
  335. package/dist/src/utils/eerp.d.ts +12 -0
  336. package/dist/src/utils/eerp.d.ts.map +1 -0
  337. package/dist/src/utils/eerp.js +13 -0
  338. package/dist/src/utils/expression.d.ts +9 -0
  339. package/dist/src/utils/expression.d.ts.map +1 -0
  340. package/dist/src/utils/expression.js +32 -0
  341. package/dist/src/utils/field.d.ts +17 -0
  342. package/dist/src/utils/field.d.ts.map +1 -0
  343. package/dist/src/utils/field.js +28 -0
  344. package/dist/src/utils/formatObject.d.ts +7 -0
  345. package/dist/src/utils/formatObject.d.ts.map +1 -0
  346. package/dist/src/utils/formatObject.js +37 -0
  347. package/dist/src/utils/indexer.d.ts +16 -0
  348. package/dist/src/utils/indexer.d.ts.map +1 -0
  349. package/dist/src/utils/indexer.js +43 -0
  350. package/dist/src/utils/indexer.test.js +47 -0
  351. package/dist/src/utils/inertia.d.ts +42 -0
  352. package/dist/src/utils/inertia.d.ts.map +1 -0
  353. package/dist/src/utils/inertia.js +124 -0
  354. package/dist/src/utils/interactionEvent.d.ts +26 -0
  355. package/dist/src/utils/interactionEvent.d.ts.map +1 -0
  356. package/dist/src/utils/interactionEvent.js +33 -0
  357. package/dist/src/utils/iterateNestedMaps.d.ts +11 -0
  358. package/dist/src/utils/iterateNestedMaps.d.ts.map +1 -0
  359. package/dist/src/utils/iterateNestedMaps.js +21 -0
  360. package/dist/src/utils/iterateNestedMaps.test.js +33 -0
  361. package/dist/src/utils/kWayMerge.d.ts +9 -0
  362. package/dist/src/utils/kWayMerge.d.ts.map +1 -0
  363. package/dist/src/utils/kWayMerge.js +42 -0
  364. package/dist/src/utils/kWayMerge.test.js +26 -0
  365. package/dist/src/utils/layout/flexLayout.d.ts +182 -0
  366. package/dist/src/utils/layout/flexLayout.d.ts.map +1 -0
  367. package/dist/src/utils/layout/flexLayout.js +381 -0
  368. package/dist/src/utils/layout/flexLayout.test.js +323 -0
  369. package/dist/src/utils/layout/grid.d.ts +29 -0
  370. package/dist/src/utils/layout/grid.d.ts.map +1 -0
  371. package/dist/src/utils/layout/grid.js +95 -0
  372. package/dist/src/utils/layout/grid.test.js +71 -0
  373. package/dist/src/utils/layout/padding.d.ts +83 -0
  374. package/dist/src/utils/layout/padding.d.ts.map +1 -0
  375. package/dist/src/utils/layout/padding.js +155 -0
  376. package/dist/src/utils/layout/point.d.ts +16 -0
  377. package/dist/src/utils/layout/point.d.ts.map +1 -0
  378. package/dist/src/utils/layout/point.js +23 -0
  379. package/dist/src/utils/layout/rectangle.d.ts +142 -0
  380. package/dist/src/utils/layout/rectangle.d.ts.map +1 -0
  381. package/dist/src/utils/layout/rectangle.js +296 -0
  382. package/dist/src/utils/layout/rectangle.test.js +172 -0
  383. package/dist/src/utils/mergeObjects.d.ts +15 -0
  384. package/dist/src/utils/mergeObjects.d.ts.map +1 -0
  385. package/dist/src/utils/mergeObjects.js +99 -0
  386. package/dist/src/utils/mergeObjects.test.js +42 -0
  387. package/dist/src/utils/numberExtractor.d.ts +9 -0
  388. package/dist/src/utils/numberExtractor.d.ts.map +1 -0
  389. package/dist/src/utils/numberExtractor.js +24 -0
  390. package/dist/src/utils/numberExtractor.test.js +6 -0
  391. package/dist/src/utils/point.d.ts +9 -0
  392. package/dist/src/utils/point.d.ts.map +1 -0
  393. package/dist/src/utils/point.js +14 -0
  394. package/dist/src/utils/propertyCacher.d.ts +30 -0
  395. package/dist/src/utils/propertyCacher.d.ts.map +1 -0
  396. package/dist/src/utils/propertyCacher.js +70 -0
  397. package/dist/src/utils/propertyCacher.test.js +85 -0
  398. package/dist/src/utils/propertyCoalescer.d.ts +15 -0
  399. package/dist/src/utils/propertyCoalescer.d.ts.map +1 -0
  400. package/dist/src/utils/propertyCoalescer.js +42 -0
  401. package/dist/src/utils/propertyCoalescer.test.js +22 -0
  402. package/dist/src/utils/reservationMap.d.ts +42 -0
  403. package/dist/src/utils/reservationMap.d.ts.map +1 -0
  404. package/dist/src/utils/reservationMap.js +103 -0
  405. package/dist/src/utils/reservationMap.test.js +20 -0
  406. package/dist/src/utils/scaleNull.d.ts +13 -0
  407. package/dist/src/utils/scaleNull.d.ts.map +1 -0
  408. package/dist/src/utils/scaleNull.js +21 -0
  409. package/dist/src/utils/setOperations.d.ts +31 -0
  410. package/dist/src/utils/setOperations.d.ts.map +1 -0
  411. package/dist/src/utils/setOperations.js +75 -0
  412. package/dist/src/utils/smoothstep.d.ts +7 -0
  413. package/dist/src/utils/smoothstep.d.ts.map +1 -0
  414. package/dist/src/utils/smoothstep.js +10 -0
  415. package/dist/src/utils/throttle.d.ts +8 -0
  416. package/dist/src/utils/throttle.d.ts.map +1 -0
  417. package/dist/src/utils/throttle.js +34 -0
  418. package/dist/src/utils/topK.d.ts +22 -0
  419. package/dist/src/utils/topK.d.ts.map +1 -0
  420. package/dist/src/utils/topK.js +76 -0
  421. package/dist/src/utils/topK.test.js +64 -0
  422. package/dist/src/utils/transition.d.ts +44 -0
  423. package/dist/src/utils/transition.d.ts.map +1 -0
  424. package/dist/src/utils/transition.js +74 -0
  425. package/dist/src/utils/trees.d.ts +56 -0
  426. package/dist/src/utils/trees.d.ts.map +1 -0
  427. package/dist/src/utils/trees.js +92 -0
  428. package/dist/src/utils/trees.test.js +130 -0
  429. package/dist/src/utils/ui/tooltip.d.ts +50 -0
  430. package/dist/src/utils/ui/tooltip.d.ts.map +1 -0
  431. package/dist/src/utils/ui/tooltip.js +189 -0
  432. package/dist/src/utils/url.d.ts +9 -0
  433. package/dist/src/utils/url.d.ts.map +1 -0
  434. package/dist/src/utils/url.js +22 -0
  435. package/dist/src/utils/variableTools.d.ts +14 -0
  436. package/dist/src/utils/variableTools.d.ts.map +1 -0
  437. package/dist/src/utils/variableTools.js +24 -0
  438. package/dist/src/utils/variableTools.test.js +13 -0
  439. package/dist/src/view/axisGridView.d.ts +39 -0
  440. package/dist/src/view/axisGridView.d.ts.map +1 -0
  441. package/dist/src/view/axisGridView.js +246 -0
  442. package/dist/src/view/axisResolution.d.ts +24 -0
  443. package/dist/src/view/axisResolution.d.ts.map +1 -0
  444. package/dist/src/view/axisResolution.js +141 -0
  445. package/dist/src/view/axisResolution.test.js +201 -0
  446. package/dist/src/view/axisView.d.ts +49 -0
  447. package/dist/src/view/axisView.d.ts.map +1 -0
  448. package/dist/src/view/axisView.js +629 -0
  449. package/dist/src/view/concatView.d.ts +16 -0
  450. package/dist/src/view/concatView.d.ts.map +1 -0
  451. package/dist/src/view/concatView.js +84 -0
  452. package/dist/src/view/containerView.d.ts +43 -0
  453. package/dist/src/view/containerView.d.ts.map +1 -0
  454. package/dist/src/view/containerView.js +137 -0
  455. package/dist/src/view/facetView.d.ts +71 -0
  456. package/dist/src/view/facetView.d.ts.map +1 -0
  457. package/dist/src/view/facetView.js +492 -0
  458. package/dist/src/view/flowBuilder.d.ts +37 -0
  459. package/dist/src/view/flowBuilder.d.ts.map +1 -0
  460. package/dist/src/view/flowBuilder.js +383 -0
  461. package/dist/src/view/flowBuilder.test.js +125 -0
  462. package/dist/src/view/gridView.d.ts +111 -0
  463. package/dist/src/view/gridView.d.ts.map +1 -0
  464. package/dist/src/view/gridView.js +1086 -0
  465. package/dist/src/view/implicitRootView.d.ts +9 -0
  466. package/dist/src/view/implicitRootView.d.ts.map +1 -0
  467. package/dist/src/view/implicitRootView.js +23 -0
  468. package/dist/src/view/importView.d.ts +17 -0
  469. package/dist/src/view/importView.d.ts.map +1 -0
  470. package/dist/src/view/importView.js +22 -0
  471. package/dist/src/view/layerView.d.ts +25 -0
  472. package/dist/src/view/layerView.d.ts.map +1 -0
  473. package/dist/src/view/layerView.js +77 -0
  474. package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts +30 -0
  475. package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts.map +1 -0
  476. package/dist/src/view/renderingContext/bufferedViewRenderingContext.js +175 -0
  477. package/dist/src/view/renderingContext/compositeViewRenderingContext.d.ts +14 -0
  478. package/dist/src/view/renderingContext/compositeViewRenderingContext.d.ts.map +1 -0
  479. package/dist/src/view/renderingContext/compositeViewRenderingContext.js +51 -0
  480. package/dist/src/view/renderingContext/debuggingViewRenderingContext.d.ts +51 -0
  481. package/dist/src/view/renderingContext/debuggingViewRenderingContext.d.ts.map +1 -0
  482. package/dist/src/view/renderingContext/debuggingViewRenderingContext.js +94 -0
  483. package/dist/src/view/renderingContext/layoutRecorderViewRenderingContext.d.ts +60 -0
  484. package/dist/src/view/renderingContext/layoutRecorderViewRenderingContext.d.ts.map +1 -0
  485. package/dist/src/view/renderingContext/layoutRecorderViewRenderingContext.js +128 -0
  486. package/dist/src/view/renderingContext/simpleViewRenderingContext.d.ts +19 -0
  487. package/dist/src/view/renderingContext/simpleViewRenderingContext.d.ts.map +1 -0
  488. package/dist/src/view/renderingContext/simpleViewRenderingContext.js +64 -0
  489. package/dist/src/view/renderingContext/svgViewRenderingContext.d.ts +22 -0
  490. package/dist/src/view/renderingContext/svgViewRenderingContext.d.ts.map +1 -0
  491. package/dist/src/view/renderingContext/svgViewRenderingContext.js +125 -0
  492. package/dist/src/view/renderingContext/viewRenderingContext.d.ts +33 -0
  493. package/dist/src/view/renderingContext/viewRenderingContext.d.ts.map +1 -0
  494. package/dist/src/view/renderingContext/viewRenderingContext.js +41 -0
  495. package/dist/src/view/scaleResolution.d.ts +170 -0
  496. package/dist/src/view/scaleResolution.d.ts.map +1 -0
  497. package/dist/src/view/scaleResolution.js +874 -0
  498. package/dist/src/view/scaleResolution.test.js +658 -0
  499. package/dist/src/view/testUtils.d.ts +30 -0
  500. package/dist/src/view/testUtils.d.ts.map +1 -0
  501. package/dist/src/view/testUtils.js +101 -0
  502. package/dist/src/view/title.d.ts +6 -0
  503. package/dist/src/view/title.d.ts.map +1 -0
  504. package/dist/src/view/title.js +165 -0
  505. package/dist/src/view/unitView.d.ts +93 -0
  506. package/dist/src/view/unitView.d.ts.map +1 -0
  507. package/dist/src/view/unitView.js +345 -0
  508. package/dist/src/view/view.d.ts +291 -0
  509. package/dist/src/view/view.d.ts.map +1 -0
  510. package/dist/src/view/view.js +691 -0
  511. package/dist/src/view/view.test.js +214 -0
  512. package/dist/src/view/viewFactory.d.ts +76 -0
  513. package/dist/src/view/viewFactory.d.ts.map +1 -0
  514. package/dist/src/view/viewFactory.js +178 -0
  515. package/dist/src/view/viewFactory.test.js +17 -0
  516. package/dist/src/view/viewUtils.d.ts +90 -0
  517. package/dist/src/view/viewUtils.d.ts.map +1 -0
  518. package/dist/src/view/viewUtils.js +326 -0
  519. package/dist/src/view/zoom.d.ts +23 -0
  520. package/dist/src/view/zoom.d.ts.map +1 -0
  521. package/dist/src/view/zoom.js +89 -0
  522. package/package.json +15 -12
  523. package/dist/style.css +0 -1
@@ -0,0 +1,1004 @@
1
+ import {
2
+ createBufferInfoFromArrays,
3
+ createProgramInfoFromProgram,
4
+ createUniformBlockInfo,
5
+ createVertexArrayInfo,
6
+ setAttribInfoBufferFromArray,
7
+ setBlockUniforms,
8
+ setUniformBlock,
9
+ setUniforms,
10
+ } from "twgl.js";
11
+ import { isContinuous, isDiscrete } from "vega-scale";
12
+ import createEncoders, {
13
+ isChannelDefWithScale,
14
+ isChannelWithScale,
15
+ isDatumDef,
16
+ isValueDef,
17
+ } from "../encoder/encoder";
18
+ import {
19
+ DOMAIN_PREFIX,
20
+ generateValueGlsl,
21
+ generateScaleGlsl,
22
+ RANGE_TEXTURE_PREFIX,
23
+ ATTRIBUTE_PREFIX,
24
+ isHighPrecisionScale,
25
+ toHighPrecisionDomainUniform,
26
+ splitHighPrecision,
27
+ } from "../scale/glslScaleGenerator";
28
+ import GLSL_COMMON from "../gl/includes/common.glsl.js";
29
+ import GLSL_SCALES from "../gl/includes/scales.glsl.js";
30
+ import GLSL_SAMPLE_FACET from "../gl/includes/sampleFacet.glsl.js";
31
+ import GLSL_PICKING_VERTEX from "../gl/includes/picking.vertex.glsl.js";
32
+ import GLSL_PICKING_FRAGMENT from "../gl/includes/picking.fragment.glsl.js";
33
+ import { getCachedOrCall } from "../utils/propertyCacher";
34
+ import { createProgram } from "../gl/webGLHelper";
35
+ import coalesceProperties from "../utils/propertyCoalescer";
36
+ import { isScalar } from "../utils/variableTools";
37
+ import { InternMap } from "internmap";
38
+ import scaleNull from "../utils/scaleNull";
39
+
40
+ export const SAMPLE_FACET_UNIFORM = "SAMPLE_FACET_UNIFORM";
41
+ export const SAMPLE_FACET_TEXTURE = "SAMPLE_FACET_TEXTURE";
42
+
43
+ /**
44
+ *
45
+ * @typedef {import("../types/rendering").RenderingOptions} RenderingOptions
46
+ * @typedef {object} _MarkRenderingOptions
47
+ * @prop {boolean} [skipViewportSetup] Don't configure viewport. Allows for
48
+ * optimized faceted rendering
49
+ * @typedef {RenderingOptions & _MarkRenderingOptions} MarkRenderingOptions
50
+ *
51
+ * @callback DrawFunction
52
+ * @param {number} offset
53
+ * @param {number} count
54
+ *
55
+ */
56
+ export default class Mark {
57
+ /**
58
+ * @typedef {import("../spec/mark").MarkConfig} MarkConfig
59
+ * @typedef {import("../spec/channel").Channel} Channel
60
+ * @typedef {import("../spec/channel").Encoding} Encoding
61
+ * @typedef {import("../spec/channel").ValueDef} ValueDef
62
+ */
63
+
64
+ /**
65
+ * @param {import("../view/unitView").default} unitView
66
+ */
67
+ constructor(unitView) {
68
+ this.unitView = unitView;
69
+
70
+ /** @type {Record<string, import("../types/encoder").Encoder>} */
71
+ this.encoders = undefined;
72
+
73
+ // TODO: Consolidate the following webgl stuff into a single object
74
+
75
+ /** @type {import("twgl.js").BufferInfo & { allocatedVertices?: number }} WebGL buffers */
76
+ this.bufferInfo = undefined;
77
+
78
+ /** @type {import("twgl.js").ProgramInfo} WebGL buffers */
79
+ this.programInfo = undefined;
80
+
81
+ /** @type {import("twgl.js").VertexArrayInfo} WebGL buffers */
82
+ this.vertexArrayInfo = undefined;
83
+
84
+ /** @type {import("twgl.js").UniformBlockInfo} WebGL buffers */
85
+ this.domainUniformInfo = undefined;
86
+
87
+ /** @type {import("twgl.js").UniformBlockInfo} WebGL buffers */
88
+ this.viewUniformInfo = undefined;
89
+
90
+ /** @type {RangeMap<any>} keep track of facet locations within the vertex array */
91
+ this.rangeMap = new RangeMap();
92
+
93
+ // TODO: Implement https://vega.github.io/vega-lite/docs/config.html
94
+ /** @type {MarkConfig} */
95
+ this.defaultProperties = {
96
+ get clip() {
97
+ // TODO: Cache once the scales have been resolved
98
+ // TODO: Only check channels that are used
99
+ // TODO: provide more fine-grained xClip and yClip props
100
+ return /** @type {import("../spec/channel").PositionalChannel[]} */ ([
101
+ "x",
102
+ "y",
103
+ ])
104
+ .map((channel) => unitView.getScaleResolution(channel))
105
+ .some((resolution) => resolution?.isZoomable() ?? false);
106
+ },
107
+ xOffset: 0,
108
+ yOffset: 0,
109
+
110
+ /**
111
+ * Minimum size for WebGL buffers (number of data items).
112
+ * Allows for using bufferSubData to update graphics.
113
+ * This property is intended for internal usage.
114
+ */
115
+ minBufferSize: 0,
116
+ };
117
+
118
+ /**
119
+ * A properties object that contains the configured mark properties or
120
+ * default values as fallback.
121
+ *
122
+ * TODO: Proper and comprehensive typings for mark properties
123
+ *
124
+ * @type {Partial<MarkConfig>}
125
+ * @readonly
126
+ */
127
+ this.properties = coalesceProperties(
128
+ typeof this.unitView.spec.mark == "object"
129
+ ? () => /** @type {MarkConfig} */ (this.unitView.spec.mark)
130
+ : () => /** @type {MarkConfig} */ ({}),
131
+ () => this.defaultProperties
132
+ );
133
+ }
134
+
135
+ get opaque() {
136
+ return false;
137
+ }
138
+
139
+ /**
140
+ * Returns attribute info for WebGL attributes that match visual channels.
141
+ *
142
+ * Note: attributes and channels do not necessarily match.
143
+ * For example, rectangles have x, y, x2, and y2 channels but only x and y as attributes.
144
+ *
145
+ * @returns {string[]}
146
+ */
147
+ getAttributes() {
148
+ // override
149
+ throw new Error("Not implemented!");
150
+ }
151
+
152
+ /**
153
+ * @returns {Channel[]}
154
+ */
155
+ getSupportedChannels() {
156
+ return [
157
+ "sample",
158
+ "facetIndex",
159
+ "x",
160
+ "y",
161
+ "color",
162
+ "opacity",
163
+ "search",
164
+ "uniqueId",
165
+ ];
166
+ }
167
+
168
+ /**
169
+ * @returns {Encoding}
170
+ */
171
+ getDefaultEncoding() {
172
+ /** @type {Encoding} */
173
+ const encoding = {
174
+ sample: undefined,
175
+ uniqueId: undefined,
176
+ };
177
+
178
+ if (this.isPickingParticipant()) {
179
+ encoding.uniqueId = {
180
+ field: "_uniqueId", // TODO: Use constant
181
+ };
182
+ }
183
+
184
+ return encoding;
185
+ }
186
+
187
+ /**
188
+ * Adds intelligent defaults etc to the encoding.
189
+ *
190
+ * @param {Encoding} encoding
191
+ * @returns {Encoding}
192
+ */
193
+ fixEncoding(encoding) {
194
+ return encoding;
195
+ }
196
+
197
+ /**
198
+ * Returns the encoding spec supplemented with mark's default encodings
199
+ *
200
+ * @returns {Encoding}
201
+ */
202
+ get encoding() {
203
+ return getCachedOrCall(this, "encoding", () => {
204
+ const defaults = this.getDefaultEncoding();
205
+ const configured = this.unitView.getEncoding();
206
+
207
+ /** @type {(property: string) => ValueDef} */
208
+ const propToValueDef = (property) => {
209
+ const value =
210
+ this.properties[/** @type {keyof MarkConfig} */ (property)];
211
+ return isScalar(value) && { value };
212
+ };
213
+
214
+ const propertyValues = Object.fromEntries(
215
+ this.getSupportedChannels()
216
+ .map(
217
+ (channel) =>
218
+ /** @type {[Channel, ValueDef]} */ ([
219
+ channel,
220
+ propToValueDef(channel),
221
+ ])
222
+ )
223
+ .filter((entry) => entry[1].value !== undefined)
224
+ );
225
+
226
+ const encoding = this.fixEncoding({
227
+ ...defaults,
228
+ ...propertyValues,
229
+ ...configured,
230
+ });
231
+
232
+ for (const channel of Object.keys(encoding)) {
233
+ if (!this.getSupportedChannels().includes(channel)) {
234
+ // TODO: Only delete channels that were inherited
235
+ // Should complain about unsupported channels that were
236
+ // explicitly specified.
237
+ delete encoding[channel];
238
+ }
239
+ }
240
+
241
+ return encoding;
242
+ });
243
+ }
244
+
245
+ getContext() {
246
+ return this.unitView.context;
247
+ }
248
+
249
+ getType() {
250
+ return this.unitView.getMarkType();
251
+ }
252
+
253
+ initializeData() {
254
+ //
255
+ }
256
+
257
+ /**
258
+ * Initialize encoders that encode fields of the data (or constants) to
259
+ * the ranges of the visual channels.
260
+ */
261
+ initializeEncoders() {
262
+ this.encoders = createEncoders(this);
263
+ }
264
+
265
+ /**
266
+ * Initialize shaders etc.
267
+ */
268
+ async initializeGraphics() {
269
+ //override
270
+ }
271
+
272
+ /**
273
+ * Update WebGL buffers from the data
274
+ */
275
+ updateGraphicsData() {
276
+ // override
277
+ }
278
+
279
+ getSampleFacetMode() {
280
+ if (this.encoders.facetIndex) {
281
+ return SAMPLE_FACET_TEXTURE;
282
+ } else if (
283
+ // If the UnitView is inside app's SampleView.
284
+ // TODO: This may break if non-faceted stuff is added to SampleView,
285
+ // e.g., view background or an x axis.
286
+ // This could also be more generic and work with other faceting views
287
+ // that will be available in the future.
288
+ this.unitView
289
+ .getLayoutAncestors()
290
+ .find((view) => "samples" in view.spec)
291
+ ) {
292
+ return SAMPLE_FACET_UNIFORM;
293
+ }
294
+ }
295
+
296
+ /**
297
+ *
298
+ * @param {string} vertexShader
299
+ * @param {string} fragmentShader
300
+ * @param {string[]} [extraHeaders]
301
+ */
302
+ createAndLinkShaders(vertexShader, fragmentShader, extraHeaders = []) {
303
+ const attributes = this.getAttributes();
304
+
305
+ // For debugging
306
+ extraHeaders.push("// view: " + this.unitView.getPathString());
307
+
308
+ // TODO: This is a temporary variable, don't store it in the mark object
309
+ /** @type {string[]} */
310
+ this.domainUniforms = [];
311
+
312
+ /** @type {string[]} */
313
+ let scaleCode = [];
314
+
315
+ const sampleFacetMode = this.getSampleFacetMode();
316
+ if (sampleFacetMode) {
317
+ extraHeaders.push(`#define ${sampleFacetMode}`);
318
+ }
319
+
320
+ for (const attribute of attributes) {
321
+ /** @type {Channel} */
322
+ let channel;
323
+ if (attribute in this.encoding) {
324
+ channel = /** @type {Channel} */ (attribute);
325
+ } else {
326
+ continue;
327
+ }
328
+
329
+ const channelDef = this.encoding[channel];
330
+
331
+ if (!channelDef) {
332
+ continue;
333
+ }
334
+
335
+ if (isValueDef(channelDef)) {
336
+ scaleCode.push(generateValueGlsl(channel, channelDef.value));
337
+ } else {
338
+ const resolutionChannel =
339
+ (isChannelDefWithScale(channelDef) &&
340
+ channelDef.resolutionChannel) ||
341
+ channel;
342
+
343
+ const scale = isChannelWithScale(resolutionChannel)
344
+ ? this.unitView
345
+ .getScaleResolution(resolutionChannel)
346
+ .getScale()
347
+ : scaleNull();
348
+
349
+ const generated = generateScaleGlsl(channel, scale, channelDef);
350
+
351
+ scaleCode.push(generated.glsl);
352
+ if (generated.domainUniform) {
353
+ this.domainUniforms.push(generated.domainUniform);
354
+ }
355
+ }
356
+ }
357
+
358
+ const domainUniformBlock = this.domainUniforms.length
359
+ ? "layout(std140) uniform Domains {\n" +
360
+ this.domainUniforms.map((u) => ` ${u}\n`).join("") +
361
+ "};\n\n"
362
+ : "";
363
+
364
+ const vertexPrecision = "precision highp float;\n";
365
+
366
+ const vertexParts = [
367
+ vertexPrecision,
368
+ ...extraHeaders,
369
+ GLSL_COMMON,
370
+ GLSL_SCALES,
371
+ domainUniformBlock,
372
+ ...scaleCode,
373
+ GLSL_SAMPLE_FACET,
374
+ GLSL_PICKING_VERTEX,
375
+ vertexShader,
376
+ ];
377
+
378
+ const fragmentParts = [
379
+ ...extraHeaders,
380
+ GLSL_COMMON,
381
+ GLSL_PICKING_FRAGMENT,
382
+ fragmentShader,
383
+ ];
384
+
385
+ const gl = this.gl;
386
+
387
+ // Postpone status checking to allow for background compilation
388
+ // See: https://toji.github.io/shader-perf/
389
+ // TODO: It might make sense to cache and share identical programs between mark instances.
390
+ this.programStatus = createProgram(
391
+ gl,
392
+ this.glHelper.compileShader(gl.VERTEX_SHADER, vertexParts),
393
+ this.glHelper.compileShader(gl.FRAGMENT_SHADER, fragmentParts)
394
+ );
395
+ }
396
+
397
+ /**
398
+ * Check WebGL shader/program compilation/linking status and finalize
399
+ * initialization.
400
+ */
401
+ finalizeGraphicsInitialization() {
402
+ const error = this.programStatus.getProgramErrors();
403
+ if (error) {
404
+ if (error.detail) {
405
+ console.warn(error.detail);
406
+ }
407
+ /** @type {Error & { view?: import("../view/view").default}} */
408
+ const err = new Error(
409
+ "Cannot create shader program: " + error.message
410
+ );
411
+ err.view = this.unitView;
412
+ throw err;
413
+ }
414
+
415
+ this.programInfo = createProgramInfoFromProgram(
416
+ this.gl,
417
+ this.programStatus.program
418
+ );
419
+ delete this.programStatus;
420
+
421
+ if (this.domainUniforms.length) {
422
+ this.domainUniformInfo = createUniformBlockInfo(
423
+ this.gl,
424
+ this.programInfo,
425
+ "Domains"
426
+ );
427
+ }
428
+
429
+ this.viewUniformInfo = createUniformBlockInfo(
430
+ this.gl,
431
+ this.programInfo,
432
+ "View"
433
+ );
434
+
435
+ this.gl.useProgram(this.programInfo.program);
436
+
437
+ this._setDatums();
438
+
439
+ setUniforms(this.programInfo, {
440
+ // left pos, left height, right pos, right height
441
+ uSampleFacet: [0, 1, 0, 1],
442
+ uTransitionOffset: 0.0,
443
+ });
444
+ }
445
+
446
+ _setDatums() {
447
+ for (const [channel, channelDef] of Object.entries(this.encoding)) {
448
+ if (isDatumDef(channelDef)) {
449
+ const encoder = this.encoders[channel];
450
+
451
+ const datum = encoder.indexer
452
+ ? encoder.indexer(channelDef.datum)
453
+ : isHighPrecisionScale(encoder.scale.type)
454
+ ? splitHighPrecision(+channelDef.datum)
455
+ : +channelDef.datum;
456
+
457
+ setUniforms(this.programInfo, {
458
+ [ATTRIBUTE_PREFIX + channel]: datum,
459
+ });
460
+ }
461
+ }
462
+ }
463
+
464
+ /**
465
+ * Delete WebGL buffers etc.
466
+ */
467
+ deleteGraphicsData() {
468
+ if (this.bufferInfo) {
469
+ const gl = this.gl;
470
+ // A hack to prevent WebGL: INVALID_OPERATION: drawArrays: no buffer is bound to enabled attribute
471
+ // TODO: Consider using bufferSubData or DYNAMIC_DRAW etc...
472
+ for (let i = 0; i < 8; i++) {
473
+ gl.disableVertexAttribArray(i);
474
+ }
475
+
476
+ Object.values(this.bufferInfo.attribs).forEach((attribInfo) =>
477
+ this.gl.deleteBuffer(attribInfo.buffer)
478
+ );
479
+ if (this.bufferInfo.indices) {
480
+ this.gl.deleteBuffer(this.bufferInfo.indices);
481
+ }
482
+ this.bufferInfo = undefined;
483
+ }
484
+ }
485
+
486
+ /**
487
+ *
488
+ * @param {any} vertexData TODO: Extract type from VertexBuilder
489
+ */
490
+ updateBufferInfo(vertexData) {
491
+ // Ensure that no VAOs are inadvertently altered
492
+ this.gl.bindVertexArray(null);
493
+
494
+ if (
495
+ this.bufferInfo &&
496
+ vertexData.vertexCount <= this.bufferInfo.allocatedVertices
497
+ ) {
498
+ for (const [attribute, attributeData] of Object.entries(
499
+ vertexData.arrays
500
+ )) {
501
+ // Skip constants
502
+ if (attributeData.data) {
503
+ // TODO: Check that all attributes and numComponents match
504
+ setAttribInfoBufferFromArray(
505
+ this.gl,
506
+ this.bufferInfo.attribs[attribute],
507
+ attributeData.data,
508
+ 0
509
+ );
510
+ // TODO: Consider double buffering:
511
+ // https://community.khronos.org/t/texture-buffers-are-much-slower-than-uniform-buffers/77139
512
+ }
513
+ }
514
+ } else {
515
+ this.deleteGraphicsData();
516
+ this.bufferInfo = createBufferInfoFromArrays(
517
+ this.gl,
518
+ vertexData.arrays,
519
+ { numElements: vertexData.vertexCount }
520
+ );
521
+ this.bufferInfo.allocatedVertices = vertexData.allocatedVertices;
522
+ this.vertexArrayInfo = undefined;
523
+ }
524
+ }
525
+
526
+ /** Convenience method */
527
+ get glHelper() {
528
+ return this.getContext().glHelper;
529
+ }
530
+
531
+ /** Convenience method */
532
+ get gl() {
533
+ return this.glHelper.gl;
534
+ }
535
+
536
+ onBeforeSampleAnimation() {
537
+ // override
538
+ }
539
+
540
+ onAfterSampleAnimation() {
541
+ // override
542
+ }
543
+
544
+ isReady() {
545
+ return this.bufferInfo && this.programInfo;
546
+ }
547
+
548
+ /**
549
+ * Returns true if this mark instance participates in picking.
550
+ *
551
+ * TODO: Check if tooltip is enabled,
552
+ * TODO: Check if selection (when it's implemented) is enabled
553
+ */
554
+ isPickingParticipant() {
555
+ // TODO: Should check encoding instead
556
+ if (this.properties.tooltip === null) {
557
+ // Disabled
558
+ return false;
559
+ }
560
+
561
+ for (const view of this.unitView.getLayoutAncestors()) {
562
+ if (!view.isPickingSupported()) {
563
+ return false;
564
+ }
565
+ }
566
+
567
+ return true;
568
+ }
569
+
570
+ /**
571
+ * Configures the WebGL state for rendering the mark instances.
572
+ * A separate preparation stage allows for efficient rendering of faceted
573
+ * views, i.e., multiple views share the uniforms (such as mark properties
574
+ * and scales) and buffers.
575
+ *
576
+ * @param {import("../types/rendering").GlobalRenderingOptions} options
577
+ * @returns {(() => void)[]}
578
+ */
579
+ // eslint-disable-next-line complexity
580
+ prepareRender(options) {
581
+ const glHelper = this.glHelper;
582
+ const gl = this.gl;
583
+
584
+ /** @type {(() => void)[]} */
585
+ const ops = [];
586
+
587
+ ops.push(() => {
588
+ if (!this.vertexArrayInfo) {
589
+ this.vertexArrayInfo = createVertexArrayInfo(
590
+ this.gl,
591
+ this.programInfo,
592
+ this.bufferInfo
593
+ );
594
+ }
595
+
596
+ gl.useProgram(this.programInfo.program);
597
+ });
598
+
599
+ if (this.domainUniformInfo) {
600
+ // TODO: Only update the domains that have changed
601
+
602
+ for (const [uniform, setter] of Object.entries(
603
+ this.domainUniformInfo.setters
604
+ )) {
605
+ // TODO: isChannel()
606
+ const channel = /** @type {Channel} */ (
607
+ uniform.substring(DOMAIN_PREFIX.length)
608
+ );
609
+
610
+ const channelDef = this.encoding[channel];
611
+ const resolutionChannel =
612
+ (isChannelDefWithScale(channelDef) &&
613
+ channelDef.resolutionChannel) ||
614
+ channel;
615
+
616
+ if (isChannelWithScale(resolutionChannel)) {
617
+ const scale = this.unitView
618
+ .getScaleResolution(resolutionChannel)
619
+ .getScale();
620
+
621
+ ops.push(() => {
622
+ const domain = isDiscrete(scale.type)
623
+ ? [0, scale.domain().length]
624
+ : scale.domain();
625
+
626
+ setter(
627
+ isHighPrecisionScale(scale.type)
628
+ ? toHighPrecisionDomainUniform(domain)
629
+ : domain
630
+ );
631
+ });
632
+ }
633
+ }
634
+
635
+ ops.push(() =>
636
+ setUniformBlock(gl, this.programInfo, this.domainUniformInfo)
637
+ );
638
+ }
639
+
640
+ for (const [channel, channelDef] of Object.entries(this.encoding)) {
641
+ if (isChannelDefWithScale(channelDef)) {
642
+ const resolutionChannel =
643
+ (isChannelDefWithScale(channelDef) &&
644
+ channelDef.resolutionChannel) ||
645
+ channel;
646
+
647
+ if (isChannelWithScale(resolutionChannel)) {
648
+ const resolution =
649
+ this.unitView.getScaleResolution(resolutionChannel);
650
+
651
+ const texture = glHelper.rangeTextures.get(resolution);
652
+ if (texture) {
653
+ ops.push(() =>
654
+ setUniforms(this.programInfo, {
655
+ [RANGE_TEXTURE_PREFIX + channel]: texture,
656
+ })
657
+ );
658
+ }
659
+ }
660
+ }
661
+ }
662
+
663
+ if (this.getSampleFacetMode() == SAMPLE_FACET_TEXTURE) {
664
+ ops.push(() => {
665
+ /** @type {WebGLTexture} */
666
+ let facetTexture;
667
+ for (const view of this.unitView.getLayoutAncestors()) {
668
+ facetTexture = view.getSampleFacetTexture();
669
+ if (facetTexture) {
670
+ break;
671
+ }
672
+ }
673
+
674
+ if (!facetTexture) {
675
+ throw new Error("No facet texture available. This is bug.");
676
+ }
677
+
678
+ setUniforms(this.programInfo, {
679
+ uSampleFacetTexture: facetTexture,
680
+ });
681
+ });
682
+ }
683
+
684
+ // TODO: Rendering of the mark should be completely skipped if it doesn't
685
+ // participate picking
686
+ const picking =
687
+ (options.picking ?? false) && this.isPickingParticipant();
688
+
689
+ // Note: the block is sent to GPU in setViewport(), which is repeated for each facet
690
+ ops.push(() =>
691
+ setBlockUniforms(this.viewUniformInfo, {
692
+ uViewOpacity: this.unitView.getEffectiveOpacity(),
693
+ uPickingEnabled: picking,
694
+ })
695
+ );
696
+
697
+ if (this.opaque || options.picking) {
698
+ ops.push(() => gl.disable(gl.BLEND));
699
+ } else {
700
+ ops.push(() => gl.enable(gl.BLEND));
701
+ }
702
+
703
+ return ops;
704
+ }
705
+
706
+ /**
707
+ * Prepares rendering of a single sample facet.
708
+ *
709
+ * @param {MarkRenderingOptions} options
710
+ * @returns {boolean} true if rendering should proceed,
711
+ * false if it should be skipped
712
+ */
713
+ prepareSampleFacetRendering(options) {
714
+ const opts = options.sampleFacetRenderingOptions;
715
+ const locationSetter = this.programInfo.uniformSetters.uSampleFacet;
716
+
717
+ if (opts && locationSetter) {
718
+ const pos = opts.locSize ? opts.locSize.location : 0.0;
719
+ const height = opts.locSize ? opts.locSize.size : 1.0;
720
+
721
+ if (pos > 1.0 || pos + height < 0.0) {
722
+ // Not visible
723
+ return false;
724
+ }
725
+
726
+ const targetPos = opts.targetLocSize
727
+ ? opts.targetLocSize.location
728
+ : pos;
729
+ const targetHeight = opts.targetLocSize
730
+ ? opts.targetLocSize.size
731
+ : height;
732
+
733
+ // Use WebGL directly, because twgl uses gl.uniform4fv, which has an
734
+ // inferior performance. Based on profiling, this optimization gives
735
+ // a significant performance boost.
736
+ this.gl.uniform4f(
737
+ // @ts-expect-error
738
+ locationSetter.location, // TODO: Make a twgl pull request to fix typing
739
+ pos,
740
+ height,
741
+ targetPos,
742
+ targetHeight
743
+ );
744
+ }
745
+
746
+ return true;
747
+ }
748
+
749
+ /**
750
+ * Returns a callback function that the ViewRenderingContext calls to
751
+ * perform the actual rendering either immediately or at a later time.
752
+ *
753
+ * @param {MarkRenderingOptions} options
754
+ * @returns {function():void} A function that renderingContext calls to
755
+ * trigger the actual rendering
756
+ */
757
+ render(options) {
758
+ // Override
759
+ return undefined;
760
+ }
761
+
762
+ /**
763
+ * @param {DrawFunction} draw A function that draws a range of vertices
764
+ * @param {import("./mark").MarkRenderingOptions} options
765
+ */
766
+ createRenderCallback(draw, options) {
767
+ if (!this.bufferInfo) {
768
+ const e = new Error(
769
+ `${this.getType()} mark has no data. This is bug.`
770
+ );
771
+ // @ts-ignore
772
+ e.view = this.unitView;
773
+ throw e;
774
+ }
775
+
776
+ // eslint-disable-next-line consistent-this
777
+ const self = this;
778
+
779
+ /** @type {function(import("../gl/dataToVertices").RangeEntry):void} rangeEntry */
780
+ let drawWithRangeEntry;
781
+
782
+ const scale = this.unitView.getScaleResolution("x")?.getScale();
783
+ const continuous = scale && isContinuous(scale.type);
784
+ const domainStartOffset = ["index", "locus"].includes(scale?.type)
785
+ ? -1
786
+ : 0;
787
+
788
+ /** @type {[number, number]} Recycle to ease garbage collector's work */
789
+ const arr = [0, 0];
790
+
791
+ drawWithRangeEntry = (rangeEntry) => {
792
+ if (continuous && rangeEntry.xIndex) {
793
+ const domain = scale.domain();
794
+ const vertexIndices = rangeEntry.xIndex(
795
+ domain[0] + domainStartOffset,
796
+ domain[1],
797
+ arr
798
+ );
799
+ const offset = vertexIndices[0];
800
+ const count = vertexIndices[1] - offset;
801
+ if (count > 0) {
802
+ draw(offset, count);
803
+ }
804
+ } else {
805
+ draw(rangeEntry.offset, rangeEntry.count);
806
+ }
807
+ };
808
+
809
+ // If is either faceted or non-faceted, not both.
810
+ // An undefined key with vertices means that the mark is non-faceted.
811
+ // In such case, the same non-faceted data is repeated for each facet.
812
+ const facetId =
813
+ this.rangeMap.get(undefined).count == 0
814
+ ? options.facetId
815
+ : undefined;
816
+ const rangeEntry = this.rangeMap.get(facetId);
817
+
818
+ return options.sampleFacetRenderingOptions
819
+ ? function renderSampleFacetRange() {
820
+ if (rangeEntry.count) {
821
+ if (self.prepareSampleFacetRendering(options)) {
822
+ drawWithRangeEntry(rangeEntry);
823
+ }
824
+ }
825
+ }
826
+ : function renderRange() {
827
+ if (rangeEntry.count) {
828
+ drawWithRangeEntry(rangeEntry);
829
+ }
830
+ };
831
+ }
832
+
833
+ /**
834
+ * Sets viewport, clipping, and uniforms related to scaling and translation
835
+ *
836
+ * @param {import("../utils/layout/rectangle").default} coords
837
+ * @param {import("../utils/layout/rectangle").default} [clipRect]
838
+ * @returns {boolean} true if the viewport is renderable (size > 0)
839
+ */
840
+ setViewport(coords, clipRect) {
841
+ coords = coords.flatten();
842
+
843
+ const dpr = this.unitView.context.devicePixelRatio;
844
+ const gl = this.gl;
845
+ const props = this.properties;
846
+
847
+ const logicalSize = this.glHelper.getLogicalCanvasSize();
848
+
849
+ // Translate by half a pixel to place vertical / horizontal
850
+ // rules inside pixels, not between pixels.
851
+ const pixelOffset = 0.5;
852
+
853
+ // Note: we also handle xOffset/yOffset mark properties here
854
+ const xOffset = (props.xOffset ?? 0) + pixelOffset;
855
+ const yOffset = (props.yOffset ?? 0) + pixelOffset;
856
+
857
+ /** @type {object} */
858
+ let uniforms;
859
+
860
+ let clippedCoords = coords;
861
+
862
+ if (props.clip !== "never" && (props.clip || clipRect)) {
863
+ let xClipOffset = 0;
864
+ let yClipOffset = 0;
865
+
866
+ /** @type {[number, number]} */
867
+ let uViewScale;
868
+
869
+ if (clipRect) {
870
+ clippedCoords = coords.intersect(clipRect).flatten();
871
+ if (!clippedCoords.isDefined()) {
872
+ return false;
873
+ }
874
+
875
+ uViewScale = [
876
+ coords.width / clippedCoords.width,
877
+ coords.height / clippedCoords.height,
878
+ ];
879
+
880
+ yClipOffset = Math.max(0, coords.y2 - clipRect.y2);
881
+ xClipOffset = Math.max(0, coords.x2 - clipRect.x2);
882
+ } else {
883
+ uViewScale = [1, 1];
884
+ }
885
+
886
+ const physicalGlCoords = [
887
+ clippedCoords.x,
888
+ logicalSize.height - clippedCoords.y2,
889
+ clippedCoords.width,
890
+ clippedCoords.height,
891
+ ].map((x) => x * dpr);
892
+
893
+ // Because glViewport accepts only integers, we subtract the rounding
894
+ // errors from xyOffsets to guarantee that graphics in clipped
895
+ // and non-clipped viewports align correctly
896
+ const roundedCoords = physicalGlCoords.map((x) => Math.round(x));
897
+ const [xError, yError] = physicalGlCoords.map(
898
+ (x, i) => x - roundedCoords[i]
899
+ );
900
+
901
+ // @ts-ignore
902
+ gl.viewport(...roundedCoords);
903
+ // @ts-ignore
904
+ gl.scissor(...roundedCoords);
905
+ gl.enable(gl.SCISSOR_TEST);
906
+
907
+ uniforms = {
908
+ uViewOffset: [
909
+ (xOffset + xClipOffset + xError / dpr) /
910
+ clippedCoords.width,
911
+ -(yOffset + yClipOffset - yError / dpr) /
912
+ clippedCoords.height,
913
+ ],
914
+ uViewScale,
915
+ };
916
+ } else {
917
+ if (!coords.isDefined()) {
918
+ return false;
919
+ }
920
+
921
+ // Viewport comprises the full canvas
922
+ gl.viewport(
923
+ 0,
924
+ 0,
925
+ logicalSize.width * dpr,
926
+ logicalSize.height * dpr
927
+ );
928
+ gl.disable(gl.SCISSOR_TEST);
929
+
930
+ // Offset and scale all drawing to the view rectangle
931
+ uniforms = {
932
+ uViewOffset: [
933
+ (coords.x + xOffset) / logicalSize.width,
934
+ (logicalSize.height - coords.y - yOffset - coords.height) /
935
+ logicalSize.height,
936
+ ],
937
+ uViewScale: [
938
+ coords.width / logicalSize.width,
939
+ coords.height / logicalSize.height,
940
+ ],
941
+ };
942
+ }
943
+
944
+ setBlockUniforms(this.viewUniformInfo, {
945
+ ...uniforms,
946
+ uViewportSize: [coords.width, coords.height],
947
+ uDevicePixelRatio: dpr,
948
+ });
949
+
950
+ setUniformBlock(this.gl, this.programInfo, this.viewUniformInfo);
951
+
952
+ return true;
953
+ }
954
+
955
+ /**
956
+ * Finds a datum that overlaps the given value on the x domain.
957
+ * The result is unspecified if multiple data are found.
958
+ *
959
+ * This is highly specific to SampleView and its sorting/filtering functionality.
960
+ *
961
+ * @param {string} facetId
962
+ * @param {import("../spec/channel").Scalar} x value on the x domain
963
+ * @returns {any}
964
+ */
965
+ findDatumAt(facetId, x) {
966
+ // override
967
+ }
968
+ }
969
+
970
+ /**
971
+ * @augments {InternMap<K, import("../gl/dataToVertices").RangeEntry>}
972
+ * @template K
973
+ */
974
+ class RangeMap extends InternMap {
975
+ constructor() {
976
+ super([], JSON.stringify);
977
+ }
978
+
979
+ /**
980
+ * @param {K} key
981
+ */
982
+ get(key) {
983
+ let value = super.get(key);
984
+ if (value === undefined) {
985
+ value = {
986
+ offset: 0,
987
+ count: 0,
988
+ xIndex: undefined,
989
+ };
990
+ super.set(key, value);
991
+ }
992
+ return value;
993
+ }
994
+
995
+ /**
996
+ *
997
+ * @param {Map<K, import("../gl/dataToVertices").RangeEntry>} anotherMap
998
+ */
999
+ migrateEntries(anotherMap) {
1000
+ for (const [key, value] of anotherMap.entries()) {
1001
+ Object.assign(this.get(key), value);
1002
+ }
1003
+ }
1004
+ }