@genome-spy/core 0.65.0 → 0.67.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 (249) hide show
  1. package/dist/bundle/browser-BRemItdO.js +138 -0
  2. package/dist/bundle/{index-CD7FLu9x.js → index-BatuyGAI.js} +23 -21
  3. package/dist/bundle/{index-C0llXMqm.js → index-ByuE8dvu.js} +140 -88
  4. package/dist/bundle/index-Cq3QFUxX.js +1781 -0
  5. package/dist/bundle/index-D28m8tSW.js +1607 -0
  6. package/dist/bundle/index-DbJ0oeYM.js +631 -0
  7. package/dist/bundle/index.es.js +15821 -14601
  8. package/dist/bundle/index.js +214 -212
  9. package/dist/bundle/{inflate-DRgHi_KK.js → inflate-GtwLkvSP.js} +222 -224
  10. package/dist/bundle/unzip-NywezaRR.js +1492 -0
  11. package/dist/schema.json +13 -3
  12. package/dist/src/config/scaleDefaults.d.ts +8 -0
  13. package/dist/src/config/scaleDefaults.d.ts.map +1 -0
  14. package/dist/src/config/scaleDefaults.js +45 -0
  15. package/dist/src/data/flowHandle.d.ts +2 -0
  16. package/dist/src/data/flowHandle.d.ts.map +1 -1
  17. package/dist/src/data/flowHandle.js +1 -0
  18. package/dist/src/data/flowInit.d.ts +12 -4
  19. package/dist/src/data/flowInit.d.ts.map +1 -1
  20. package/dist/src/data/flowInit.js +115 -16
  21. package/dist/src/data/sources/lazy/axisTickSource.js +1 -1
  22. package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts +1 -1
  23. package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts.map +1 -1
  24. package/dist/src/data/sources/lazy/singleAxisLazySource.js +10 -3
  25. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
  26. package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +5 -1
  27. package/dist/src/data/transforms/filterScoredLabels.d.ts +1 -1
  28. package/dist/src/data/transforms/filterScoredLabels.d.ts.map +1 -1
  29. package/dist/src/data/transforms/filterScoredLabels.js +1 -1
  30. package/dist/src/data/transforms/linearizeGenomicCoordinate.d.ts.map +1 -1
  31. package/dist/src/data/transforms/linearizeGenomicCoordinate.js +2 -1
  32. package/dist/src/encoder/encoder.d.ts +1 -1
  33. package/dist/src/encoder/encoder.d.ts.map +1 -1
  34. package/dist/src/encoder/encoder.js +1 -1
  35. package/dist/src/genome/scaleLocus.d.ts +39 -0
  36. package/dist/src/genome/scaleLocus.d.ts.map +1 -1
  37. package/dist/src/genome/scaleLocus.js +76 -0
  38. package/dist/src/genomeSpy/canvasExport.d.ts +19 -0
  39. package/dist/src/genomeSpy/canvasExport.d.ts.map +1 -0
  40. package/dist/src/genomeSpy/canvasExport.js +66 -0
  41. package/dist/src/genomeSpy/containerUi.d.ts +17 -0
  42. package/dist/src/genomeSpy/containerUi.d.ts.map +1 -0
  43. package/dist/src/genomeSpy/containerUi.js +78 -0
  44. package/dist/src/genomeSpy/eventListenerRegistry.d.ts +19 -0
  45. package/dist/src/genomeSpy/eventListenerRegistry.d.ts.map +1 -0
  46. package/dist/src/genomeSpy/eventListenerRegistry.js +38 -0
  47. package/dist/src/genomeSpy/inputBindingManager.d.ts +14 -0
  48. package/dist/src/genomeSpy/inputBindingManager.d.ts.map +1 -0
  49. package/dist/src/genomeSpy/inputBindingManager.js +63 -0
  50. package/dist/src/genomeSpy/interactionController.d.ts +40 -0
  51. package/dist/src/genomeSpy/interactionController.d.ts.map +1 -0
  52. package/dist/src/genomeSpy/interactionController.js +371 -0
  53. package/dist/src/genomeSpy/keyboardListenerManager.d.ts +10 -0
  54. package/dist/src/genomeSpy/keyboardListenerManager.d.ts.map +1 -0
  55. package/dist/src/genomeSpy/keyboardListenerManager.js +31 -0
  56. package/dist/src/genomeSpy/loadingIndicatorManager.d.ts +15 -0
  57. package/dist/src/genomeSpy/loadingIndicatorManager.d.ts.map +1 -0
  58. package/dist/src/genomeSpy/loadingIndicatorManager.js +92 -0
  59. package/dist/src/genomeSpy/renderCoordinator.d.ts +22 -0
  60. package/dist/src/genomeSpy/renderCoordinator.d.ts.map +1 -0
  61. package/dist/src/genomeSpy/renderCoordinator.js +118 -0
  62. package/dist/src/genomeSpy/viewContextFactory.d.ts +18 -0
  63. package/dist/src/genomeSpy/viewContextFactory.d.ts.map +1 -0
  64. package/dist/src/genomeSpy/viewContextFactory.js +79 -0
  65. package/dist/src/genomeSpy/viewDataInit.d.ts +22 -0
  66. package/dist/src/genomeSpy/viewDataInit.d.ts.map +1 -0
  67. package/dist/src/genomeSpy/viewDataInit.js +160 -0
  68. package/dist/src/genomeSpy/viewDataInit.test.d.ts +2 -0
  69. package/dist/src/genomeSpy/viewDataInit.test.d.ts.map +1 -0
  70. package/dist/src/genomeSpy/viewHierarchyConfig.d.ts +14 -0
  71. package/dist/src/genomeSpy/viewHierarchyConfig.d.ts.map +1 -0
  72. package/dist/src/genomeSpy/viewHierarchyConfig.js +24 -0
  73. package/dist/src/genomeSpy/viewHighlight.d.ts +5 -0
  74. package/dist/src/genomeSpy/viewHighlight.d.ts.map +1 -0
  75. package/dist/src/genomeSpy/viewHighlight.js +30 -0
  76. package/dist/src/genomeSpy.d.ts +17 -71
  77. package/dist/src/genomeSpy.d.ts.map +1 -1
  78. package/dist/src/genomeSpy.js +197 -741
  79. package/dist/src/gl/dataToVertices.d.ts.map +1 -1
  80. package/dist/src/gl/dataToVertices.js +16 -4
  81. package/dist/src/gl/glslScaleGenerator.d.ts +1 -1
  82. package/dist/src/gl/webGLHelper.d.ts +2 -2
  83. package/dist/src/gl/webGLHelper.d.ts.map +1 -1
  84. package/dist/src/gl/webGLHelper.js +4 -4
  85. package/dist/src/index.d.ts.map +1 -1
  86. package/dist/src/index.js +2 -12
  87. package/dist/src/marks/mark.d.ts.map +1 -1
  88. package/dist/src/marks/mark.js +4 -2
  89. package/dist/src/{view → scales}/axisResolution.d.ts +9 -16
  90. package/dist/src/scales/axisResolution.d.ts.map +1 -0
  91. package/dist/src/{view → scales}/axisResolution.js +29 -18
  92. package/dist/src/scales/axisResolution.test.d.ts.map +1 -0
  93. package/dist/src/scales/scaleDomainAggregator.d.ts +57 -0
  94. package/dist/src/scales/scaleDomainAggregator.d.ts.map +1 -0
  95. package/dist/src/scales/scaleDomainAggregator.js +167 -0
  96. package/dist/src/scales/scaleDomainAggregator.test.d.ts +2 -0
  97. package/dist/src/scales/scaleDomainAggregator.test.d.ts.map +1 -0
  98. package/dist/src/scales/scaleInstanceManager.d.ts +40 -0
  99. package/dist/src/scales/scaleInstanceManager.d.ts.map +1 -0
  100. package/dist/src/scales/scaleInstanceManager.js +317 -0
  101. package/dist/src/scales/scaleInstanceManager.test.d.ts +2 -0
  102. package/dist/src/scales/scaleInstanceManager.test.d.ts.map +1 -0
  103. package/dist/src/scales/scaleInteractionController.d.ts +73 -0
  104. package/dist/src/scales/scaleInteractionController.d.ts.map +1 -0
  105. package/dist/src/scales/scaleInteractionController.js +336 -0
  106. package/dist/src/scales/scaleInteractionController.test.d.ts +2 -0
  107. package/dist/src/scales/scaleInteractionController.test.d.ts.map +1 -0
  108. package/dist/src/scales/scalePropsResolver.d.ts +23 -0
  109. package/dist/src/scales/scalePropsResolver.d.ts.map +1 -0
  110. package/dist/src/scales/scalePropsResolver.js +74 -0
  111. package/dist/src/{view → scales}/scaleResolution.d.ts +53 -35
  112. package/dist/src/scales/scaleResolution.d.ts.map +1 -0
  113. package/dist/src/scales/scaleResolution.js +732 -0
  114. package/dist/src/scales/scaleResolution.test.d.ts.map +1 -0
  115. package/dist/src/scales/scaleResolutionConstants.d.ts +6 -0
  116. package/dist/src/scales/scaleResolutionConstants.d.ts.map +1 -0
  117. package/dist/src/scales/scaleResolutionConstants.js +5 -0
  118. package/dist/src/scales/scaleRules.d.ts +16 -0
  119. package/dist/src/scales/scaleRules.d.ts.map +1 -0
  120. package/dist/src/scales/scaleRules.js +103 -0
  121. package/dist/src/scales/scaleRules.test.d.ts +2 -0
  122. package/dist/src/scales/scaleRules.test.d.ts.map +1 -0
  123. package/dist/src/spec/channel.d.ts +13 -18
  124. package/dist/src/spec/scale.d.ts +6 -0
  125. package/dist/src/types/embedApi.d.ts +5 -0
  126. package/dist/src/types/scaleResolutionApi.d.ts +1 -1
  127. package/dist/src/utils/domainArray.d.ts.map +1 -1
  128. package/dist/src/utils/domainArray.js +3 -0
  129. package/dist/src/utils/indexer.d.ts +3 -0
  130. package/dist/src/utils/indexer.d.ts.map +1 -1
  131. package/dist/src/utils/indexer.js +3 -0
  132. package/dist/src/view/concatView.d.ts +18 -0
  133. package/dist/src/view/concatView.d.ts.map +1 -1
  134. package/dist/src/view/concatView.js +73 -0
  135. package/dist/src/view/concatView.test.d.ts +2 -0
  136. package/dist/src/view/concatView.test.d.ts.map +1 -0
  137. package/dist/src/view/containerMutationHelper.d.ts +74 -0
  138. package/dist/src/view/containerMutationHelper.d.ts.map +1 -0
  139. package/dist/src/view/containerMutationHelper.js +118 -0
  140. package/dist/src/view/containerView.d.ts +0 -7
  141. package/dist/src/view/containerView.d.ts.map +1 -1
  142. package/dist/src/view/containerView.js +0 -10
  143. package/dist/src/view/facetView.d.ts.map +1 -1
  144. package/dist/src/view/facetView.js +0 -15
  145. package/dist/src/view/flowBuilder.d.ts +5 -3
  146. package/dist/src/view/flowBuilder.d.ts.map +1 -1
  147. package/dist/src/view/flowBuilder.js +69 -6
  148. package/dist/src/view/gridView/gridChild.d.ts +11 -0
  149. package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
  150. package/dist/src/view/gridView/gridChild.js +32 -6
  151. package/dist/src/view/gridView/gridView.d.ts +39 -1
  152. package/dist/src/view/gridView/gridView.d.ts.map +1 -1
  153. package/dist/src/view/gridView/gridView.js +106 -48
  154. package/dist/src/view/gridView/gridView.test.d.ts +2 -0
  155. package/dist/src/view/gridView/gridView.test.d.ts.map +1 -0
  156. package/dist/src/view/gridView/scrollbar.d.ts +39 -8
  157. package/dist/src/view/gridView/scrollbar.d.ts.map +1 -1
  158. package/dist/src/view/gridView/scrollbar.js +184 -69
  159. package/dist/src/view/layerView.d.ts +14 -0
  160. package/dist/src/view/layerView.d.ts.map +1 -1
  161. package/dist/src/view/layerView.js +66 -0
  162. package/dist/src/view/layerView.test.d.ts +2 -0
  163. package/dist/src/view/layerView.test.d.ts.map +1 -0
  164. package/dist/src/view/testUtils.d.ts.map +1 -1
  165. package/dist/src/view/testUtils.js +7 -1
  166. package/dist/src/view/unitView.d.ts.map +1 -1
  167. package/dist/src/view/unitView.js +41 -36
  168. package/dist/src/view/view.d.ts +18 -6
  169. package/dist/src/view/view.d.ts.map +1 -1
  170. package/dist/src/view/view.js +30 -4
  171. package/package.json +2 -2
  172. package/dist/bundle/browser-txUcLy2H.js +0 -123
  173. package/dist/bundle/index-BQpbYrv4.js +0 -1712
  174. package/dist/bundle/index-BhtHKLUo.js +0 -73
  175. package/dist/bundle/index-CCe8rnZz.js +0 -716
  176. package/dist/bundle/index-DhcU-Gk-.js +0 -1487
  177. package/dist/src/data/collector.test.js +0 -138
  178. package/dist/src/data/dataFlow.test.js +0 -38
  179. package/dist/src/data/flow.test.js +0 -81
  180. package/dist/src/data/flowInit.test.js +0 -413
  181. package/dist/src/data/flowNode.test.js +0 -50
  182. package/dist/src/data/flowOptimizer.test.js +0 -209
  183. package/dist/src/data/formats/fasta.test.js +0 -27
  184. package/dist/src/data/sources/inlineSource.test.js +0 -63
  185. package/dist/src/data/sources/sequenceSource.test.js +0 -81
  186. package/dist/src/data/transforms/aggregate.test.js +0 -134
  187. package/dist/src/data/transforms/clone.test.js +0 -11
  188. package/dist/src/data/transforms/coverage.test.js +0 -238
  189. package/dist/src/data/transforms/filter.test.js +0 -20
  190. package/dist/src/data/transforms/flatten.test.js +0 -96
  191. package/dist/src/data/transforms/flattenDelimited.test.js +0 -90
  192. package/dist/src/data/transforms/flattenSequence.test.js +0 -34
  193. package/dist/src/data/transforms/formula.test.js +0 -25
  194. package/dist/src/data/transforms/identifier.test.js +0 -92
  195. package/dist/src/data/transforms/pileup.test.js +0 -70
  196. package/dist/src/data/transforms/project.test.js +0 -32
  197. package/dist/src/data/transforms/regexExtract.test.js +0 -70
  198. package/dist/src/data/transforms/regexFold.test.js +0 -201
  199. package/dist/src/data/transforms/sample.test.js +0 -38
  200. package/dist/src/data/transforms/stack.test.js +0 -91
  201. package/dist/src/encoder/accessor.test.js +0 -162
  202. package/dist/src/encoder/encoder.test.js +0 -105
  203. package/dist/src/genome/genome.test.js +0 -268
  204. package/dist/src/genome/genomes.test.js +0 -8
  205. package/dist/src/genome/scaleIndex.test.js +0 -78
  206. package/dist/src/genome/scaleLocus.test.js +0 -4
  207. package/dist/src/scale/scale.test.js +0 -326
  208. package/dist/src/scale/ticks.test.js +0 -46
  209. package/dist/src/selection/selection.test.js +0 -14
  210. package/dist/src/utils/addBaseUrl.test.js +0 -30
  211. package/dist/src/utils/binnedIndex.test.js +0 -201
  212. package/dist/src/utils/cloner.test.js +0 -35
  213. package/dist/src/utils/coalesce.test.js +0 -16
  214. package/dist/src/utils/concatIterables.test.js +0 -8
  215. package/dist/src/utils/domainArray.test.js +0 -130
  216. package/dist/src/utils/indexer.test.js +0 -49
  217. package/dist/src/utils/interactionEvent.test.js +0 -35
  218. package/dist/src/utils/iterateNestedMaps.test.js +0 -33
  219. package/dist/src/utils/kWayMerge.test.js +0 -30
  220. package/dist/src/utils/mergeObjects.test.js +0 -42
  221. package/dist/src/utils/numberExtractor.test.js +0 -6
  222. package/dist/src/utils/propertyCacher.test.js +0 -89
  223. package/dist/src/utils/propertyCoalescer.test.js +0 -25
  224. package/dist/src/utils/radixSort.test.js +0 -51
  225. package/dist/src/utils/reservationMap.test.js +0 -20
  226. package/dist/src/utils/ringBuffer.test.js +0 -39
  227. package/dist/src/utils/topK.test.js +0 -54
  228. package/dist/src/utils/trees.test.js +0 -135
  229. package/dist/src/utils/url.test.js +0 -28
  230. package/dist/src/utils/variableTools.test.js +0 -13
  231. package/dist/src/view/axisResolution.d.ts.map +0 -1
  232. package/dist/src/view/axisResolution.test.d.ts.map +0 -1
  233. package/dist/src/view/axisResolution.test.js +0 -206
  234. package/dist/src/view/flowBuilder.test.js +0 -125
  235. package/dist/src/view/gridView/selectionRect.test.js +0 -87
  236. package/dist/src/view/layout/flexLayout.test.js +0 -323
  237. package/dist/src/view/layout/grid.test.js +0 -71
  238. package/dist/src/view/layout/rectangle.test.js +0 -192
  239. package/dist/src/view/paramMediator.test.js +0 -282
  240. package/dist/src/view/scaleResolution.d.ts.map +0 -1
  241. package/dist/src/view/scaleResolution.js +0 -1059
  242. package/dist/src/view/scaleResolution.test.d.ts.map +0 -1
  243. package/dist/src/view/scaleResolution.test.js +0 -645
  244. package/dist/src/view/view.test.js +0 -245
  245. package/dist/src/view/viewDispose.test.js +0 -110
  246. package/dist/src/view/viewFactory.test.js +0 -25
  247. package/dist/src/view/viewUtils.test.js +0 -87
  248. /package/dist/src/{view → scales}/axisResolution.test.d.ts +0 -0
  249. /package/dist/src/{view → scales}/scaleResolution.test.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"facetView.d.ts","sourceRoot":"","sources":["../../../src/view/facetView.js"],"names":[],"mappings":"AAmDA;;;;;;;;;;;;;;GAcG;AACH;IACI;;;;;;;OAOG;IACH;;;;;;OAMG;IACH,kBALW,OAAO,gBAAgB,EAAE,SAAS,WAClC,OAAO,gBAAgB,EAAE,WAAW,UACpC,aAAa,QACb,MAAM,EA8BhB;IAzBG,UAAgB;IAEhB,WAEC;IAED;;;;OAIG;IACH,aAFU,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAYvC;IAED,oDAAoD;IACpD,kBADY,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,CACa;IA4BjE,sBAIC;IAED;;;OAGG;IACH,qBAFW,KAAK,GAAG,QAAQ,OAwB1B;IAED,qBAyCC;IAED,qBASC;IA6BD,kDAgBC;IAOD;;;;OAIG;IACH,gBAJW,OAAO,4CAA4C,EAAE,OAAO,UAC5D,OAAO,uBAAuB,EAAE,OAAO,YACvC,OAAO,WAAW,EAAE,gBAAgB,QA2L9C;IA3KO,wBAA0B;CA4KrC;2BAhcY,QAAQ,GAAG,KAAK;;;;;;aA4CnB,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE;;;0BA1Df,oBAAoB;qBACzB,eAAe"}
1
+ {"version":3,"file":"facetView.d.ts","sourceRoot":"","sources":["../../../src/view/facetView.js"],"names":[],"mappings":"AAmDA;;;;;;;;;;;;;;GAcG;AACH;IACI;;;;;;;OAOG;IACH;;;;;;OAMG;IACH,kBALW,OAAO,gBAAgB,EAAE,SAAS,WAClC,OAAO,gBAAgB,EAAE,WAAW,UACpC,aAAa,QACb,MAAM,EA8BhB;IAzBG,UAAgB;IAEhB,WAEC;IAED;;;;OAIG;IACH,aAFU,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAYvC;IAED,oDAAoD;IACpD,kBADY,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,CACa;IAajE,sBAIC;IAED;;;OAGG;IACH,qBAFW,KAAK,GAAG,QAAQ,OAwB1B;IAED,qBAyCC;IAED,qBASC;IA6BD,kDAgBC;IAOD;;;;OAIG;IACH,gBAJW,OAAO,4CAA4C,EAAE,OAAO,UAC5D,OAAO,uBAAuB,EAAE,OAAO,YACvC,OAAO,WAAW,EAAE,gBAAgB,QA2L9C;IA3KO,wBAA0B;CA4KrC;2BAjbY,QAAQ,GAAG,KAAK;;;;;;aA4CnB,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE;;;0BA1Df,oBAAoB;qBACzB,eAAe"}
@@ -120,21 +120,6 @@ export default class FacetView extends ContainerView {
120
120
  }
121
121
  }
122
122
 
123
- /**
124
- * @param {import("./view.js").default} child
125
- * @param {import("./view.js").default} replacement
126
- */
127
- replaceChild(child, replacement) {
128
- if (child !== this.child) {
129
- throw new Error("Not my child!");
130
- }
131
-
132
- child.disposeSubtree();
133
- this.child = /** @type {UnitView | LayerView | DecoratorView} */ (
134
- replacement
135
- );
136
- }
137
-
138
123
  transformData() {
139
124
  super.transformData();
140
125
  // A hacky solution for updating facets. TODO: Something more robust.
@@ -2,16 +2,18 @@
2
2
  * @param {View} root
3
3
  * @param {DataFlow} [existingFlow] Add data flow
4
4
  * graphs to an existing DataFlow object.
5
+ * @param {(view: View) => boolean} [viewFilter]
6
+ * @param {(view: View) => boolean} [viewInitializationPredicate]
5
7
  */
6
- export function buildDataFlow(root: import("./view.js").default, existingFlow?: DataFlow): DataFlow;
8
+ export function buildDataFlow(root: import("./view.js").default, existingFlow?: DataFlow, viewFilter?: (view: import("./view.js").default) => boolean, viewInitializationPredicate?: (view: import("./view.js").default) => boolean): DataFlow;
7
9
  /**
8
10
  * Changes the ChromPos channelDefs into FieldDefs and returns
9
11
  * LinearizeGenomicCoordinate transform(s) that should be inserted into
10
12
  * the data flow.
11
13
  *
12
- * @param {View} view
14
+ * @param {import("./unitView.js").default} view
13
15
  */
14
- export function linearizeLocusAccess(view: import("./view.js").default): {
16
+ export function linearizeLocusAccess(view: import("./unitView.js").default): {
15
17
  transforms: import("../data/flowNode.js").default[];
16
18
  rewrittenEncoding: import("../spec/channel.js").Encoding;
17
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"flowBuilder.d.ts","sourceRoot":"","sources":["../../../src/view/flowBuilder.js"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,gFAHW,QAAQ,YAmNlB;AAED;;;;;;GAMG;AACH;;;IAgGc;;;OAGG;;EAYhB;AAgCD;;;;;;GAMG;AACH,4BAFwB,CAAC,SAAZ,qCAAU,cAFZ,CAAC,iBACA,uCAAW;;;0BAwBG,OAAO,CAAC,QAAQ,CAAC,OAAO,qBAAqB,EAAE,KAAK,CAAC,CAAC;EAkB/E;qBA7aoB,qBAAqB;sBANpB,sBAAsB"}
1
+ {"version":3,"file":"flowBuilder.d.ts","sourceRoot":"","sources":["../../../src/view/flowBuilder.js"],"names":[],"mappings":"AAyBA;;;;;;GAMG;AACH,gFALW,QAAQ,eAER,CAAC,IAAI,6BAAM,KAAK,OAAO,gCACvB,CAAC,IAAI,6BAAM,KAAK,OAAO,YAoPjC;AAuBD;;;;;;GAMG;AACH,2CAFW,OAAO,eAAe,EAAE,OAAO;;;IAuG5B;;;OAGG;;EAYhB;AAgCD;;;;;;GAMG;AACH,4BAFwB,CAAC,SAAZ,qCAAU,cAFZ,CAAC,iBACA,uCAAW;;;0BAwBG,OAAO,CAAC,QAAQ,CAAC,OAAO,qBAAqB,EAAE,KAAK,CAAC,CAAC;EAkB/E;qBA3eoB,qBAAqB;sBAPpB,sBAAsB"}
@@ -2,6 +2,7 @@ import Collector from "../data/collector.js";
2
2
  import createTransform from "../data/transforms/transformFactory.js";
3
3
  import createDataSource from "../data/sources/dataSourceFactory.js";
4
4
  import UnitView from "./unitView.js";
5
+ import { VISIT_SKIP } from "./view.js";
5
6
  import { BEHAVIOR_MODIFIES } from "../data/flowNode.js";
6
7
  import CloneTransform from "../data/transforms/clone.js";
7
8
  import DataFlow from "../data/dataFlow.js";
@@ -26,8 +27,15 @@ import { nodesToTreesWithAccessor, visitTree } from "../utils/trees.js";
26
27
  * @param {View} root
27
28
  * @param {DataFlow} [existingFlow] Add data flow
28
29
  * graphs to an existing DataFlow object.
30
+ * @param {(view: View) => boolean} [viewFilter]
31
+ * @param {(view: View) => boolean} [viewInitializationPredicate]
29
32
  */
30
- export function buildDataFlow(root, existingFlow) {
33
+ export function buildDataFlow(
34
+ root,
35
+ existingFlow,
36
+ viewFilter,
37
+ viewInitializationPredicate
38
+ ) {
31
39
  /**
32
40
  * @typedef {import("./view.js").default} View
33
41
  * @typedef {import("../data/flowNode.js").default} FlowNode
@@ -47,6 +55,8 @@ export function buildDataFlow(root, existingFlow) {
47
55
  /** @type {(function():void)[]} */
48
56
  const postProcessOps = [];
49
57
 
58
+ const shouldInitializeView = viewInitializationPredicate ?? (() => true);
59
+
50
60
  /**
51
61
  * @param {FlowNode} node
52
62
  * @param {function():Error} [onMissingParent]
@@ -121,6 +131,27 @@ export function buildDataFlow(root, existingFlow) {
121
131
 
122
132
  /** @param {View} view */
123
133
  const processView = (view) => {
134
+ if (!shouldInitializeView(view)) {
135
+ const flowNode = view.flowHandle?.node;
136
+ if (flowNode) {
137
+ if (flowNode !== currentNode) {
138
+ currentNode = flowNode;
139
+ nodeStack.push(flowNode);
140
+ }
141
+ return;
142
+ }
143
+ if (
144
+ view.spec.data ||
145
+ view.spec.transform ||
146
+ view instanceof UnitView
147
+ ) {
148
+ throw new Error(
149
+ "Cannot reuse missing flow nodes for " +
150
+ view.getPathString()
151
+ );
152
+ }
153
+ return;
154
+ }
124
155
  if (view.spec.data) {
125
156
  const previousDataSource = view.flowHandle?.dataSource;
126
157
  if (
@@ -205,12 +236,18 @@ export function buildDataFlow(root, existingFlow) {
205
236
  view.flowHandle ??= {};
206
237
  view.flowHandle.collector = collector;
207
238
  }
239
+
240
+ if (currentNode) {
241
+ view.flowHandle ??= {};
242
+ view.flowHandle.node = currentNode;
243
+ }
208
244
  };
209
245
 
210
246
  // Views only keep track of their children based on the layout hierachy.
211
247
  // Thus, let's get traversable hierarchies using dataParents.
248
+ const views = collectSubtreeViews(root, viewFilter);
212
249
  const dataTrees = nodesToTreesWithAccessor(
213
- root.getDescendants(),
250
+ views,
214
251
  (view) => view.dataParent
215
252
  );
216
253
 
@@ -237,16 +274,36 @@ export function buildDataFlow(root, existingFlow) {
237
274
  return dataFlow;
238
275
  }
239
276
 
277
+ /**
278
+ * @param {import("./view.js").default} root
279
+ * @param {(view: import("./view.js").default) => boolean} [viewFilter]
280
+ * @returns {import("./view.js").default[]}
281
+ */
282
+ function collectSubtreeViews(root, viewFilter) {
283
+ if (!viewFilter) {
284
+ return root.getDescendants();
285
+ }
286
+
287
+ /** @type {import("./view.js").default[]} */
288
+ const views = [];
289
+ root.visit((view) => {
290
+ if (!viewFilter(view)) {
291
+ return VISIT_SKIP;
292
+ }
293
+ views.push(view);
294
+ });
295
+ return views;
296
+ }
297
+
240
298
  /**
241
299
  * Changes the ChromPos channelDefs into FieldDefs and returns
242
300
  * LinearizeGenomicCoordinate transform(s) that should be inserted into
243
301
  * the data flow.
244
302
  *
245
- * @param {View} view
303
+ * @param {import("./unitView.js").default} view
246
304
  */
247
305
  export function linearizeLocusAccess(view) {
248
306
  /**
249
- * @typedef {import("./view.js").default} View
250
307
  * @typedef {import("../data/flowNode.js").default} FlowNode
251
308
  * @typedef {import("../spec/channel.js").Channel} Channel
252
309
  * @typedef {import("../spec/channel.js").Encoding} Encoding
@@ -258,12 +315,18 @@ export function linearizeLocusAccess(view) {
258
315
  /** @type {Encoding} */
259
316
  const rewrittenEncoding = {};
260
317
 
318
+ // Use mark.encoding so we see the same channel defs that encoders consume,
319
+ // including inherited channels and mark defaults. getEncoding() only returns
320
+ // spec/inherited encodings and can omit channels during lazy init (e.g.,
321
+ // summary views that inherit chrom/pos), which would skip chrom/pos rewrites.
322
+ const encoding = view.mark.encoding;
323
+
261
324
  /** @type {{ channel: Channel, chromPosDef: import("../spec/channel.js").ChromPosDef}[]} */
262
325
  const channelsAndChromPosDefs = [];
263
326
 
264
327
  // Optimize the number of transforms. Use only a single transform for positions
265
328
  // that share the chromosome field and channel.
266
- for (const [c, channelDef] of Object.entries(view.getEncoding())) {
329
+ for (const [c, channelDef] of Object.entries(encoding)) {
267
330
  const channel = /** @type {Channel} */ (c);
268
331
  if (isPositionalChannel(channel) && isChromPosDef(channelDef)) {
269
332
  channelsAndChromPosDefs.push({ channel, chromPosDef: channelDef });
@@ -302,7 +365,7 @@ export function linearizeLocusAccess(view) {
302
365
  /** @type {any} */
303
366
  const newFieldDef = {
304
367
  ...(view.spec.encoding?.[channel] ??
305
- view.getEncoding()[channel] ??
368
+ encoding[channel] ??
306
369
  {}),
307
370
  field: linearizedField,
308
371
  };
@@ -9,6 +9,13 @@ export function createBackground(viewBackground: import("../../spec/view.js").Vi
9
9
  */
10
10
  export function createBackgroundStroke(viewBackground: import("../../spec/view.js").ViewBackground): import("../../spec/view.js").UnitSpec;
11
11
  export default class GridChild {
12
+ /**
13
+ * Users guide:
14
+ * - GridChild is owned by GridView and is not meant to be instantiated or
15
+ * managed directly by callers.
16
+ * - Use GridView/ConcatView APIs for insertion/removal so decorations and
17
+ * dataflow are kept in sync.
18
+ */
12
19
  /**
13
20
  * @param {import("../view.js").default} view
14
21
  * @param {import("../containerView.js").default} layoutParent
@@ -39,6 +46,10 @@ export default class GridChild {
39
46
  * Create view decorations, grid lines, axes, etc.
40
47
  */
41
48
  createAxes(): Promise<void>;
49
+ /**
50
+ * Disposes axis and gridline views so axes can be recreated safely.
51
+ */
52
+ disposeAxisViews(): void;
42
53
  getOverhang(): Padding;
43
54
  getOverhangAndPadding(): Padding;
44
55
  #private;
@@ -1 +1 @@
1
- {"version":3,"file":"gridChild.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/gridChild.js"],"names":[],"mappings":"AAkqBA;;;GAGG;AACH,iDAHW,OAAO,oBAAoB,EAAE,cAAc,GACzC,OAAO,oBAAoB,EAAE,QAAQ,CA8BjD;AAED;;;GAGG;AACH,uDAHW,OAAO,oBAAoB,EAAE,cAAc,GACzC,OAAO,oBAAoB,EAAE,QAAQ,CA6CjD;AAhuBD;IACI;;;;OAIG;IACH,kBAJW,OAAO,YAAY,EAAE,OAAO,gBAC5B,OAAO,qBAAqB,EAAE,OAAO,UACrC,MAAM,EAyFhB;IAtFG,oDAAgC;IAChC,mCAAgB;IAChB,eAAoB;IAEpB,uBAAuB;IACvB,YADW,QAAQ,CACQ;IAE3B,uBAAuB;IACvB,kBADW,QAAQ,CACc;IAEjC,sFAAsF;IACtF,MADW,OAAO,CAAC,MAAM,CAAC,OAAO,oBAAoB,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAC/D;IAEd,+FAA+F;IAC/F,WADW,OAAO,CAAC,MAAM,CAAC,OAAO,oBAAoB,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAC9D;IAEnB,mFAAmF;IACnF,YADW,OAAO,CAAC,MAAM,CAAC,OAAO,gBAAgB,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC,CAC3D;IAEpB,4BAA4B;IAC5B,eADW,aAAa,CACM;IAE9B,uBAAuB;IACvB,OADW,QAAQ,CACG;IAEtB,wBAAwB;IACxB,QADW,SAAS,CACQ;IAoZhC,sEAiBC;IAED;;OAEG;IACH,4BAsKC;IAED,uBAqBC;IAED,iCAEC;;CACJ;qBAjpBoB,gBAAgB;qBANK,gBAAgB;yBADjC,oBAAoB;sBAQvB,gBAAgB;0BACZ,oBAAoB;sBAJxB,wBAAwB;oBAF1B,sBAAsB"}
1
+ {"version":3,"file":"gridChild.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/gridChild.js"],"names":[],"mappings":"AA4rBA;;;GAGG;AACH,iDAHW,OAAO,oBAAoB,EAAE,cAAc,GACzC,OAAO,oBAAoB,EAAE,QAAQ,CA8BjD;AAED;;;GAGG;AACH,uDAHW,OAAO,oBAAoB,EAAE,cAAc,GACzC,OAAO,oBAAoB,EAAE,QAAQ,CA6CjD;AA1vBD;IACI;;;;;;OAMG;IAEH;;;;OAIG;IACH,kBAJW,OAAO,YAAY,EAAE,OAAO,gBAC5B,OAAO,qBAAqB,EAAE,OAAO,UACrC,MAAM,EAyFhB;IAtFG,oDAAgC;IAChC,mCAAgB;IAChB,eAAoB;IAEpB,uBAAuB;IACvB,YADW,QAAQ,CACQ;IAE3B,uBAAuB;IACvB,kBADW,QAAQ,CACc;IAEjC,sFAAsF;IACtF,MADW,OAAO,CAAC,MAAM,CAAC,OAAO,oBAAoB,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAC/D;IAEd,+FAA+F;IAC/F,WADW,OAAO,CAAC,MAAM,CAAC,OAAO,oBAAoB,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAC9D;IAEnB,mFAAmF;IACnF,YADW,OAAO,CAAC,MAAM,CAAC,OAAO,gBAAgB,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC,CAC3D;IAEpB,4BAA4B;IAC5B,eADW,aAAa,CACM;IAE9B,uBAAuB;IACvB,OADW,QAAQ,CACG;IAEtB,wBAAwB;IACxB,QADW,SAAS,CACQ;IAoZhC,sEAiBC;IAED;;OAEG;IACH,4BAwKC;IAED;;OAEG;IACH,yBAWC;IAED,uBAqBC;IAED,iCAEC;;CACJ;qBA3qBoB,gBAAgB;qBANK,gBAAgB;yBADjC,oBAAoB;sBAQvB,gBAAgB;0BACZ,oBAAoB;sBAJxB,wBAAwB;oBAF1B,sBAAsB"}
@@ -18,6 +18,14 @@ import Scrollbar from "./scrollbar.js";
18
18
  import SelectionRect from "./selectionRect.js";
19
19
 
20
20
  export default class GridChild {
21
+ /**
22
+ * Users guide:
23
+ * - GridChild is owned by GridView and is not meant to be instantiated or
24
+ * managed directly by callers.
25
+ * - Use GridView/ConcatView APIs for insertion/removal so decorations and
26
+ * dataflow are kept in sync.
27
+ */
28
+
21
29
  /**
22
30
  * @param {import("../view.js").default} view
23
31
  * @param {import("../containerView.js").default} layoutParent
@@ -137,7 +145,7 @@ export default class GridChild {
137
145
  const scaleResolutions = Object.fromEntries(
138
146
  channels.map((channel) => {
139
147
  const resolution = this.view.getScaleResolution(channel);
140
- const scale = resolution?.scale;
148
+ const scale = resolution?.getScale();
141
149
 
142
150
  if (!scale || !isContinuous(scale.type)) {
143
151
  throw new Error(
@@ -214,7 +222,7 @@ export default class GridChild {
214
222
  const np = view.coords.normalizePoint(point.x, point.y, true);
215
223
 
216
224
  for (const channel of channels) {
217
- const scale = scaleResolutions[channel].scale;
225
+ const scale = scaleResolutions[channel].getScale();
218
226
  // @ts-ignore
219
227
  const val = scale.invert(channel == "x" ? np.x : np.y);
220
228
  inverted[channel] =
@@ -243,7 +251,7 @@ export default class GridChild {
243
251
  /** @type {number} */ val
244
252
  ) => {
245
253
  if (val == null) return null;
246
- return scaleResolutions[channel].scale(val);
254
+ return scaleResolutions[channel].getScale()(val);
247
255
  };
248
256
  const px = getCoord("x", xVal) ?? i;
249
257
  const py = getCoord("y", yVal) ?? i;
@@ -477,10 +485,12 @@ export default class GridChild {
477
485
  * Create view decorations, grid lines, axes, etc.
478
486
  */
479
487
  async createAxes() {
488
+ this.disposeAxisViews();
489
+
480
490
  const { view, axes, gridLines } = this;
481
491
 
482
492
  /**
483
- * @param {import("../axisResolution.js").default} r
493
+ * @param {import("../../scales/axisResolution.js").default} r
484
494
  * @param {import("../../spec/channel.js").PrimaryPositionalChannel} channel
485
495
  */
486
496
  const getAxisPropsWithDefaults = (r, channel) => {
@@ -521,7 +531,7 @@ export default class GridChild {
521
531
  };
522
532
 
523
533
  /**
524
- * @param {import("../axisResolution.js").default} r
534
+ * @param {import("../../scales/axisResolution.js").default} r
525
535
  * @param {import("../../spec/channel.js").PrimaryPositionalChannel} channel
526
536
  * @param {import("../view.js").default} axisParent
527
537
  */
@@ -548,7 +558,7 @@ export default class GridChild {
548
558
  };
549
559
 
550
560
  /**
551
- * @param {import("../axisResolution.js").default} r
561
+ * @param {import("../../scales/axisResolution.js").default} r
552
562
  * @param {import("../../spec/channel.js").PrimaryPositionalChannel} channel
553
563
  * @param {import("../view.js").default} axisParent
554
564
  */
@@ -644,6 +654,22 @@ export default class GridChild {
644
654
  );
645
655
  }
646
656
 
657
+ /**
658
+ * Disposes axis and gridline views so axes can be recreated safely.
659
+ */
660
+ disposeAxisViews() {
661
+ for (const axisView of Object.values(this.axes)) {
662
+ axisView.disposeSubtree();
663
+ }
664
+
665
+ for (const gridView of Object.values(this.gridLines)) {
666
+ gridView.disposeSubtree();
667
+ }
668
+
669
+ this.axes = {};
670
+ this.gridLines = {};
671
+ }
672
+
647
673
  getOverhang() {
648
674
  const calculate = (
649
675
  /** @type {import("../../spec/axis.js").AxisOrient} */ orient
@@ -43,6 +43,37 @@ export default class GridView extends ContainerView {
43
43
  * @param {View} view
44
44
  */
45
45
  appendChild(view: import("../view.js").default): void;
46
+ /**
47
+ * Appends a child view without initializing dataflow or axes.
48
+ * Intended for ConcatView when building the initial hierarchy.
49
+ *
50
+ * @param {View} view
51
+ * @returns {GridChild}
52
+ */
53
+ appendChildView(view: import("../view.js").default): GridChild;
54
+ /**
55
+ * Inserts a child view without initializing dataflow or axes.
56
+ * Callers should create axes, initialize subtree data, and request layout.
57
+ *
58
+ * @param {View} view
59
+ * @param {number} index
60
+ * @returns {GridChild}
61
+ */
62
+ insertChildViewAt(view: import("../view.js").default, index: number): GridChild;
63
+ /**
64
+ * Removes a child by instance and disposes its subtree.
65
+ * Callers should sync shared axes and request layout.
66
+ *
67
+ * @param {View} view
68
+ */
69
+ removeChildView(view: import("../view.js").default): void;
70
+ /**
71
+ * Removes a child by index and disposes its subtree.
72
+ * Callers should sync shared axes and request layout.
73
+ *
74
+ * @param {number} index
75
+ */
76
+ removeChildAt(index: number): void;
46
77
  /**
47
78
  * @param {View[]} views
48
79
  */
@@ -55,10 +86,17 @@ export default class GridView extends ContainerView {
55
86
  /**
56
87
  * @protected
57
88
  */
58
- protected createAxes(): Promise<void[]>;
89
+ protected createAxes(): Promise<void>;
90
+ /**
91
+ * Recreates shared axes based on current axis resolutions.
92
+ *
93
+ * This is used after dynamic child insert/remove to keep shared axes in sync.
94
+ */
95
+ syncSharedAxes(): Promise<void>;
59
96
  #private;
60
97
  }
61
98
  import AxisView from "../axisView.js";
62
99
  import Rectangle from "../layout/rectangle.js";
63
100
  import ContainerView from "../containerView.js";
101
+ import GridChild from "./gridChild.js";
64
102
  //# sourceMappingURL=gridView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gridView.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/gridView.js"],"names":[],"mappings":"AAkzBA;;GAEG;AACH,+EAUC;AAED;;;;;GAKG;AACH,4CAJW,OAAO,wBAAwB,EAAE,OAAO,UACxC,OAAO,oBAAoB,EAAE,UAAU,YACvC,QAAQ,aAmBlB;AAr0BD;;;;;;;;;;;;;;;GAeG;AACH;IA6BI;;;;;;;;;OASG;IACH,kBARW,OAAO,oBAAoB,EAAE,aAAa,WAC1C,OAAO,4BAA4B,EAAE,OAAO,gBAC5C,aAAa,kDAEb,MAAM,WACN,MAAM,YACN,OAAO,YAAY,EAAE,WAAW,EAoB1C;IARG,iDAAgB;IAOhB,uBAA0B;IAG9B;;OAEG;IACH,sDAIC;IAeD;;OAEG;IACH,mBAFW,8BAAM,QAUhB;IA+BD;;OAEG;IACH,+CAEC;IAED,yBAEC;IAED;;OAEG;IACH,wCAmCC;;CAwkBJ;qBA3wB0D,gBAAgB;sBADrD,wBAAwB;0BAEpB,qBAAqB"}
1
+ {"version":3,"file":"gridView.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/gridView.js"],"names":[],"mappings":"AA42BA;;GAEG;AACH,+EAUC;AAED;;;;;GAKG;AACH,4CAJW,OAAO,wBAAwB,EAAE,OAAO,UACxC,OAAO,oBAAoB,EAAE,UAAU,YACvC,QAAQ,aAmBlB;AA/3BD;;;;;;;;;;;;;;;GAeG;AACH;IAoCI;;;;;;;;;OASG;IACH,kBARW,OAAO,oBAAoB,EAAE,aAAa,WAC1C,OAAO,4BAA4B,EAAE,OAAO,gBAC5C,aAAa,kDAEb,MAAM,WACN,MAAM,YACN,OAAO,YAAY,EAAE,WAAW,EAoB1C;IARG,iDAAgB;IAOhB,uBAA0B;IAG9B;;OAEG;IACH,sDAEC;IAED;;;;;;OAMG;IACH,qDAFa,SAAS,CAIrB;IAED;;;;;;;OAOG;IACH,6DAHW,MAAM,GACJ,SAAS,CAQrB;IAED;;;;;OAKG;IACH,0DAQC;IAED;;;;;OAKG;IACH,qBAFW,MAAM,QAShB;IAeD;;OAEG;IACH,mBAFW,8BAAM,QAUhB;IAYD;;OAEG;IACH,+CAEC;IAED,yBAEC;IAED;;OAEG;IACH,sCAKC;IAED;;;;OAIG;IACH,gCAqCC;;CAwkBJ;qBAr0B0D,gBAAgB;sBADrD,wBAAwB;0BAEpB,qBAAqB;sBAIzB,gBAAgB"}
@@ -34,6 +34,13 @@ import GridChild from "./gridChild.js";
34
34
  * - And later on, brushing, legend(?)
35
35
  */
36
36
  export default class GridView extends ContainerView {
37
+ /**
38
+ * Users guide:
39
+ * - GridView owns GridChild instances and manages decorations and shared axes.
40
+ * - Use ConcatView helpers for dynamic insertion/removal so dataflow and axes
41
+ * lifecycle stays consistent.
42
+ */
43
+
37
44
  /**
38
45
  * @typedef {"row" | "column"} Direction
39
46
  * @typedef {"horizontal" | "vertical"} ScrollDirection
@@ -96,9 +103,65 @@ export default class GridView extends ContainerView {
96
103
  * @param {View} view
97
104
  */
98
105
  appendChild(view) {
106
+ this.appendChildView(view);
107
+ }
108
+
109
+ /**
110
+ * Appends a child view without initializing dataflow or axes.
111
+ * Intended for ConcatView when building the initial hierarchy.
112
+ *
113
+ * @param {View} view
114
+ * @returns {GridChild}
115
+ */
116
+ appendChildView(view) {
117
+ return this.insertChildViewAt(view, this.#children.length);
118
+ }
119
+
120
+ /**
121
+ * Inserts a child view without initializing dataflow or axes.
122
+ * Callers should create axes, initialize subtree data, and request layout.
123
+ *
124
+ * @param {View} view
125
+ * @param {number} index
126
+ * @returns {GridChild}
127
+ */
128
+ insertChildViewAt(view, index) {
99
129
  view.layoutParent ??= this;
100
- this.#children.push(new GridChild(view, this, this.#childSerial));
130
+ const gridChild = new GridChild(view, this, this.#childSerial);
101
131
  this.#childSerial++;
132
+ this.#children.splice(index, 0, gridChild);
133
+ return gridChild;
134
+ }
135
+
136
+ /**
137
+ * Removes a child by instance and disposes its subtree.
138
+ * Callers should sync shared axes and request layout.
139
+ *
140
+ * @param {View} view
141
+ */
142
+ removeChildView(view) {
143
+ const index = this.#children.findIndex(
144
+ (gridChild) => gridChild.view === view
145
+ );
146
+ if (index < 0) {
147
+ throw new Error("Not my child view!");
148
+ }
149
+ this.removeChildAt(index);
150
+ }
151
+
152
+ /**
153
+ * Removes a child by index and disposes its subtree.
154
+ * Callers should sync shared axes and request layout.
155
+ *
156
+ * @param {number} index
157
+ */
158
+ removeChildAt(index) {
159
+ const gridChild = this.#children[index];
160
+ if (!gridChild) {
161
+ throw new Error("Child index out of range!");
162
+ }
163
+ this.#disposeGridChild(gridChild);
164
+ this.#children.splice(index, 1);
102
165
  }
103
166
 
104
167
  get #visibleChildren() {
@@ -127,30 +190,11 @@ export default class GridView extends ContainerView {
127
190
  }
128
191
  }
129
192
 
130
- /**
131
- * @param {View} child
132
- * @param {View} replacement
133
- */
134
- replaceChild(child, replacement) {
135
- const i = this.#children.findIndex(
136
- (gridChild) => gridChild.view == child
137
- );
138
- if (i >= 0) {
139
- this.#disposeGridChild(this.#children[i]);
140
- this.#children[i] = new GridChild(
141
- replacement,
142
- this,
143
- this.#childSerial
144
- );
145
- } else {
146
- throw new Error("Not my child view!");
147
- }
148
- }
149
-
150
193
  /**
151
194
  * @param {GridChild} gridChild
152
195
  */
153
196
  #disposeGridChild(gridChild) {
197
+ gridChild.disposeAxisViews();
154
198
  for (const view of gridChild.getChildren()) {
155
199
  view.disposeSubtree();
156
200
  }
@@ -171,40 +215,54 @@ export default class GridView extends ContainerView {
171
215
  * @protected
172
216
  */
173
217
  async createAxes() {
218
+ await this.syncSharedAxes();
219
+ await Promise.all(
220
+ this.#children.map((gridChild) => gridChild.createAxes())
221
+ );
222
+ }
223
+
224
+ /**
225
+ * Recreates shared axes based on current axis resolutions.
226
+ *
227
+ * This is used after dynamic child insert/remove to keep shared axes in sync.
228
+ */
229
+ async syncSharedAxes() {
230
+ for (const axisView of Object.values(this.#sharedAxes)) {
231
+ axisView.disposeSubtree();
232
+ }
233
+ this.#sharedAxes = {};
234
+
174
235
  /** @type {Promise<void>[]} */
175
236
  const promises = [];
176
237
 
177
- // Axis ticks, labels, etc. They should be created only if this view has caught
178
- // the scale resolution for the channel.
179
238
  for (const channel of primaryPositionalChannels) {
180
239
  const r = this.resolutions.axis[channel];
181
- if (r) {
182
- const props = r.getAxisProps();
183
- if (props) {
184
- const propsWithDefaults = {
185
- title: r.getTitle(),
186
- orient: CHANNEL_ORIENTS[channel][0],
187
- ...props,
188
- };
189
- // TODO: Validate that channel and orient are compatible
190
- const v = new AxisView(
191
- propsWithDefaults,
192
- r.scaleResolution.type,
193
- this.context,
194
- this,
195
- this
196
- );
197
- promises.push(v.initializeChildren());
198
- this.#sharedAxes[channel] = v;
199
- }
240
+ if (!r) {
241
+ continue;
200
242
  }
243
+
244
+ const props = r.getAxisProps();
245
+ if (!props) {
246
+ continue;
247
+ }
248
+
249
+ const propsWithDefaults = {
250
+ title: r.getTitle(),
251
+ orient: CHANNEL_ORIENTS[channel][0],
252
+ ...props,
253
+ };
254
+ const axisView = new AxisView(
255
+ propsWithDefaults,
256
+ r.scaleResolution.type,
257
+ this.context,
258
+ this,
259
+ this
260
+ );
261
+ promises.push(axisView.initializeChildren());
262
+ this.#sharedAxes[channel] = axisView;
201
263
  }
202
264
 
203
- // Create view decorations, grid lines, and independent axes for each child
204
- return Promise.all([
205
- ...promises,
206
- ...this.#children.map((gridChild) => gridChild.createAxes()),
207
- ]);
265
+ await Promise.all(promises);
208
266
  }
209
267
 
210
268
  /**
@@ -797,7 +855,7 @@ export default class GridView extends ContainerView {
797
855
  * @returns
798
856
  */
799
857
  function getZoomableResolutions(view) {
800
- /** @type {Record<import("../../spec/channel.js").PrimaryPositionalChannel, Set<import("../scaleResolution.js").default>>} */
858
+ /** @type {Record<import("../../spec/channel.js").PrimaryPositionalChannel, Set<import("../../scales/scaleResolution.js").default>>} */
801
859
  const resolutions = {
802
860
  x: new Set(),
803
861
  y: new Set(),
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=gridView.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gridView.test.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/gridView.test.js"],"names":[],"mappings":""}
@@ -1,31 +1,62 @@
1
1
  /**
2
+ * This class represents a scrollbar thumb that can be used within a grid view
3
+ * to provide scrolling functionality for overflowing content.
4
+ *
2
5
  * @typedef {"horizontal" | "vertical"} ScrollDirection
3
6
  */
4
7
  export default class Scrollbar extends UnitView {
5
8
  /**
6
9
  * @param {import("./gridChild.js").default} gridChild
7
10
  * @param {ScrollDirection} scrollDirection
11
+ * @param {{ onViewportOffsetChange?: (offset: number) => void }} [options]
12
+ */
13
+ constructor(gridChild: import("./gridChild.js").default, scrollDirection: ScrollDirection, options?: {
14
+ onViewportOffsetChange?: (offset: number) => void;
15
+ });
16
+ /**
17
+ * The actual state of the scrollbar.
18
+ *
19
+ * It's better to keep track of the viewport offset rather than the
20
+ * scrollbar offset because the former is more stable when the
21
+ * viewport size changes.
8
22
  */
9
- constructor(gridChild: import("./gridChild.js").default, scrollDirection: ScrollDirection);
10
23
  viewportOffset: number;
11
24
  config: {
12
25
  scrollbarSize: number;
13
26
  scrollbarPadding: number;
14
- };
15
- interpolateViewportOffset: ((target: {
16
- x: number;
17
- }) => void) & {
18
- stop: () => void;
27
+ scrollbarMinLength: number;
19
28
  };
20
29
  get scrollOffset(): number;
21
30
  /**
31
+ * @param {number} value
32
+ * @param {{ notify?: boolean, syncSmoother?: boolean }} [options]
33
+ */
34
+ setViewportOffset(value: number, { notify, syncSmoother }?: {
35
+ notify?: boolean;
36
+ syncSmoother?: boolean;
37
+ }): void;
38
+ /**
39
+ * Updates the scrollbar with the latest viewport and content rectangles.
40
+ *
41
+ * Viewport coords are flattened to stay stable between layout passes, while
42
+ * content coords may be dynamic (e.g., peek transitions) and are evaluated
43
+ * on demand via accessors.
22
44
  *
23
45
  * @param {Rectangle} viewportCoords
24
- * @param {Rectangle} coords
46
+ * @param {Rectangle} contentCoords
25
47
  */
26
- updateScrollbar(viewportCoords: Rectangle, coords: Rectangle): void;
48
+ updateScrollbar(viewportCoords: Rectangle, contentCoords: Rectangle): void;
49
+ interpolateViewportOffset: ((target: {
50
+ x: number;
51
+ }) => void) & {
52
+ stop: () => void;
53
+ };
27
54
  #private;
28
55
  }
56
+ /**
57
+ * This class represents a scrollbar thumb that can be used within a grid view
58
+ * to provide scrolling functionality for overflowing content.
59
+ */
29
60
  export type ScrollDirection = "horizontal" | "vertical";
30
61
  import UnitView from "../unitView.js";
31
62
  import Rectangle from "../layout/rectangle.js";