@genome-spy/core 0.36.1 → 0.37.1

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 → bundle/index.es.js} +2253 -2115
  3. package/dist/{index.js → bundle/index.js} +180 -44
  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 +17 -12
  523. package/dist/style.css +0 -1
@@ -0,0 +1,691 @@
1
+ import {
2
+ parseSizeDef,
3
+ FlexDimensions,
4
+ ZERO_FLEXDIMENSIONS,
5
+ } from "../utils/layout/flexLayout";
6
+ import Padding from "../utils/layout/padding";
7
+ import {
8
+ getCachedOrCall,
9
+ initPropertyCache,
10
+ invalidatePrefix,
11
+ } from "../utils/propertyCacher";
12
+ import { isNumber, isString, span } from "vega-util";
13
+ import { scaleLog } from "d3-scale";
14
+ import { isFieldDef, getPrimaryChannel } from "../encoder/encoder";
15
+ import { appendToBaseUrl } from "../utils/url";
16
+ import { isDiscrete, bandSpace } from "vega-scale";
17
+ import { peek } from "../utils/arrayUtils";
18
+
19
+ // TODO: View classes have too many responsibilities. Come up with a way
20
+ // to separate the concerns. However, most concerns are tightly tied to
21
+ // the hierarchy, which makes the separation quite tricky.
22
+ // Separation of concerns would also make the code more easily testable.
23
+
24
+ /** Skip children */
25
+ export const VISIT_SKIP = "VISIT_SKIP";
26
+ /** Stop further visits */
27
+ export const VISIT_STOP = "VISIT_STOP";
28
+
29
+ /** @type {function(number):number} */
30
+ const defaultOpacityFunction = (parentOpacity) => parentOpacity;
31
+
32
+ /**
33
+ * @typedef {VISIT_SKIP|VISIT_STOP|void} VisitResult
34
+ *
35
+ * @callback VisitorCallback
36
+ * @param {View} view
37
+ * @returns {VisitResult}
38
+ *
39
+ * @typedef {VisitorCallback & {
40
+ * postOrder?: function(View):void,
41
+ * beforeChildren?: function(View):void,
42
+ * afterChildren?: function(View):void}
43
+ * } Visitor
44
+ *
45
+ * @typedef {object} BroadcastMessage
46
+ * @prop {import("../genomeSpy").BroadcastEventType} type Broadcast type
47
+ * @prop {any} [payload] Anything
48
+ *
49
+ * @callback InteractionEventListener
50
+ * @param {import("../utils/layout/rectangle").default} coords
51
+ * Coordinates of the view
52
+ * @param {import("../utils/interactionEvent").default} event
53
+ */
54
+ export default class View {
55
+ /** @type {Record<string, (function(BroadcastMessage):void)[]>} */
56
+ #broadcastHandlers = {};
57
+
58
+ /** @type {Record<string, InteractionEventListener[]>} */
59
+ #capturingInteractionEventListeners = {};
60
+
61
+ /** @type {Record<string, InteractionEventListener[]>} */
62
+ #nonCapturingInteractionEventListeners = {};
63
+
64
+ /**
65
+ * @type {function(number):number}
66
+ */
67
+ opacityFunction = defaultOpacityFunction;
68
+
69
+ /**
70
+ *
71
+ * @param {import("../spec/view").ViewSpec} spec
72
+ * @param {import("../types/viewContext").default} context
73
+ * @param {import("./containerView").default} layoutParent Parent that handles rendering of this view
74
+ * @param {import("./view").default} dataParent Parent that provides data, encodings, and is used in scale resolution
75
+ * @param {string} name
76
+ */
77
+ constructor(spec, context, layoutParent, dataParent, name) {
78
+ if (!spec) {
79
+ throw new Error("View spec must be defined!");
80
+ }
81
+
82
+ this.context = context;
83
+ this.layoutParent = layoutParent;
84
+ this.dataParent = dataParent;
85
+ this.name = spec.name || name;
86
+ this.spec = spec;
87
+
88
+ this.resolutions = {
89
+ /**
90
+ * Channel-specific scale resolutions
91
+ * @type {Partial<Record<import("../spec/channel").ChannelWithScale, import("./scaleResolution").default>>}
92
+ */
93
+ scale: {},
94
+ /**
95
+ * Channel-specific axis resolutions
96
+ * @type {Partial<Record<import("../spec/channel").PrimaryPositionalChannel, import("./axisResolution").default>>}
97
+ */
98
+ axis: {},
99
+ };
100
+
101
+ initPropertyCache(this);
102
+
103
+ /**
104
+ * Don't inherit encodings from parent.
105
+ * TODO: Make configurable through spec. Allow more fine-grained control.
106
+ */
107
+ this.blockEncodingInheritance = false;
108
+
109
+ /**
110
+ * Whether ScaleResolution should include this view or its children in the domain.
111
+ * This is mainly used to block axis views from contributing to the domain.
112
+ */
113
+ this.contributesToScaleDomain = true;
114
+
115
+ /**
116
+ * Whether GridView or equivalent should draw axis and grid lines for this view.
117
+ * @type {Record<import("../spec/channel").PrimaryPositionalChannel, boolean>}
118
+ */
119
+ this.needsAxes = { x: false, y: false };
120
+ }
121
+
122
+ getPadding() {
123
+ return this._cache("size/padding", () =>
124
+ Padding.createFromConfig(this.spec.padding)
125
+ );
126
+ }
127
+
128
+ /**
129
+ * Returns a padding that indicates how much axes and titles extend over the plot area.
130
+ *
131
+ * @returns {Padding}
132
+ */
133
+ getOverhang() {
134
+ return Padding.zero();
135
+ }
136
+
137
+ /**
138
+ * Returns the configured size, if present. Otherwise a computed or default
139
+ * height is returned.
140
+ *
141
+ * @returns {FlexDimensions}
142
+ */
143
+ getSize() {
144
+ return this._cache("size/size", () =>
145
+ this.isConfiguredVisible()
146
+ ? this.#getSizeFromSpec()
147
+ : ZERO_FLEXDIMENSIONS
148
+ );
149
+ }
150
+
151
+ /**
152
+ * @return {FlexDimensions}
153
+ */
154
+ #getSizeFromSpec() {
155
+ /**
156
+ * @param {"width" | "height"} dimension
157
+ * @return {import("../utils/layout/flexLayout").SizeDef}
158
+ */
159
+ const handleSize = (dimension) => {
160
+ let value = this.spec[dimension];
161
+
162
+ if (isStepSize(value)) {
163
+ const stepSize = value.step;
164
+
165
+ const scale = this.getScaleResolution(
166
+ dimension == "width" ? "x" : "y"
167
+ )?.getScale();
168
+
169
+ if (scale) {
170
+ // Note: this and all ancestral views need to be refreshed when the domain is changed.
171
+ let steps = 0;
172
+ if (isDiscrete(scale.type)) {
173
+ steps = scale.domain().length;
174
+ } else if (["locus", "index"].includes(scale.type)) {
175
+ const domain = scale.domain();
176
+ steps = peek(domain) - domain[0];
177
+ } else {
178
+ throw new Error(
179
+ `Cannot use step-based size with "${scale.type}" scale!`
180
+ );
181
+ }
182
+
183
+ // TODO: Type guards maybe?
184
+ const _scale =
185
+ /** @type {import("d3-scale").ScaleBand<any> | import("../genome/scaleLocus").ScaleLocus | import("../genome/scaleIndex").ScaleIndex} */ (
186
+ scale
187
+ );
188
+
189
+ steps = bandSpace(
190
+ steps,
191
+ _scale.paddingInner(),
192
+ _scale.paddingOuter()
193
+ );
194
+
195
+ return { px: steps * stepSize, grow: 0 };
196
+ } else {
197
+ throw new Error(
198
+ "Cannot use 'step' size with missing scale!"
199
+ );
200
+ }
201
+ } else {
202
+ return (value && parseSizeDef(value)) ?? { px: 0, grow: 1 };
203
+ }
204
+ };
205
+
206
+ return this._cache(
207
+ "size/sizeFromSpec",
208
+ () => new FlexDimensions(handleSize("width"), handleSize("height"))
209
+ );
210
+ }
211
+
212
+ isConfiguredVisible() {
213
+ return this.context.isViewConfiguredVisible(this);
214
+ }
215
+
216
+ isVisibleInSpec() {
217
+ return this.spec.visible ?? true;
218
+ }
219
+
220
+ /**
221
+ * Returns the effective visibility of this view, e.g., whether this view
222
+ * and all its ancestors are visible.
223
+ *
224
+ * When doing a depth-first traversal on the view hierarchy, it's best to
225
+ * use `isConfiguredVisible()` instead of this method.
226
+ *
227
+ * @returns {boolean}
228
+ */
229
+ isVisible() {
230
+ return this.getLayoutAncestors().every((view) =>
231
+ view.isConfiguredVisible()
232
+ );
233
+ }
234
+
235
+ /**
236
+ * Returns the effective opacity of this view, e.g., view's opacity multiplied
237
+ * by opacities of its ancestors.
238
+ *
239
+ * TODO: This methods makes sense only in Unit and Layer views.
240
+ *
241
+ * @returns {number}
242
+ */
243
+ getEffectiveOpacity() {
244
+ return this.opacityFunction(
245
+ this.layoutParent?.getEffectiveOpacity() ?? 1.0
246
+ );
247
+ }
248
+
249
+ getPathString() {
250
+ return this.getLayoutAncestors()
251
+ .map((v) => v.name)
252
+ .reverse()
253
+ .join("/");
254
+ }
255
+
256
+ /**
257
+ * @param {"dataParent" | "layoutParent"} prop
258
+ * @returns {View[]}
259
+ */
260
+ #getAncestors(prop) {
261
+ /** @type {View[]} */
262
+ const ancestors = [];
263
+ // eslint-disable-next-line consistent-this
264
+ let view = /** @type {View} */ (this);
265
+ do {
266
+ ancestors.push(view);
267
+ view = view[prop];
268
+ } while (view);
269
+ return ancestors;
270
+ }
271
+
272
+ /**
273
+ * Returns the ancestor views, starting with this view.
274
+ */
275
+ getLayoutAncestors() {
276
+ return this.#getAncestors("layoutParent");
277
+ }
278
+
279
+ /**
280
+ * Returns the ancestor views, starting with this view.
281
+ */
282
+ getDataAncestors() {
283
+ return this.#getAncestors("dataParent");
284
+ }
285
+
286
+ /**
287
+ * Handles a broadcast message that is intended for the whole view hierarchy.
288
+ *
289
+ * @param {BroadcastMessage} message
290
+ */
291
+ handleBroadcast(message) {
292
+ // TODO: message types should be constants
293
+ for (const handler of this.#broadcastHandlers[message.type] || []) {
294
+ handler(message);
295
+ }
296
+ }
297
+
298
+ /**
299
+ *
300
+ * @param {string} type
301
+ * @param {function(BroadcastMessage):void} handler
302
+ */
303
+ _addBroadcastHandler(type, handler) {
304
+ let handlers = this.#broadcastHandlers[type];
305
+ if (!handlers) {
306
+ handlers = [];
307
+ this.#broadcastHandlers[type] = handlers;
308
+ }
309
+ handlers.push(handler);
310
+ }
311
+
312
+ /**
313
+ * Handles an interactionEvent
314
+ *
315
+ * @param {import("../utils/layout/rectangle").default} coords
316
+ * Coordinates of the view
317
+ * @param {import("../utils/interactionEvent").default} event
318
+ * @param {boolean} capturing
319
+ */
320
+ handleInteractionEvent(coords, event, capturing) {
321
+ const listenersByType = capturing
322
+ ? this.#capturingInteractionEventListeners
323
+ : this.#nonCapturingInteractionEventListeners;
324
+ for (const listener of listenersByType[event.type] || []) {
325
+ listener(coords, event);
326
+ }
327
+ }
328
+
329
+ /**
330
+ * Add an "interaction" event listener that mimics DOM's event model inside
331
+ * the view hierarchy.
332
+ *
333
+ * This is intended for GenomeSpy's internal use. It allows the views to handle
334
+ * low level interactions such as dragging, wheeling, etc.
335
+ *
336
+ * @param {string} type
337
+ * @param {InteractionEventListener} listener
338
+ * @param {boolean} [useCapture]
339
+ */
340
+ addInteractionEventListener(type, listener, useCapture) {
341
+ const listenersByType = useCapture
342
+ ? this.#capturingInteractionEventListeners
343
+ : this.#nonCapturingInteractionEventListeners;
344
+ let listeners = listenersByType[type];
345
+ if (!listeners) {
346
+ listeners = [];
347
+ listenersByType[type] = listeners;
348
+ }
349
+
350
+ listeners.push(listener);
351
+ }
352
+
353
+ /**
354
+ * Visits child views in depth-first order. Visitor's return value
355
+ * controls the traversal.
356
+ *
357
+ * @param {Visitor} visitor
358
+ * @returns {VisitResult}
359
+ *
360
+ */
361
+ visit(visitor) {
362
+ try {
363
+ const result = visitor(this);
364
+
365
+ if (visitor.postOrder) {
366
+ visitor.postOrder(this);
367
+ }
368
+
369
+ if (result !== VISIT_STOP) {
370
+ return result;
371
+ }
372
+ } catch (e) {
373
+ // Augment the exception with the view
374
+ e.view = this;
375
+ throw e;
376
+ }
377
+ }
378
+
379
+ /**
380
+ * Get all descendants of this view in depth-first order.
381
+ */
382
+ getDescendants() {
383
+ /** @type {View[]} */
384
+ const descendants = [];
385
+ this.visit((view) => {
386
+ descendants.push(view);
387
+ });
388
+ return descendants;
389
+ }
390
+
391
+ /**
392
+ * Called after all scales in the view hierarchy have been resolved.
393
+ */
394
+ onScalesResolved() {
395
+ // Only set the opacity function once. The idea is to allow custom functions
396
+ // and prevent accidental overwrites.
397
+ if (
398
+ !this.opacityFunction ||
399
+ this.opacityFunction === defaultOpacityFunction
400
+ ) {
401
+ this.opacityFunction = createViewOpacityFunction(this);
402
+ }
403
+ }
404
+
405
+ /**
406
+ * ViewRenderingContext calls this method once for each view during each rendering
407
+ * pass. The order is depth first, pre order.
408
+ */
409
+ onBeforeRender() {
410
+ //
411
+ }
412
+
413
+ /**
414
+ * Recursively traverses the view hierarchy, computes the view coordinates,
415
+ * and coordinates the mark rendering.
416
+ *
417
+ * @type {import("../types/rendering").RenderMethod}
418
+ */
419
+ render(context, coords, options = {}) {
420
+ // override
421
+ }
422
+
423
+ /**
424
+ * Returns the encodings specified in this view combined with the inherited
425
+ * encodings. However, this does not contain any defaults or inferred/adjusted/fixed
426
+ * encodings. Those are available in Mark's encoding property.
427
+ *
428
+ * @return {import("../spec/channel").Encoding}
429
+ */
430
+ getEncoding() {
431
+ const pe =
432
+ this.dataParent && !this.blockEncodingInheritance
433
+ ? this.dataParent.getEncoding()
434
+ : {};
435
+ const te = this.spec.encoding || {};
436
+
437
+ /** @type {import("../spec/channel").Encoding} */
438
+ const combined = {
439
+ ...pe,
440
+ ...te,
441
+ };
442
+
443
+ for (const [channel, channelDef] of Object.entries(combined)) {
444
+ if (channelDef === null) {
445
+ // Prevent propagation
446
+ delete combined[channel];
447
+ }
448
+ }
449
+
450
+ return combined;
451
+ }
452
+
453
+ /**
454
+ * @param {View} [whoIsAsking] Passed to the immediate parent. Allows for
455
+ * selectively breaking the inheritance.
456
+ * @return {function(object):any}
457
+ */
458
+ getFacetAccessor(whoIsAsking) {
459
+ if (this.layoutParent) {
460
+ return this.layoutParent.getFacetAccessor(this);
461
+ }
462
+ }
463
+
464
+ /**
465
+ * Returns the fields that should be used for partitioning the data for facets.
466
+ *
467
+ * @param {View} [whoIsAsking]
468
+ * @returns {string[]}
469
+ */
470
+ getFacetFields(whoIsAsking) {
471
+ const sampleFieldDef = this.getEncoding().sample;
472
+ if (isFieldDef(sampleFieldDef)) {
473
+ return [sampleFieldDef.field];
474
+ } else {
475
+ return this.layoutParent?.getFacetFields(this);
476
+ }
477
+ }
478
+
479
+ /**
480
+ * Returns a texture that has a mapping for the sample locations. This is implemented
481
+ * only in the SampleView of GenomeSpy App.
482
+ *
483
+ * Background:
484
+ * There are to ways to manage how sample facets are drawn in the App:
485
+ *
486
+ * 1) Use one draw call for each facet and pass the location data as a uniform.
487
+ * 2) Draw all facets with one call and pass the facet locations as a texture.
488
+ *
489
+ * The former is suitable for large datasets, which can be subsetted for better
490
+ * performance. The latter one is more performant for cases where each facet
491
+ * consists of few data items (sample attributes / metadata).
492
+ *
493
+ * @return {WebGLTexture}
494
+ */
495
+ getSampleFacetTexture() {
496
+ return undefined;
497
+ }
498
+
499
+ /**
500
+ * @param {import("../spec/channel").ChannelWithScale} channel
501
+ */
502
+ getScaleResolution(channel) {
503
+ const primaryChannel =
504
+ /** @type {import("../spec/channel").ChannelWithScale} */ (
505
+ getPrimaryChannel(channel)
506
+ );
507
+
508
+ return this.getDataAncestors()
509
+ .map((view) => view.resolutions.scale[primaryChannel])
510
+ .find((resolution) => resolution);
511
+ }
512
+
513
+ /**
514
+ * @param {import("../spec/channel").PositionalChannel} channel
515
+ */
516
+ getAxisResolution(channel) {
517
+ const primaryChannel =
518
+ /** @type {import("../spec/channel").PrimaryPositionalChannel} */ (
519
+ getPrimaryChannel(channel)
520
+ );
521
+
522
+ return this.getDataAncestors()
523
+ .map((view) => view.resolutions.axis[primaryChannel])
524
+ .find((resolution) => resolution);
525
+ }
526
+
527
+ /**
528
+ * @param {import("../spec/channel").Channel | "default"} channel
529
+ * @param {import("../spec/view").ResolutionTarget} resolutionType
530
+ * @returns {import("../spec/view").ResolutionBehavior}
531
+ */
532
+ getConfiguredResolution(channel, resolutionType) {
533
+ return this.spec.resolve?.[resolutionType]?.[channel];
534
+ }
535
+
536
+ /**
537
+ * @param {import("../spec/channel").Channel} channel
538
+ * @param {import("../spec/view").ResolutionTarget} resolutionType
539
+ * @returns {import("../spec/view").ResolutionBehavior}
540
+ */
541
+ getConfiguredOrDefaultResolution(channel, resolutionType) {
542
+ return (
543
+ this.getConfiguredResolution(channel, resolutionType) ??
544
+ this.getConfiguredResolution("default", resolutionType) ??
545
+ this.getDefaultResolution(channel, resolutionType)
546
+ );
547
+ }
548
+
549
+ /**
550
+ * @param {import("../spec/channel").Channel} channel
551
+ * @param {import("../spec/view").ResolutionTarget} resolutionType
552
+ * @returns {import("../spec/view").ResolutionBehavior}
553
+ */
554
+ getDefaultResolution(channel, resolutionType) {
555
+ return "independent";
556
+ }
557
+
558
+ /**
559
+ * @returns {string}
560
+ */
561
+ getBaseUrl() {
562
+ return appendToBaseUrl(
563
+ () => this.dataParent?.getBaseUrl(),
564
+ this.spec.baseUrl
565
+ );
566
+ }
567
+
568
+ /**
569
+ * Returns `true` if this view and its children supports picking.
570
+ */
571
+ isPickingSupported() {
572
+ return true;
573
+ }
574
+
575
+ getTitleText() {
576
+ const title = this.spec.title;
577
+ if (title) {
578
+ return isString(title) ? title : title.text;
579
+ }
580
+ }
581
+
582
+ /**
583
+ * @param {any} key string
584
+ * @param {function(key?):T} callable A function that produces a value to be cached
585
+ * @returns {T}
586
+ * @template T
587
+ * @protected
588
+ */
589
+ _cache(key, callable) {
590
+ return getCachedOrCall(this, key, callable);
591
+ }
592
+
593
+ /**
594
+ *
595
+ * @param {string} key
596
+ * @param {"self" | "progeny" | "ancestors"} [direction]
597
+ */
598
+ _invalidateCacheByPrefix(key, direction = "self") {
599
+ switch (direction) {
600
+ case "self":
601
+ invalidatePrefix(this, key);
602
+ break;
603
+ case "ancestors":
604
+ for (const view of this.getLayoutAncestors()) {
605
+ invalidatePrefix(view, key);
606
+ }
607
+ break;
608
+ case "progeny":
609
+ this.visit((view) => invalidatePrefix(view, key));
610
+ break;
611
+ default:
612
+ }
613
+ }
614
+
615
+ invalidateSizeCache() {
616
+ this._invalidateCacheByPrefix("size/", "ancestors");
617
+ }
618
+
619
+ /**
620
+ * Broadcasts a message to views that include the given (x, y) point.
621
+ * This is mainly intended for mouse events.
622
+ *
623
+ * @param {import("../utils/interactionEvent").default} event
624
+ */
625
+ propagateInteractionEvent(event) {
626
+ // Subclasses must implement proper handling
627
+ }
628
+ }
629
+
630
+ /**
631
+ *
632
+ * @param {any} opacity
633
+ * @returns {opacity is import("../spec/view").DynamicOpacity}
634
+ */
635
+ function isDynamicOpacity(opacity) {
636
+ return "unitsPerPixel" in opacity;
637
+ }
638
+
639
+ /**
640
+ *
641
+ * @param {View} view
642
+ * @returns {function(number):number}
643
+ */
644
+ function createViewOpacityFunction(view) {
645
+ const opacityDef = view.spec.opacity;
646
+
647
+ if (opacityDef !== undefined) {
648
+ if (isNumber(opacityDef)) {
649
+ return (parentOpacity) => parentOpacity * opacityDef;
650
+ } else if (isDynamicOpacity(opacityDef)) {
651
+ /** @type {(channel: import("../spec/channel").ChannelWithScale) => any} */
652
+ const getScale = (channel) => {
653
+ const scale = view.getScaleResolution(channel)?.getScale();
654
+ // Only works on linear scales
655
+ if (["linear", "index", "locus"].includes(scale?.type)) {
656
+ return scale;
657
+ }
658
+ };
659
+
660
+ const scale = opacityDef.channel
661
+ ? getScale(opacityDef.channel)
662
+ : getScale("x") || getScale("y");
663
+
664
+ if (!scale) {
665
+ throw new Error(
666
+ "Cannot find a resolved quantitative scale for dynamic opacity!"
667
+ );
668
+ }
669
+
670
+ const interpolate = scaleLog()
671
+ .domain(opacityDef.unitsPerPixel)
672
+ .range(opacityDef.values)
673
+ .clamp(true);
674
+
675
+ return (parentOpacity) => {
676
+ const rangeSpan = 1000; //TODO: span(scale.range());
677
+ const unitsPerPixel = span(scale.domain()) / rangeSpan;
678
+
679
+ return interpolate(unitsPerPixel) * parentOpacity;
680
+ };
681
+ }
682
+ }
683
+ return (parentOpacity) => parentOpacity;
684
+ }
685
+
686
+ /**
687
+ *
688
+ * @param {any} size
689
+ * @return {size is import("../spec/view").Step}
690
+ */
691
+ export const isStepSize = (size) => !!size?.step;