@genome-spy/core 0.77.0 → 0.79.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 (317) hide show
  1. package/dist/bundle/{browser-KWU9rWZT.js → browser-CETrb2cm.js} +53 -33
  2. package/dist/bundle/esm-BdLYkz-m.js +248 -0
  3. package/dist/bundle/esm-BwiDsqSb.js +1367 -0
  4. package/dist/bundle/esm-CDFd1cjk.js +441 -0
  5. package/dist/bundle/{esm-CRMf_I9V.js → esm-CTUHLDbv.js} +30 -30
  6. package/dist/bundle/esm-Cx-EbkOj.js +1221 -0
  7. package/dist/bundle/esm-DlYGqi79.js +128 -0
  8. package/dist/bundle/{esm-BygJiwh0.js → esm-k9p3oHkt.js} +133 -158
  9. package/dist/bundle/{esm-CT3ygiMq.js → esm-zAZJQO6D.js} +226 -212
  10. package/dist/bundle/index.es.js +14102 -10810
  11. package/dist/bundle/index.js +109 -95
  12. package/dist/bundle/{parquetRead-DG_-F5j5.js → parquetRead-Cad1SOVV.js} +473 -399
  13. package/dist/schema.json +23788 -11049
  14. package/dist/src/config/axisConfig.d.ts +2 -2
  15. package/dist/src/config/axisConfig.d.ts.map +1 -1
  16. package/dist/src/config/axisConfig.js +28 -44
  17. package/dist/src/config/configLayers.d.ts +45 -0
  18. package/dist/src/config/configLayers.d.ts.map +1 -0
  19. package/dist/src/config/configLayers.js +110 -0
  20. package/dist/src/config/defaultConfig.d.ts.map +1 -1
  21. package/dist/src/config/defaultConfig.js +8 -1
  22. package/dist/src/config/defaults/legendDefaults.d.ts +14 -0
  23. package/dist/src/config/defaults/legendDefaults.d.ts.map +1 -0
  24. package/dist/src/config/defaults/legendDefaults.js +46 -0
  25. package/dist/src/config/defaults/titleDefaults.d.ts.map +1 -1
  26. package/dist/src/config/defaults/titleDefaults.js +26 -18
  27. package/dist/src/config/legendConfig.d.ts +11 -0
  28. package/dist/src/config/legendConfig.d.ts.map +1 -0
  29. package/dist/src/config/legendConfig.js +63 -0
  30. package/dist/src/config/styleUtils.d.ts +8 -2
  31. package/dist/src/config/styleUtils.d.ts.map +1 -1
  32. package/dist/src/config/styleUtils.js +25 -1
  33. package/dist/src/config/themes.d.ts.map +1 -1
  34. package/dist/src/config/themes.js +21 -2
  35. package/dist/src/config/titleConfig.d.ts.map +1 -1
  36. package/dist/src/config/titleConfig.js +2 -18
  37. package/dist/src/data/collector.d.ts.map +1 -1
  38. package/dist/src/data/collector.js +40 -18
  39. package/dist/src/data/flowInit.d.ts +6 -0
  40. package/dist/src/data/flowInit.d.ts.map +1 -1
  41. package/dist/src/data/flowInit.js +1 -1
  42. package/dist/src/data/flowNode.d.ts +32 -0
  43. package/dist/src/data/flowNode.d.ts.map +1 -1
  44. package/dist/src/data/flowNode.js +59 -0
  45. package/dist/src/data/sources/lazy/bamSource.d.ts +0 -1
  46. package/dist/src/data/sources/lazy/bamSource.d.ts.map +1 -1
  47. package/dist/src/data/sources/lazy/bamSource.js +39 -30
  48. package/dist/src/data/sources/lazy/bigBedSource.d.ts +0 -10
  49. package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
  50. package/dist/src/data/sources/lazy/bigBedSource.js +127 -62
  51. package/dist/src/data/sources/lazy/bigWigSource.d.ts +2 -2
  52. package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
  53. package/dist/src/data/sources/lazy/bigWigSource.js +234 -81
  54. package/dist/src/data/sources/lazy/gff3Source.d.ts +7 -3
  55. package/dist/src/data/sources/lazy/gff3Source.d.ts.map +1 -1
  56. package/dist/src/data/sources/lazy/gff3Source.js +7 -8
  57. package/dist/src/data/sources/lazy/indexedFastaSource.d.ts +1 -1
  58. package/dist/src/data/sources/lazy/indexedFastaSource.d.ts.map +1 -1
  59. package/dist/src/data/sources/lazy/indexedFastaSource.js +28 -19
  60. package/dist/src/data/sources/lazy/legendEntriesSource.d.ts +24 -0
  61. package/dist/src/data/sources/lazy/legendEntriesSource.d.ts.map +1 -0
  62. package/dist/src/data/sources/lazy/legendEntriesSource.js +217 -0
  63. package/dist/src/data/sources/lazy/legendGradientSource.d.ts +30 -0
  64. package/dist/src/data/sources/lazy/legendGradientSource.d.ts.map +1 -0
  65. package/dist/src/data/sources/lazy/legendGradientSource.js +388 -0
  66. package/dist/src/data/sources/lazy/mockLazySource.d.ts +4 -1
  67. package/dist/src/data/sources/lazy/mockLazySource.d.ts.map +1 -1
  68. package/dist/src/data/sources/lazy/mockLazySource.js +49 -4
  69. package/dist/src/data/sources/lazy/registerCoreLazySources.js +2 -0
  70. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
  71. package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +3 -4
  72. package/dist/src/data/sources/lazy/tabixSource.d.ts +9 -4
  73. package/dist/src/data/sources/lazy/tabixSource.d.ts.map +1 -1
  74. package/dist/src/data/sources/lazy/tabixSource.js +201 -70
  75. package/dist/src/data/sources/lazy/tabixTsvSource.d.ts +2 -3
  76. package/dist/src/data/sources/lazy/tabixTsvSource.d.ts.map +1 -1
  77. package/dist/src/data/sources/lazy/tabixTsvSource.js +14 -12
  78. package/dist/src/data/sources/lazy/vcfSource.d.ts +7 -3
  79. package/dist/src/data/sources/lazy/vcfSource.d.ts.map +1 -1
  80. package/dist/src/data/sources/lazy/vcfSource.js +7 -8
  81. package/dist/src/data/sources/urlDescriptor.d.ts +165 -0
  82. package/dist/src/data/sources/urlDescriptor.d.ts.map +1 -0
  83. package/dist/src/data/sources/urlDescriptor.js +473 -0
  84. package/dist/src/data/sources/urlDescriptorController.d.ts +25 -0
  85. package/dist/src/data/sources/urlDescriptorController.d.ts.map +1 -0
  86. package/dist/src/data/sources/urlDescriptorController.js +72 -0
  87. package/dist/src/data/sources/urlDescriptorState.d.ts +47 -0
  88. package/dist/src/data/sources/urlDescriptorState.d.ts.map +1 -0
  89. package/dist/src/data/sources/urlDescriptorState.js +129 -0
  90. package/dist/src/data/sources/urlSource.d.ts.map +1 -1
  91. package/dist/src/data/sources/urlSource.js +101 -61
  92. package/dist/src/data/transforms/packLegendLabels.d.ts +21 -0
  93. package/dist/src/data/transforms/packLegendLabels.d.ts.map +1 -0
  94. package/dist/src/data/transforms/packLegendLabels.js +189 -0
  95. package/dist/src/data/transforms/transformFactory.d.ts.map +1 -1
  96. package/dist/src/data/transforms/transformFactory.js +4 -0
  97. package/dist/src/data/transforms/truncateText.d.ts +27 -0
  98. package/dist/src/data/transforms/truncateText.d.ts.map +1 -0
  99. package/dist/src/data/transforms/truncateText.js +94 -0
  100. package/dist/src/debug/dataflowDebugSnapshot.d.ts +58 -0
  101. package/dist/src/debug/dataflowDebugSnapshot.d.ts.map +1 -0
  102. package/dist/src/debug/dataflowDebugSnapshot.js +159 -0
  103. package/dist/src/debug/markDebugSnapshot.d.ts +54 -0
  104. package/dist/src/debug/markDebugSnapshot.d.ts.map +1 -0
  105. package/dist/src/debug/markDebugSnapshot.js +100 -0
  106. package/dist/src/debug/paramDebugSnapshot.d.ts +53 -0
  107. package/dist/src/debug/paramDebugSnapshot.d.ts.map +1 -0
  108. package/dist/src/debug/paramDebugSnapshot.js +86 -0
  109. package/dist/src/debug/resolutionDebugSnapshot.d.ts +155 -0
  110. package/dist/src/debug/resolutionDebugSnapshot.d.ts.map +1 -0
  111. package/dist/src/debug/resolutionDebugSnapshot.js +291 -0
  112. package/dist/src/debug/valuePreview.d.ts +9 -0
  113. package/dist/src/debug/valuePreview.d.ts.map +1 -0
  114. package/dist/src/debug/valuePreview.js +57 -0
  115. package/dist/src/debug/viewDebugSnapshot.d.ts +131 -0
  116. package/dist/src/debug/viewDebugSnapshot.d.ts.map +1 -0
  117. package/dist/src/debug/viewDebugSnapshot.js +390 -0
  118. package/dist/src/embedFactory.d.ts.map +1 -1
  119. package/dist/src/embedFactory.js +6 -1
  120. package/dist/src/encoder/encoder.d.ts +2 -2
  121. package/dist/src/encoder/encoder.d.ts.map +1 -1
  122. package/dist/src/encoder/encoder.js +5 -4
  123. package/dist/src/fonts/bmFontManager.d.ts +1 -1
  124. package/dist/src/fonts/bmFontManager.d.ts.map +1 -1
  125. package/dist/src/fonts/bmFontManager.js +45 -10
  126. package/dist/src/fonts/textMetrics.d.ts +69 -0
  127. package/dist/src/fonts/textMetrics.d.ts.map +1 -0
  128. package/dist/src/fonts/textMetrics.js +73 -0
  129. package/dist/src/genomeSpy/headlessBootstrap.d.ts.map +1 -1
  130. package/dist/src/genomeSpy/headlessBootstrap.js +8 -0
  131. package/dist/src/genomeSpy/interactionController.d.ts +4 -1
  132. package/dist/src/genomeSpy/interactionController.d.ts.map +1 -1
  133. package/dist/src/genomeSpy/interactionController.js +57 -13
  134. package/dist/src/genomeSpy/renderCoordinator.d.ts.map +1 -1
  135. package/dist/src/genomeSpy/renderCoordinator.js +25 -3
  136. package/dist/src/genomeSpy/viewDataInit.d.ts +14 -0
  137. package/dist/src/genomeSpy/viewDataInit.d.ts.map +1 -1
  138. package/dist/src/genomeSpy/viewDataInit.js +45 -8
  139. package/dist/src/genomeSpyBase.d.ts +6 -0
  140. package/dist/src/genomeSpyBase.d.ts.map +1 -1
  141. package/dist/src/genomeSpyBase.js +25 -4
  142. package/dist/src/gl/glslScaleGenerator.d.ts +17 -0
  143. package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
  144. package/dist/src/gl/glslScaleGenerator.js +39 -2
  145. package/dist/src/gl/includes/common.glsl.js +1 -1
  146. package/dist/src/gl/vertexRangeIndex.d.ts.map +1 -1
  147. package/dist/src/gl/vertexRangeIndex.js +4 -2
  148. package/dist/src/gl/webGLHelper.d.ts +1 -1
  149. package/dist/src/gl/webGLHelper.d.ts.map +1 -1
  150. package/dist/src/gl/webGLHelper.js +13 -8
  151. package/dist/src/marks/__snapshots__/shaderSnapshot.test.js.snap +140 -3
  152. package/dist/src/marks/mark.d.ts +47 -4
  153. package/dist/src/marks/mark.d.ts.map +1 -1
  154. package/dist/src/marks/mark.js +158 -54
  155. package/dist/src/marks/point.d.ts.map +1 -1
  156. package/dist/src/marks/point.js +4 -0
  157. package/dist/src/marks/point.vertex.glsl.js +1 -1
  158. package/dist/src/marks/text.d.ts +1 -1
  159. package/dist/src/marks/text.d.ts.map +1 -1
  160. package/dist/src/marks/text.js +2 -7
  161. package/dist/src/marks/text.vertex.glsl.js +1 -1
  162. package/dist/src/paramRuntime/paramUtils.d.ts +43 -9
  163. package/dist/src/paramRuntime/paramUtils.d.ts.map +1 -1
  164. package/dist/src/paramRuntime/paramUtils.js +61 -1
  165. package/dist/src/paramRuntime/viewParamRuntime.d.ts +32 -0
  166. package/dist/src/paramRuntime/viewParamRuntime.d.ts.map +1 -1
  167. package/dist/src/paramRuntime/viewParamRuntime.js +63 -0
  168. package/dist/src/scales/axisResolution.d.ts +35 -0
  169. package/dist/src/scales/axisResolution.d.ts.map +1 -1
  170. package/dist/src/scales/axisResolution.js +115 -7
  171. package/dist/src/scales/domainExpressions.d.ts +21 -0
  172. package/dist/src/scales/domainExpressions.d.ts.map +1 -0
  173. package/dist/src/scales/domainExpressions.js +43 -0
  174. package/dist/src/scales/domainPlanner.d.ts +12 -1
  175. package/dist/src/scales/domainPlanner.d.ts.map +1 -1
  176. package/dist/src/scales/domainPlanner.js +55 -36
  177. package/dist/src/scales/legendResolution.d.ts +83 -0
  178. package/dist/src/scales/legendResolution.d.ts.map +1 -0
  179. package/dist/src/scales/legendResolution.js +461 -0
  180. package/dist/src/scales/scaleInstanceManager.d.ts +1 -0
  181. package/dist/src/scales/scaleInstanceManager.d.ts.map +1 -1
  182. package/dist/src/scales/scaleInstanceManager.js +5 -0
  183. package/dist/src/scales/scalePropsResolver.d.ts +6 -1
  184. package/dist/src/scales/scalePropsResolver.d.ts.map +1 -1
  185. package/dist/src/scales/scalePropsResolver.js +35 -10
  186. package/dist/src/scales/scaleResolution.d.ts +52 -0
  187. package/dist/src/scales/scaleResolution.d.ts.map +1 -1
  188. package/dist/src/scales/scaleResolution.js +195 -16
  189. package/dist/src/scales/scaleRules.d.ts +10 -0
  190. package/dist/src/scales/scaleRules.d.ts.map +1 -1
  191. package/dist/src/scales/scaleRules.js +38 -1
  192. package/dist/src/scales/viewLevelGuideConfig.d.ts +53 -0
  193. package/dist/src/scales/viewLevelGuideConfig.d.ts.map +1 -0
  194. package/dist/src/scales/viewLevelGuideConfig.js +224 -0
  195. package/dist/src/scales/viewLevelScaleConfig.d.ts +45 -0
  196. package/dist/src/scales/viewLevelScaleConfig.d.ts.map +1 -0
  197. package/dist/src/scales/viewLevelScaleConfig.js +149 -0
  198. package/dist/src/spec/axis.d.ts +109 -3
  199. package/dist/src/spec/channel.d.ts +23 -4
  200. package/dist/src/spec/config.d.ts +59 -4
  201. package/dist/src/spec/data.d.ts +177 -17
  202. package/dist/src/spec/legend.d.ts +246 -0
  203. package/dist/src/spec/mark.d.ts +16 -4
  204. package/dist/src/spec/scale.d.ts +19 -6
  205. package/dist/src/spec/title.d.ts +58 -1
  206. package/dist/src/spec/transform.d.ts +149 -0
  207. package/dist/src/spec/view.d.ts +50 -6
  208. package/dist/src/styles/genome-spy.css +4 -1
  209. package/dist/src/styles/genome-spy.css.d.ts +1 -1
  210. package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
  211. package/dist/src/styles/genome-spy.css.js +4 -1
  212. package/dist/src/types/embedApi.d.ts +262 -6
  213. package/dist/src/types/rendering.d.ts +19 -3
  214. package/dist/src/types/viewContext.d.ts +18 -2
  215. package/dist/src/utils/arrayUtils.d.ts +11 -0
  216. package/dist/src/utils/arrayUtils.d.ts.map +1 -1
  217. package/dist/src/utils/arrayUtils.js +23 -0
  218. package/dist/src/utils/suspension.d.ts +17 -0
  219. package/dist/src/utils/suspension.d.ts.map +1 -0
  220. package/dist/src/utils/suspension.js +41 -0
  221. package/dist/src/utils/ui/tooltip.d.ts +4 -0
  222. package/dist/src/utils/ui/tooltip.d.ts.map +1 -1
  223. package/dist/src/utils/ui/tooltip.js +35 -10
  224. package/dist/src/view/axisGridView.d.ts.map +1 -1
  225. package/dist/src/view/axisGridView.js +1 -4
  226. package/dist/src/view/axisView.d.ts +18 -2
  227. package/dist/src/view/axisView.d.ts.map +1 -1
  228. package/dist/src/view/axisView.js +180 -75
  229. package/dist/src/view/concatView.d.ts +10 -2
  230. package/dist/src/view/concatView.d.ts.map +1 -1
  231. package/dist/src/view/concatView.js +46 -9
  232. package/dist/src/view/containerMutationHelper.d.ts +20 -1
  233. package/dist/src/view/containerMutationHelper.d.ts.map +1 -1
  234. package/dist/src/view/containerMutationHelper.js +203 -32
  235. package/dist/src/view/facetView.d.ts +1 -1
  236. package/dist/src/view/gridView/gridChild.d.ts +54 -4
  237. package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
  238. package/dist/src/view/gridView/gridChild.js +301 -120
  239. package/dist/src/view/gridView/gridChildLegends.d.ts +57 -0
  240. package/dist/src/view/gridView/gridChildLegends.d.ts.map +1 -0
  241. package/dist/src/view/gridView/gridChildLegends.js +503 -0
  242. package/dist/src/view/gridView/gridView.d.ts +25 -0
  243. package/dist/src/view/gridView/gridView.d.ts.map +1 -1
  244. package/dist/src/view/gridView/gridView.js +454 -78
  245. package/dist/src/view/gridView/legendLayout.d.ts +26 -0
  246. package/dist/src/view/gridView/legendLayout.d.ts.map +1 -0
  247. package/dist/src/view/gridView/legendLayout.js +111 -0
  248. package/dist/src/view/gridView/scrollbar.d.ts.map +1 -1
  249. package/dist/src/view/gridView/scrollbar.js +1 -4
  250. package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
  251. package/dist/src/view/gridView/selectionRect.js +1 -4
  252. package/dist/src/view/gridView/separatorView.d.ts.map +1 -1
  253. package/dist/src/view/gridView/separatorView.js +1 -4
  254. package/dist/src/view/layerView.d.ts +9 -2
  255. package/dist/src/view/layerView.d.ts.map +1 -1
  256. package/dist/src/view/layerView.js +18 -1
  257. package/dist/src/view/layout/flexLayout.d.ts +20 -4
  258. package/dist/src/view/layout/flexLayout.d.ts.map +1 -1
  259. package/dist/src/view/layout/flexLayout.js +331 -31
  260. package/dist/src/view/layout/rectangle.d.ts +14 -0
  261. package/dist/src/view/layout/rectangle.d.ts.map +1 -1
  262. package/dist/src/view/layout/rectangle.js +40 -0
  263. package/dist/src/view/legend/legendEntries.d.ts +20 -0
  264. package/dist/src/view/legend/legendEntries.d.ts.map +1 -0
  265. package/dist/src/view/legend/legendEntries.js +21 -0
  266. package/dist/src/view/legendView.d.ts +134 -0
  267. package/dist/src/view/legendView.d.ts.map +1 -0
  268. package/dist/src/view/legendView.js +1611 -0
  269. package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts.map +1 -1
  270. package/dist/src/view/renderingContext/bufferedViewRenderingContext.js +26 -4
  271. package/dist/src/view/renderingContext/clipOptions.d.ts +44 -0
  272. package/dist/src/view/renderingContext/clipOptions.d.ts.map +1 -0
  273. package/dist/src/view/renderingContext/clipOptions.js +140 -0
  274. package/dist/src/view/renderingContext/simpleViewRenderingContext.d.ts.map +1 -1
  275. package/dist/src/view/renderingContext/simpleViewRenderingContext.js +12 -1
  276. package/dist/src/view/resolutionPlanner.d.ts +2 -1
  277. package/dist/src/view/resolutionPlanner.d.ts.map +1 -1
  278. package/dist/src/view/resolutionPlanner.js +89 -25
  279. package/dist/src/view/testUtils.d.ts +4 -2
  280. package/dist/src/view/testUtils.d.ts.map +1 -1
  281. package/dist/src/view/testUtils.js +29 -7
  282. package/dist/src/view/titleView.d.ts +37 -0
  283. package/dist/src/view/titleView.d.ts.map +1 -0
  284. package/dist/src/view/titleView.js +584 -0
  285. package/dist/src/view/unitView.d.ts +3 -3
  286. package/dist/src/view/unitView.d.ts.map +1 -1
  287. package/dist/src/view/unitView.js +3 -2
  288. package/dist/src/view/view.d.ts +25 -24
  289. package/dist/src/view/view.d.ts.map +1 -1
  290. package/dist/src/view/view.js +121 -16
  291. package/dist/src/view/viewFactory.d.ts +2 -5
  292. package/dist/src/view/viewFactory.d.ts.map +1 -1
  293. package/dist/src/view/viewFactory.js +1 -2
  294. package/dist/src/view/viewIdentityRegistry.d.ts +37 -0
  295. package/dist/src/view/viewIdentityRegistry.d.ts.map +1 -0
  296. package/dist/src/view/viewIdentityRegistry.js +71 -0
  297. package/dist/src/view/viewMutationAcidTestUtils.d.ts +112 -0
  298. package/dist/src/view/viewMutationAcidTestUtils.d.ts.map +1 -0
  299. package/dist/src/view/viewMutationAcidTestUtils.js +234 -0
  300. package/dist/src/view/viewMutationApi.d.ts +42 -0
  301. package/dist/src/view/viewMutationApi.d.ts.map +1 -0
  302. package/dist/src/view/viewMutationApi.js +811 -0
  303. package/dist/src/view/viewSelectors.d.ts +10 -0
  304. package/dist/src/view/viewSelectors.d.ts.map +1 -1
  305. package/dist/src/view/viewSelectors.js +23 -1
  306. package/package.json +4 -4
  307. package/dist/bundle/esm-0dYHNV_D.js +0 -121
  308. package/dist/bundle/esm-C49STiCR.js +0 -1248
  309. package/dist/bundle/esm-CscjKVDc.js +0 -1426
  310. package/dist/bundle/esm-CuMSzCHy.js +0 -298
  311. package/dist/bundle/esm-DMXpJXM4.js +0 -369
  312. package/dist/src/view/title.d.ts +0 -13
  313. package/dist/src/view/title.d.ts.map +0 -1
  314. package/dist/src/view/title.js +0 -154
  315. /package/dist/bundle/{AbortablePromiseCache-3gHJdF3E.js → AbortablePromiseCache-BTmAcN-t.js} +0 -0
  316. /package/dist/bundle/{esm-CuVa5T98.js → esm-VvpZ9hsq.js} +0 -0
  317. /package/dist/bundle/{chunk-DmhlhrBa.js → rolldown-runtime-Dy4uBu1J.js} +0 -0
@@ -9,7 +9,12 @@ import {
9
9
  getConfiguredNamedRange,
10
10
  isConfigRangeName,
11
11
  } from "../config/scaleConfig.js";
12
- import { applyLockedProperties, getDefaultScaleType } from "./scaleRules.js";
12
+ import { collectConfiguredDomainExprRefs } from "./domainExpressions.js";
13
+ import {
14
+ applyLockedProperties,
15
+ getDefaultScaleType,
16
+ validateScaleTypeCompatibility,
17
+ } from "./scaleRules.js";
13
18
  import { INDEX, LOCUS } from "./scaleResolutionConstants.js";
14
19
 
15
20
  /**
@@ -23,6 +28,7 @@ import { INDEX, LOCUS } from "./scaleResolutionConstants.js";
23
28
  * @param {Channel} options.channel
24
29
  * @param {import("../spec/channel.js").Type} options.dataType
25
30
  * @param {ScaleResolutionMember[]} options.orderedMembers
31
+ * @param {{ view: import("../view/view.js").default, config: Scale } | undefined} [options.viewLevelScaleConfig]
26
32
  * @param {boolean} options.isExplicitDomain
27
33
  * @param {import("../spec/config.js").GenomeSpyConfig[]} options.configScopes
28
34
  * @returns {Scale}
@@ -31,6 +37,7 @@ export function resolveScalePropsBase({
31
37
  channel,
32
38
  dataType,
33
39
  orderedMembers,
40
+ viewLevelScaleConfig,
34
41
  isExplicitDomain,
35
42
  configScopes,
36
43
  }) {
@@ -44,9 +51,11 @@ export function resolveScalePropsBase({
44
51
  )
45
52
  .filter((markType) => !!markType);
46
53
 
47
- const propArray = memberList
48
- .map((member) => member.channelDef.scale)
49
- .filter((props) => props !== undefined);
54
+ const propArray = viewLevelScaleConfig
55
+ ? [viewLevelScaleConfig.config]
56
+ : memberList
57
+ .map((member) => member.channelDef.scale)
58
+ .filter((props) => props !== undefined);
50
59
 
51
60
  // TODO: Disabled scale: https://vega.github.io/vega-lite/docs/scale.html#disable
52
61
  const mergedProps = mergeObjects(propArray, "scale", ["domain"]);
@@ -76,6 +85,13 @@ export function resolveScalePropsBase({
76
85
  props.type = getDefaultScaleType(channel, dataType);
77
86
  }
78
87
 
88
+ validateScaleTypeCompatibility(
89
+ channel,
90
+ dataType,
91
+ viewLevelScaleConfig ? props.type : undefined,
92
+ `View-level scales.${channel}.type`
93
+ );
94
+
79
95
  if (typeof props.range == "string") {
80
96
  if (!isConfigRangeName(props.range)) {
81
97
  throw new Error(
@@ -132,9 +148,15 @@ export function resolveScalePropsBase({
132
148
  }
133
149
 
134
150
  if (props.domainTransition === undefined) {
135
- const hasExprDrivenDomain = memberList.some((member) =>
136
- isExprRef(member.channelDef.scale?.domain)
137
- );
151
+ const hasExprDrivenDomain =
152
+ memberList.some(
153
+ (member) =>
154
+ collectConfiguredDomainExprRefs(
155
+ member.channelDef.scale?.domain
156
+ ).length > 0
157
+ ) ||
158
+ collectConfiguredDomainExprRefs(viewLevelScaleConfig?.config.domain)
159
+ .length > 0;
138
160
  props.domainTransition = !hasExprDrivenDomain;
139
161
  }
140
162
 
@@ -143,9 +165,12 @@ export function resolveScalePropsBase({
143
165
  props.range.some(isExprRef) &&
144
166
  memberList.length > 0
145
167
  ) {
146
- const rangeOwner = memberList.find(
147
- (member) => member.channelDef.scale?.range !== undefined
148
- )?.view;
168
+ const rangeOwner =
169
+ viewLevelScaleConfig?.config.range !== undefined
170
+ ? viewLevelScaleConfig.view
171
+ : memberList.find(
172
+ (member) => member.channelDef.scale?.range !== undefined
173
+ )?.view;
149
174
  if (rangeOwner) {
150
175
  /** @type {any} */
151
176
  (props).__rangeExprScope = rangeOwner;
@@ -68,6 +68,22 @@ export default class ScaleResolution implements ScaleResolutionApi {
68
68
  * @returns {() => boolean}
69
69
  */
70
70
  registerMember(member: ScaleResolutionMember): () => boolean;
71
+ /**
72
+ * @param {import("../view/view.js").default} view
73
+ * @param {import("../spec/scale.js").Scale} config
74
+ */
75
+ attachViewLevelScaleConfig(view: import("../view/view.js").default, config: import("../spec/scale.js").Scale): void;
76
+ /**
77
+ * @param {import("../view/view.js").default} view
78
+ */
79
+ clearViewLevelScaleConfig(view: import("../view/view.js").default): void;
80
+ /**
81
+ * @returns {{ view: import("../view/view.js").default, config: import("../spec/scale.js").Scale } | undefined}
82
+ */
83
+ getViewLevelScaleConfig(): {
84
+ view: import("../view/view.js").default;
85
+ config: import("../spec/scale.js").Scale;
86
+ } | undefined;
71
87
  dispose(): void;
72
88
  /**
73
89
  * @param {import("../data/collector.js").default} collector
@@ -80,6 +96,39 @@ export default class ScaleResolution implements ScaleResolutionApi {
80
96
  */
81
97
  isDomainDefinedExplicitly(): boolean;
82
98
  isDomainInitialized(): boolean;
99
+ /**
100
+ * Returns the participating members in the same deterministic order used
101
+ * for scale property merging.
102
+ *
103
+ * @returns {ScaleResolutionMember[]}
104
+ */
105
+ getOrderedMembers(): ScaleResolutionMember[];
106
+ getDebugState(): {
107
+ kind: string;
108
+ channel: import("../spec/channel.js").Channel;
109
+ hostView: import("../view/view.js").default<import("../spec/view.js").ViewSpec>;
110
+ name: string;
111
+ type: import("../spec/channel.js").Type;
112
+ resolvedScaleType: import("../spec/scale.js").ScaleType;
113
+ domain: any[];
114
+ complexDomain: import("../spec/scale.js").NumericDomain | import("../spec/scale.js").ComplexDomain;
115
+ range: any[];
116
+ zoomable: boolean;
117
+ zoomed: boolean;
118
+ members: {
119
+ view: import("../view/unitView.js").default<import("../spec/view.js").UnitSpec>;
120
+ channel: import("../spec/channel.js").ChannelWithScale;
121
+ channelDef: import("../spec/channel.js").ChannelDefWithScale;
122
+ contributesToDomain: boolean;
123
+ active: boolean;
124
+ }[];
125
+ activeMemberCount: number;
126
+ dataDomainMemberCount: number;
127
+ viewLevelScaleConfig: {
128
+ view: import("../view/view.js").default<import("../spec/view.js").ViewSpec>;
129
+ config: import("../spec/scale.js").Scale;
130
+ };
131
+ };
83
132
  /**
84
133
  * Returns locus assembly requirements without initializing the scale.
85
134
  *
@@ -129,6 +178,9 @@ export default class ScaleResolution implements ScaleResolutionApi {
129
178
  * Returns the scale instance, creating it if needed.
130
179
  *
131
180
  * Use this from call sites that may run before explicit initialization.
181
+ * Creating the scale resolves default domains and may require loaded
182
+ * assemblies for locus scales. For side-effect-free type checks, use
183
+ * `getResolvedScaleType()`.
132
184
  *
133
185
  * @returns {ScaleWithProps}
134
186
  */
@@ -1 +1 @@
1
- {"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleResolution.js"],"names":[],"mappings":"AAoDA;;;;;;;;GAQG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH;IA8cI;;;;;;;;OAQG;IACH,uBALa,CAAC,eACH,QAAQ,CAAC,eAAe,CAAC,YACzB,MAAM,CAAC,GACL,CAAC,CAqBb;IAnaD;;;OAGG;IACH,sEAFW,OAAO,iBAAiB,EAAE,OAAO,EAuC3C;IApCG,8CAAsB;IACtB,0FAA0F;IAC1F,MADW,OAAO,oBAAoB,EAAE,IAAI,CAC5B;IAEhB,iEAAiE;IACjE,MADW,MAAM,CACI;IA2EzB,2BASC;IAwBD;;;;;;;OAOG;IACH,4KAEC;IAED;;;OAGG;IACH,+KAEC;IAiCD,sCA6CC;IA+MD;;;OAGG;IACH,uBAHW,qBAAqB,GACnB,MAAM,OAAO,CAazB;IAED,gBAMC;IAoFD;;;;OAIG;IACH,0CAJW,OAAO,sBAAsB,EAAE,OAAO,aACtC,QAAQ,CAAC,OAAO,qBAAqB,EAAE,aAAa,CAAC,GACnD,MAAM,IAAI,CAkCtB;IAED;;OAEG;IACH,qCAEC;IAED,+BAiBC;IAuED;;;;;;;;;;;OAWG;IACH,0BALa;QACR,QAAQ,EAAE,OAAO,kBAAkB,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;QACnE,oBAAoB,EAAE,OAAO,CAAA;KAC9B,CAeH;IAED;;;;;;;OAOG;IACH,wBAFa,OAAO,kBAAkB,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAShE;IAgGD;;;;;OAKG;IACH,oBAYC;IAED;;;;;OAKG;IACH,0BA0BC;IAoID;;OAEG;IACH;eAnhCkC,OAAO,kBAAkB,EAAE,KAAK;MA0hCjE;IAED;;;;;;OAMG;IACH;eAniCkC,OAAO,kBAAkB,EAAE,KAAK;MA0iCjE;IAED;;;;OAIG;IACH;eAjjCkC,OAAO,kBAAkB,EAAE,KAAK;MA0jCjE;IAED,mBASC;IAED;;;;OAIG;IACH,+DAEC;IAED;;OAEG;IACH,oBAFa,mFAA6B,CASzC;IAED;;OAEG;IACH;;;;MAqBC;IAED;;;;OAIG;IACH,oBAEC;IAED;;OAEG;IACH,sBASC;IAED;;;;;;;OAOG;IACH,kBALW,MAAM,eACN,MAAM,OACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;;;OAMG;IACH,eAJW,mFAA6B,YAC7B,OAAO,gCAAgC,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,iBAKnF;IAED;;;;OAIG;IACH,qBAEC;IAED;;;;;OAKG;IACH,uBAEC;IAED;;;;;;;OAOG;IACH,wBAoBC;IAED;;;;;OAKG;IACH,uBAFW,MAAM,yDAUhB;IAED;;OAEG;IACH,iBAFW,MAAM,yDAIhB;IAED;;;OAGG;IACH,qBAHW,MAAM,+CAAmB,GACvB,MAAM,CAIlB;IAED;;;OAGG;IACH,8BAHW,kFAA4B,GAC1B,MAAM,EAAE,CAOpB;;CACJ;kCAxyC+B,CAAC,SAApB,6CAAkB;;;;UAGrB,OAAO,qBAAqB,EAAE,OAAO;aACrC,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB;yBAChD,OAAO;;sBApCV,+BAA+B;sBAA/B,+BAA+B;wBAA/B,+BAA+B;wBAA/B,+BAA+B;6BAA/B,+BAA+B"}
1
+ {"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleResolution.js"],"names":[],"mappings":"AAkDA;;;;;;;;GAQG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH;IAwdI;;;;;;;;OAQG;IACH,uBALa,CAAC,eACH,QAAQ,CAAC,eAAe,CAAC,YACzB,MAAM,CAAC,GACL,CAAC,CAqBb;IAxaD;;;OAGG;IACH,sEAFW,OAAO,iBAAiB,EAAE,OAAO,EAyC3C;IAtCG,8CAAsB;IACtB,0FAA0F;IAC1F,MADW,OAAO,oBAAoB,EAAE,IAAI,CAC5B;IAEhB,iEAAiE;IACjE,MADW,MAAM,CACI;IA6EzB,2BASC;IAwBD;;;;;;;OAOG;IACH,4KAEC;IAED;;;OAGG;IACH,+KAEC;IAiCD,sCA6CC;IAkND;;;OAGG;IACH,uBAHW,qBAAqB,GACnB,MAAM,OAAO,CAazB;IAED;;;OAGG;IACH,iCAHW,OAAO,iBAAiB,EAAE,OAAO,UACjC,OAAO,kBAAkB,EAAE,KAAK,QAyB1C;IAED;;OAEG;IACH,gCAFW,OAAO,iBAAiB,EAAE,OAAO,QAc3C;IAED;;OAEG;IACH,2BAFa;QAAE,IAAI,EAAE,OAAO,iBAAiB,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,kBAAkB,EAAE,KAAK,CAAA;KAAE,GAAG,SAAS,CAI7G;IA2CD,gBAMC;IAqGD;;;;OAIG;IACH,0CAJW,OAAO,sBAAsB,EAAE,OAAO,aACtC,QAAQ,CAAC,OAAO,qBAAqB,EAAE,aAAa,CAAC,GACnD,MAAM,IAAI,CAkCtB;IAED;;OAEG;IACH,qCAEC;IAED,+BAiBC;IA+CD;;;;;OAKG;IACH,qBAFa,qBAAqB,EAAE,CAInC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;MA+BC;IAwCD;;;;;;;;;;;OAWG;IACH,0BALa;QACR,QAAQ,EAAE,OAAO,kBAAkB,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;QACnE,oBAAoB,EAAE,OAAO,CAAA;KAC9B,CAeH;IAED;;;;;;;OAOG;IACH,wBAFa,OAAO,kBAAkB,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAShE;IAgGD;;;;;OAKG;IACH,oBAYC;IAED;;;;;OAKG;IACH,0BA0BC;IAoID;;OAEG;IACH;eArsCkC,OAAO,kBAAkB,EAAE,KAAK;MA4sCjE;IAED;;;;;;;;;OASG;IACH;eAxtCkC,OAAO,kBAAkB,EAAE,KAAK;MA+tCjE;IAED;;;;OAIG;IACH;eAtuCkC,OAAO,kBAAkB,EAAE,KAAK;MA+uCjE;IAED,mBASC;IAED;;;;OAIG;IACH,+DAEC;IAED;;OAEG;IACH,oBAFa,mFAA6B,CASzC;IAED;;OAEG;IACH;;;;MAqBC;IAED;;;;OAIG;IACH,oBAEC;IAED;;OAEG;IACH,sBASC;IAED;;;;;;;OAOG;IACH,kBALW,MAAM,eACN,MAAM,OACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;;;OAMG;IACH,eAJW,mFAA6B,YAC7B,OAAO,gCAAgC,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,iBAKnF;IAED;;;;OAIG;IACH,qBAEC;IAED;;;;;OAKG;IACH,uBAEC;IAED;;;;;;;OAOG;IACH,wBAoBC;IAED;;;;;OAKG;IACH,uBAFW,MAAM,yDAUhB;IAED;;OAEG;IACH,iBAFW,MAAM,yDAIhB;IAED;;;OAGG;IACH,qBAHW,MAAM,+CAAmB,GACvB,MAAM,CAIlB;IAED;;;OAGG;IACH,8BAHW,kFAA4B,GAC1B,MAAM,EAAE,CAOpB;;CACJ;kCA79C+B,CAAC,SAApB,6CAAkB;;;;UAGrB,OAAO,qBAAqB,EAAE,OAAO;aACrC,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB;yBAChD,OAAO;;sBAjCV,+BAA+B;sBAA/B,+BAA+B;wBAA/B,+BAA+B;wBAA/B,+BAA+B;6BAA/B,+BAA+B"}
@@ -15,6 +15,7 @@ import ScaleInstanceManager from "./scaleInstanceManager.js";
15
15
  import { resolveScalePropsBase } from "./scalePropsResolver.js";
16
16
  import DomainPlanner from "./domainPlanner.js";
17
17
  import ScaleInteractionController from "./scaleInteractionController.js";
18
+ import { validateScaleTypeCompatibility } from "./scaleRules.js";
18
19
  import {
19
20
  INDEX,
20
21
  LOCUS,
@@ -24,11 +25,8 @@ import {
24
25
  } from "./scaleResolutionConstants.js";
25
26
 
26
27
  import { getAccessorDomainKey } from "../encoder/accessor.js";
27
- import {
28
- isPrimaryPositionalChannel,
29
- isSecondaryChannel,
30
- } from "../encoder/encoder.js";
31
- import { isExprRef } from "../paramRuntime/paramUtils.js";
28
+ import { isSecondaryChannel } from "../encoder/encoder.js";
29
+ import { collectConfiguredDomainExprRefs } from "./domainExpressions.js";
32
30
  import { NominalDomain } from "../utils/domainArray.js";
33
31
  import { shallowArrayEquals } from "../utils/arrayUtils.js";
34
32
  import createIndexer from "../utils/indexer.js";
@@ -143,6 +141,11 @@ export default class ScaleResolution {
143
141
  /** @type {import("../view/view.js").default | undefined} */
144
142
  #hostView;
145
143
 
144
+ /**
145
+ * @type {{ view: import("../view/view.js").default, config: import("../spec/scale.js").Scale } | undefined}
146
+ */
147
+ #viewLevelScaleConfig;
148
+
146
149
  #resolvingScaleProps = 0;
147
150
 
148
151
  #memberRegistrationBatchDepth = 0;
@@ -168,6 +171,8 @@ export default class ScaleResolution {
168
171
  getAllMembers: () => this.#members,
169
172
  getDataMembers: () =>
170
173
  this.#getActiveMembers(this.#dataDomainMembers),
174
+ getViewLevelConfiguredDomain: () =>
175
+ this.#getViewLevelConfiguredDomain(),
171
176
  getType: () => this.type,
172
177
  getLocusExtent: (assembly) => this.#getLocusExtent(assembly),
173
178
  fromComplexInterval: this.fromComplexInterval.bind(this),
@@ -400,6 +405,10 @@ export default class ScaleResolution {
400
405
  * @returns {boolean}
401
406
  */
402
407
  #hasConfiguredDomain() {
408
+ if (this.#viewLevelScaleConfig?.config.domain !== undefined) {
409
+ return true;
410
+ }
411
+
403
412
  for (const member of this.#members) {
404
413
  if (
405
414
  member.contributesToDomain &&
@@ -452,6 +461,8 @@ export default class ScaleResolution {
452
461
  const member = normalizeMember(newMember);
453
462
  const { channel, channelDef } = member;
454
463
 
464
+ this.#assertCanRegisterMember(member);
465
+
455
466
  // A convenience hack for cases where the new member should adapt
456
467
  // the scale type to the existing one. For example: SelectionRect
457
468
  // TODO: Add test
@@ -481,15 +492,12 @@ export default class ScaleResolution {
481
492
  explicitScaleType ??
482
493
  (type === INDEX || type === LOCUS ? type : undefined);
483
494
 
484
- if (
485
- effectiveScaleType &&
486
- [INDEX, LOCUS].includes(effectiveScaleType) &&
487
- !isPrimaryPositionalChannel(this.channel)
488
- ) {
489
- throw new Error(
490
- `Index and locus scales are only supported on positional channels (x/y). Channel "${this.channel}" resolves to scale type "${effectiveScaleType}".`
491
- );
492
- }
495
+ validateScaleTypeCompatibility(
496
+ this.channel,
497
+ type,
498
+ effectiveScaleType,
499
+ `encoding.${channel}.scale.type`
500
+ );
493
501
 
494
502
  if (name) {
495
503
  if (this.name !== undefined && name != this.name) {
@@ -587,6 +595,100 @@ export default class ScaleResolution {
587
595
  };
588
596
  }
589
597
 
598
+ /**
599
+ * @param {import("../view/view.js").default} view
600
+ * @param {import("../spec/scale.js").Scale} config
601
+ */
602
+ attachViewLevelScaleConfig(view, config) {
603
+ if (
604
+ this.#viewLevelScaleConfig &&
605
+ this.#viewLevelScaleConfig.view !== view
606
+ ) {
607
+ throw new Error(
608
+ `Multiple view-level scale configs target the same ${this.channel} scale resolution.`
609
+ );
610
+ }
611
+
612
+ for (const member of this.#members) {
613
+ this.#assertMemberHasNoScaleConfig(member);
614
+ }
615
+
616
+ this.#viewLevelScaleConfig = { view, config };
617
+ this.#invalidateMergedScaleProps();
618
+ this.#invalidateConfiguredDomain();
619
+ this.#refreshSelectionDomainParamSubscriptions();
620
+ this.#refreshConfiguredDomainExprSubscriptions();
621
+ if (this.#scaleManager.scale) {
622
+ this.#scaleManager.resetScale();
623
+ this.initializeScale();
624
+ }
625
+ }
626
+
627
+ /**
628
+ * @param {import("../view/view.js").default} view
629
+ */
630
+ clearViewLevelScaleConfig(view) {
631
+ if (this.#viewLevelScaleConfig?.view === view) {
632
+ this.#viewLevelScaleConfig = undefined;
633
+ this.#invalidateMergedScaleProps();
634
+ this.#invalidateConfiguredDomain();
635
+ this.#refreshSelectionDomainParamSubscriptions();
636
+ this.#refreshConfiguredDomainExprSubscriptions();
637
+ if (this.#scaleManager.scale) {
638
+ this.#scaleManager.resetScale();
639
+ this.initializeScale();
640
+ }
641
+ }
642
+ }
643
+
644
+ /**
645
+ * @returns {{ view: import("../view/view.js").default, config: import("../spec/scale.js").Scale } | undefined}
646
+ */
647
+ getViewLevelScaleConfig() {
648
+ return this.#viewLevelScaleConfig;
649
+ }
650
+
651
+ #getViewLevelConfiguredDomain() {
652
+ const viewLevelScaleConfig = this.#viewLevelScaleConfig;
653
+ if (!viewLevelScaleConfig) {
654
+ return undefined;
655
+ }
656
+
657
+ return {
658
+ view: viewLevelScaleConfig.view,
659
+ channel:
660
+ /** @type {import("../spec/channel.js").ChannelWithScale} */ (
661
+ this.channel
662
+ ),
663
+ type: this.type,
664
+ domain: viewLevelScaleConfig.config.domain,
665
+ };
666
+ }
667
+
668
+ /**
669
+ * @param {ScaleResolutionMember} member
670
+ */
671
+ #assertCanRegisterMember(member) {
672
+ if (!this.#viewLevelScaleConfig) {
673
+ return;
674
+ }
675
+
676
+ this.#assertMemberHasNoScaleConfig(member);
677
+ }
678
+
679
+ /**
680
+ * @param {ScaleResolutionMember} member
681
+ */
682
+ #assertMemberHasNoScaleConfig(member) {
683
+ if (member.channelDef.scale === undefined) {
684
+ return;
685
+ }
686
+
687
+ throw new Error(
688
+ `Cannot mix view-level scales.${this.channel} with encoding.${member.channel}.scale in the same scale resolution.`
689
+ );
690
+ }
691
+
590
692
  dispose() {
591
693
  this.#clearSelectionDomainParamSubscriptions();
592
694
  this.#clearConfiguredDomainExprSubscriptions();
@@ -658,11 +760,28 @@ export default class ScaleResolution {
658
760
  continue;
659
761
  }
660
762
  const domain = member.channelDef.scale?.domain;
661
- if (!isExprRef(domain)) {
763
+ const exprRefs = collectConfiguredDomainExprRefs(domain);
764
+ if (exprRefs.length === 0) {
662
765
  continue;
663
766
  }
664
767
 
665
- const expr = member.view.paramRuntime.createExpression(domain.expr);
768
+ for (const exprRef of exprRefs) {
769
+ const expr = member.view.paramRuntime.createExpression(
770
+ exprRef.expr
771
+ );
772
+ const unsubscribe = expr.subscribe(listener);
773
+ this.#configuredDomainExprUnsubscribers.push(unsubscribe);
774
+ }
775
+ }
776
+
777
+ const viewLevelDomain = this.#viewLevelScaleConfig?.config.domain;
778
+ const viewLevelExprRefs =
779
+ collectConfiguredDomainExprRefs(viewLevelDomain);
780
+ for (const exprRef of viewLevelExprRefs) {
781
+ const expr =
782
+ this.#viewLevelScaleConfig.view.paramRuntime.createExpression(
783
+ exprRef.expr
784
+ );
666
785
  const unsubscribe = expr.subscribe(listener);
667
786
  this.#configuredDomainExprUnsubscribers.push(unsubscribe);
668
787
  }
@@ -754,6 +873,7 @@ export default class ScaleResolution {
754
873
  channel: this.channel,
755
874
  dataType: this.type,
756
875
  orderedMembers: this.#getOrderedMembers(),
876
+ viewLevelScaleConfig: this.#viewLevelScaleConfig,
757
877
  isExplicitDomain: this.isDomainDefinedExplicitly(),
758
878
  configScopes: this.#resolutionView.getConfigScopes(),
759
879
  });
@@ -786,6 +906,62 @@ export default class ScaleResolution {
786
906
  return this.#orderedMembers;
787
907
  }
788
908
 
909
+ /**
910
+ * Returns the participating members in the same deterministic order used
911
+ * for scale property merging.
912
+ *
913
+ * @returns {ScaleResolutionMember[]}
914
+ */
915
+ getOrderedMembers() {
916
+ return this.#getOrderedMembers().slice();
917
+ }
918
+
919
+ getDebugState() {
920
+ const scale = this.#scaleManager.scale;
921
+ const canReadDomain = scale && typeof scale.domain === "function";
922
+ const canReadRange = scale && typeof scale.range === "function";
923
+
924
+ return {
925
+ kind: "scale",
926
+ channel: this.channel,
927
+ hostView: this.#resolutionView,
928
+ name: this.name,
929
+ type: this.type,
930
+ resolvedScaleType: this.getResolvedScaleType(),
931
+ domain: canReadDomain ? this.getDomain() : undefined,
932
+ complexDomain: canReadDomain ? this.getComplexDomain() : undefined,
933
+ range: canReadRange ? scale.range() : undefined,
934
+ zoomable: this.isZoomable(),
935
+ zoomed: this.isZoomable() ? this.isZoomed() : false,
936
+ members: this.#getOrderedMembers().map((member) =>
937
+ this.#createDebugMember(member)
938
+ ),
939
+ activeMemberCount: this.#getActiveMembers().size,
940
+ dataDomainMemberCount: this.#dataDomainMembers.size,
941
+ viewLevelScaleConfig: this.#viewLevelScaleConfig
942
+ ? {
943
+ view: this.#viewLevelScaleConfig.view,
944
+ config: structuredClone(
945
+ this.#viewLevelScaleConfig.config
946
+ ),
947
+ }
948
+ : undefined,
949
+ };
950
+ }
951
+
952
+ /**
953
+ * @param {ScaleResolutionMember} member
954
+ */
955
+ #createDebugMember(member) {
956
+ return {
957
+ view: member.view,
958
+ channel: member.channel,
959
+ channelDef: structuredClone(member.channelDef),
960
+ contributesToDomain: member.contributesToDomain,
961
+ active: this.#getActiveMembers().has(member),
962
+ };
963
+ }
964
+
789
965
  #invalidateConfiguredDomain() {
790
966
  this.#domainAggregator.invalidateConfiguredDomain();
791
967
  this.#invalidateMergedScaleProps();
@@ -1149,6 +1325,9 @@ export default class ScaleResolution {
1149
1325
  * Returns the scale instance, creating it if needed.
1150
1326
  *
1151
1327
  * Use this from call sites that may run before explicit initialization.
1328
+ * Creating the scale resolves default domains and may require loaded
1329
+ * assemblies for locus scales. For side-effect-free type checks, use
1330
+ * `getResolvedScaleType()`.
1152
1331
  *
1153
1332
  * @returns {ScaleWithProps}
1154
1333
  */
@@ -7,6 +7,16 @@
7
7
  * @returns {import("../spec/scale.js").ScaleType}
8
8
  */
9
9
  export function getDefaultScaleType(channel: Channel, dataType: import("../spec/channel.js").Type): import("../spec/scale.js").ScaleType;
10
+ /**
11
+ * Validates explicit scale type choices against the resolved data type and
12
+ * channel constraints.
13
+ *
14
+ * @param {Channel} channel
15
+ * @param {import("../spec/channel.js").Type} dataType
16
+ * @param {import("../spec/scale.js").ScaleType | undefined} scaleType
17
+ * @param {string} source
18
+ */
19
+ export function validateScaleTypeCompatibility(channel: Channel, dataType: import("../spec/channel.js").Type, scaleType: import("../spec/scale.js").ScaleType | undefined, source: string): void;
10
20
  /**
11
21
  * @param {import("../spec/scale.js").Scale} props
12
22
  * @param {Channel} channel
@@ -1 +1 @@
1
- {"version":3,"file":"scaleRules.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleRules.js"],"names":[],"mappings":"AAcA;;GAEG;AAEH;;;;GAIG;AACH,6CAJW,OAAO,YACP,OAAO,oBAAoB,EAAE,IAAI,GAC/B,OAAO,kBAAkB,EAAE,SAAS,CA2EhD;AAED;;;GAGG;AACH,6CAHW,OAAO,kBAAkB,EAAE,KAAK,WAChC,OAAO,QAgBjB;sBArGY,OAAO,oBAAoB,EAAE,OAAO"}
1
+ {"version":3,"file":"scaleRules.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleRules.js"],"names":[],"mappings":"AAcA;;GAEG;AAEH;;;;GAIG;AACH,6CAJW,OAAO,YACP,OAAO,oBAAoB,EAAE,IAAI,GAC/B,OAAO,kBAAkB,EAAE,SAAS,CA0EhD;AAED;;;;;;;;GAQG;AACH,wDALW,OAAO,YACP,OAAO,oBAAoB,EAAE,IAAI,aACjC,OAAO,kBAAkB,EAAE,SAAS,GAAG,SAAS,UAChD,MAAM,QA6BhB;AAED;;;GAGG;AACH,6CAHW,OAAO,kBAAkB,EAAE,KAAK,WAChC,OAAO,QAgBjB;sBA1IY,OAAO,oBAAoB,EAAE,OAAO"}
@@ -37,7 +37,6 @@ export function getDefaultScaleType(channel, dataType) {
37
37
  if (isPrimaryPositionalChannel(channel)) {
38
38
  return dataType;
39
39
  } else {
40
- // TODO: Also explicitly set scales should be validated
41
40
  throw new Error(
42
41
  channel +
43
42
  " does not support " +
@@ -96,6 +95,44 @@ export function getDefaultScaleType(channel, dataType) {
96
95
  return type;
97
96
  }
98
97
 
98
+ /**
99
+ * Validates explicit scale type choices against the resolved data type and
100
+ * channel constraints.
101
+ *
102
+ * @param {Channel} channel
103
+ * @param {import("../spec/channel.js").Type} dataType
104
+ * @param {import("../spec/scale.js").ScaleType | undefined} scaleType
105
+ * @param {string} source
106
+ */
107
+ export function validateScaleTypeCompatibility(
108
+ channel,
109
+ dataType,
110
+ scaleType,
111
+ source
112
+ ) {
113
+ if (!scaleType) {
114
+ return;
115
+ }
116
+
117
+ if (
118
+ [INDEX, LOCUS].includes(scaleType) &&
119
+ !isPrimaryPositionalChannel(channel)
120
+ ) {
121
+ throw new Error(
122
+ `Index and locus scales are only supported on positional channels (x/y). Channel "${channel}" resolves to scale type "${scaleType}".`
123
+ );
124
+ }
125
+
126
+ if (
127
+ ([INDEX, LOCUS].includes(dataType) && scaleType !== dataType) ||
128
+ (scaleType === LOCUS && scaleType !== dataType)
129
+ ) {
130
+ throw new Error(
131
+ `${source} "${scaleType}" is incompatible with "${dataType}" data.`
132
+ );
133
+ }
134
+ }
135
+
99
136
  /**
100
137
  * @param {import("../spec/scale.js").Scale} props
101
138
  * @param {Channel} channel
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Maps view-level axis configs and attaches non-pending configs to their
3
+ * target resolutions.
4
+ *
5
+ * @param {View} root
6
+ * @returns {ViewLevelAxisConfigMapping[]}
7
+ */
8
+ export function attachViewLevelAxisConfigs(root: View): ViewLevelAxisConfigMapping[];
9
+ /**
10
+ * Maps view-level legend configs and attaches non-pending configs to their
11
+ * target resolutions.
12
+ *
13
+ * @param {View} root
14
+ * @returns {ViewLevelLegendConfigMapping[]}
15
+ */
16
+ export function attachViewLevelLegendConfigs(root: View): ViewLevelLegendConfigMapping[];
17
+ /**
18
+ * Clears view-level guide configs owned by views in the subtree.
19
+ *
20
+ * @param {View} root
21
+ */
22
+ export function clearViewLevelGuideConfigs(root: View): void;
23
+ export type ChannelWithScale = import("../spec/channel.js").ChannelWithScale;
24
+ export type PrimaryPositionalChannel = import("../spec/channel.js").PrimaryPositionalChannel;
25
+ export type AxisConfig = import("../spec/axis.js").Axis & import("../spec/axis.js").GenomeAxis;
26
+ export type LegendConfig = import("../spec/legend.js").Legend;
27
+ export type View = import("../view/view.js").default;
28
+ export type AxisResolution = import("./axisResolution.js").default;
29
+ export type LegendResolution = import("./legendResolution.js").default;
30
+ export type ViewLevelAxisConfigMapping = {
31
+ view: View;
32
+ channel: PrimaryPositionalChannel;
33
+ config: Partial<AxisConfig>;
34
+ resolution: AxisResolution | undefined;
35
+ };
36
+ export type ViewLevelLegendConfigMapping = {
37
+ view: View;
38
+ channel: ChannelWithScale;
39
+ config: LegendConfig;
40
+ resolution: LegendResolution | undefined;
41
+ };
42
+ export type GuideConfigSpec = {
43
+ configKey: "axes" | "legends";
44
+ resolutionType: "axis" | "legend";
45
+ getResolution: (view: View, channel: any) => AxisResolution | LegendResolution | undefined;
46
+ getAllResolutions: (view: View) => Iterable<AxisResolution | LegendResolution>;
47
+ attach: (resolution: any, view: View, config: any) => void;
48
+ getAttachedConfig: (resolution: any) => {
49
+ view: View;
50
+ } | undefined;
51
+ clear: (resolution: any, view: View) => void;
52
+ };
53
+ //# sourceMappingURL=viewLevelGuideConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewLevelGuideConfig.d.ts","sourceRoot":"","sources":["../../../src/scales/viewLevelGuideConfig.js"],"names":[],"mappings":"AA0DA;;;;;;GAMG;AACH,iDAHW,IAAI,GACF,0BAA0B,EAAE,CAMxC;AAED;;;;;;GAMG;AACH,mDAHW,IAAI,GACF,4BAA4B,EAAE,CAM1C;AAED;;;;GAIG;AACH,iDAFW,IAAI,QAKd;+BAxFY,OAAO,oBAAoB,EAAE,gBAAgB;uCAC7C,OAAO,oBAAoB,EAAE,wBAAwB;yBACrD,OAAO,iBAAiB,EAAE,IAAI,GAAG,OAAO,iBAAiB,EAAE,UAAU;2BACrE,OAAO,mBAAmB,EAAE,MAAM;mBAClC,OAAO,iBAAiB,EAAE,OAAO;6BACjC,OAAO,qBAAqB,EAAE,OAAO;+BACrC,OAAO,uBAAuB,EAAE,OAAO;;UAG1C,IAAI;aACJ,wBAAwB;YACxB,OAAO,CAAC,UAAU,CAAC;gBACnB,cAAc,GAAG,SAAS;;;UAG1B,IAAI;aACJ,gBAAgB;YAChB,YAAY;gBACZ,gBAAgB,GAAG,SAAS;;;eAG5B,MAAM,GAAG,SAAS;oBAClB,MAAM,GAAG,QAAQ;mBACjB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,cAAc,GAAG,gBAAgB,GAAG,SAAS;uBAC3E,CAAC,IAAI,EAAE,IAAI,KAAK,QAAQ,CAAC,cAAc,GAAG,gBAAgB,CAAC;YAC3D,CAAC,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI;uBAClD,CAAC,UAAU,EAAE,GAAG,KAAK;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,GAAG,SAAS;WAC/C,CAAC,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI"}