@genome-spy/core 0.72.0 → 0.74.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.
- package/LICENSE +1 -1
- package/dist/bundle/AbortablePromiseCache-3gHJdF3E.js +96 -0
- package/dist/bundle/browser-BTgw5ieH.js +126 -0
- package/dist/bundle/chunk-DmhlhrBa.js +11 -0
- package/dist/bundle/esm-BDFRLEuD.js +1248 -0
- package/dist/bundle/esm-BygJiwh0.js +573 -0
- package/dist/bundle/esm-CGX-qz1d.js +155 -0
- package/dist/bundle/esm-CgfVIRJ-.js +121 -0
- package/dist/bundle/esm-CuMSzCHy.js +298 -0
- package/dist/bundle/esm-DMXpJXM4.js +369 -0
- package/dist/bundle/esm-DQiq2Zhd.js +1426 -0
- package/dist/bundle/esm-DtE8VqAv.js +1015 -0
- package/dist/bundle/esm-sIoQYZ21.js +461 -0
- package/dist/bundle/index.es.js +21078 -24556
- package/dist/bundle/index.js +379 -383
- package/dist/bundle/parquetRead-DG_-F5j5.js +1609 -0
- package/dist/schema.json +13349 -7082
- package/dist/src/config/axisConfig.d.ts +16 -0
- package/dist/src/config/axisConfig.d.ts.map +1 -0
- package/dist/src/config/axisConfig.js +84 -0
- package/dist/src/config/defaultConfig.d.ts +3 -0
- package/dist/src/config/defaultConfig.d.ts.map +1 -0
- package/dist/src/config/defaultConfig.js +38 -0
- package/dist/src/config/defaults/axisDefaults.d.ts +5 -0
- package/dist/src/config/defaults/axisDefaults.d.ts.map +1 -0
- package/dist/src/config/defaults/axisDefaults.js +72 -0
- package/dist/src/config/defaults/markDefaults.d.ts +15 -0
- package/dist/src/config/defaults/markDefaults.d.ts.map +1 -0
- package/dist/src/config/defaults/markDefaults.js +121 -0
- package/dist/src/config/defaults/scaleDefaults.d.ts +5 -0
- package/dist/src/config/defaults/scaleDefaults.d.ts.map +1 -0
- package/dist/src/config/defaults/scaleDefaults.js +18 -0
- package/dist/src/config/defaults/titleDefaults.d.ts +5 -0
- package/dist/src/config/defaults/titleDefaults.d.ts.map +1 -0
- package/dist/src/config/defaults/titleDefaults.js +47 -0
- package/dist/src/config/defaults/viewDefaults.d.ts +3 -0
- package/dist/src/config/defaults/viewDefaults.d.ts.map +1 -0
- package/dist/src/config/defaults/viewDefaults.js +2 -0
- package/dist/src/config/markConfig.d.ts +8 -0
- package/dist/src/config/markConfig.d.ts.map +1 -0
- package/dist/src/config/markConfig.js +27 -0
- package/dist/src/config/mergeConfig.d.ts +8 -0
- package/dist/src/config/mergeConfig.d.ts.map +1 -0
- package/dist/src/config/mergeConfig.js +81 -0
- package/dist/src/config/resolveConfig.d.ts +22 -0
- package/dist/src/config/resolveConfig.d.ts.map +1 -0
- package/dist/src/config/resolveConfig.js +32 -0
- package/dist/src/config/scaleConfig.d.ts +40 -0
- package/dist/src/config/scaleConfig.d.ts.map +1 -0
- package/dist/src/config/scaleConfig.js +220 -0
- package/dist/src/config/styleUtils.d.ts +6 -0
- package/dist/src/config/styleUtils.d.ts.map +1 -0
- package/dist/src/config/styleUtils.js +10 -0
- package/dist/src/config/themes.d.ts +15 -0
- package/dist/src/config/themes.d.ts.map +1 -0
- package/dist/src/config/themes.js +293 -0
- package/dist/src/config/titleConfig.d.ts +12 -0
- package/dist/src/config/titleConfig.d.ts.map +1 -0
- package/dist/src/config/titleConfig.js +42 -0
- package/dist/src/config/viewConfig.d.ts +7 -0
- package/dist/src/config/viewConfig.d.ts.map +1 -0
- package/dist/src/config/viewConfig.js +29 -0
- package/dist/src/data/flowNode.d.ts +22 -1
- package/dist/src/data/flowNode.d.ts.map +1 -1
- package/dist/src/data/flowNode.js +37 -1
- package/dist/src/data/formats/bed.d.ts +8 -0
- package/dist/src/data/formats/bed.d.ts.map +1 -0
- package/dist/src/data/formats/bed.js +58 -0
- package/dist/src/data/formats/bedpe.d.ts +8 -0
- package/dist/src/data/formats/bedpe.d.ts.map +1 -0
- package/dist/src/data/formats/bedpe.js +164 -0
- package/dist/src/data/formats/fasta.d.ts.map +1 -1
- package/dist/src/data/formats/fasta.js +4 -0
- package/dist/src/data/formats/parquet.d.ts.map +1 -1
- package/dist/src/data/formats/parquet.js +4 -0
- package/dist/src/data/sources/dataSourceFactory.d.ts +2 -13
- package/dist/src/data/sources/dataSourceFactory.d.ts.map +1 -1
- package/dist/src/data/sources/dataSourceFactory.js +5 -141
- package/dist/src/data/sources/dataUtils.d.ts +16 -0
- package/dist/src/data/sources/dataUtils.d.ts.map +1 -1
- package/dist/src/data/sources/dataUtils.js +53 -3
- package/dist/src/data/sources/lazy/axisGenomeSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/axisGenomeSource.js +11 -0
- package/dist/src/data/sources/lazy/axisTickSource.d.ts +1 -1
- package/dist/src/data/sources/lazy/axisTickSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/axisTickSource.js +19 -8
- package/dist/src/data/sources/lazy/bamSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bamSource.js +11 -0
- package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigBedSource.js +12 -1
- package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigWigSource.js +11 -0
- package/dist/src/data/sources/lazy/gff3Source.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/gff3Source.js +12 -1
- package/dist/src/data/sources/lazy/indexedFastaSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/indexedFastaSource.js +11 -0
- package/dist/src/data/sources/lazy/lazyDataSourceRegistry.d.ts +27 -0
- package/dist/src/data/sources/lazy/lazyDataSourceRegistry.d.ts.map +1 -0
- package/dist/src/data/sources/lazy/lazyDataSourceRegistry.js +65 -0
- package/dist/src/data/sources/lazy/registerBuiltInLazySources.d.ts +2 -0
- package/dist/src/data/sources/lazy/registerBuiltInLazySources.d.ts.map +1 -0
- package/dist/src/data/sources/lazy/registerBuiltInLazySources.js +8 -0
- package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/singleAxisLazySource.js +11 -2
- package/dist/src/data/sources/lazy/vcfSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/vcfSource.js +11 -0
- package/dist/src/data/sources/urlSource.d.ts +4 -0
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +138 -16
- package/dist/src/data/transforms/aggregate.d.ts +1 -0
- package/dist/src/data/transforms/aggregate.d.ts.map +1 -1
- package/dist/src/data/transforms/aggregate.js +30 -8
- package/dist/src/data/transforms/aggregateOps.d.ts.map +1 -1
- package/dist/src/data/transforms/aggregateOps.js +12 -1
- package/dist/src/data/transforms/coverage.js +2 -2
- package/dist/src/data/transforms/filter.js +1 -1
- package/dist/src/data/transforms/filterScoredLabels.d.ts +6 -0
- package/dist/src/data/transforms/filterScoredLabels.d.ts.map +1 -1
- package/dist/src/data/transforms/filterScoredLabels.js +9 -0
- package/dist/src/data/transforms/measureText.d.ts +1 -0
- package/dist/src/data/transforms/measureText.d.ts.map +1 -1
- package/dist/src/data/transforms/measureText.js +14 -5
- package/dist/src/data/transforms/pileup.d.ts.map +1 -1
- package/dist/src/data/transforms/pileup.js +1 -2
- package/dist/src/data/transforms/regexFold.d.ts.map +1 -1
- package/dist/src/data/transforms/regexFold.js +0 -1
- package/dist/src/embedFactory.d.ts +13 -0
- package/dist/src/embedFactory.d.ts.map +1 -0
- package/dist/src/embedFactory.js +127 -0
- package/dist/src/encoder/accessor.d.ts +3 -12
- package/dist/src/encoder/accessor.d.ts.map +1 -1
- package/dist/src/encoder/accessor.js +10 -65
- package/dist/src/encoder/encoder.d.ts +51 -8
- package/dist/src/encoder/encoder.d.ts.map +1 -1
- package/dist/src/encoder/encoder.js +179 -55
- package/dist/src/fonts/bmFontManager.js +1 -1
- package/dist/src/full.d.ts +2 -0
- package/dist/src/full.d.ts.map +1 -0
- package/dist/src/full.js +2 -0
- package/dist/src/genome/assemblyPreflight.d.ts +31 -0
- package/dist/src/genome/assemblyPreflight.d.ts.map +1 -0
- package/dist/src/genome/assemblyPreflight.js +99 -0
- package/dist/src/genome/genome.d.ts +10 -2
- package/dist/src/genome/genome.d.ts.map +1 -1
- package/dist/src/genome/genome.js +20 -2
- package/dist/src/genome/genomeStore.d.ts +34 -3
- package/dist/src/genome/genomeStore.d.ts.map +1 -1
- package/dist/src/genome/genomeStore.js +409 -18
- package/dist/src/genome/rootGenomeConfig.d.ts +26 -0
- package/dist/src/genome/rootGenomeConfig.d.ts.map +1 -0
- package/dist/src/genome/rootGenomeConfig.js +98 -0
- package/dist/src/genome/scaleLocus.d.ts.map +1 -1
- package/dist/src/genome/scaleLocus.js +26 -7
- package/dist/src/genomeSpy/cursorManager.d.ts +69 -0
- package/dist/src/genomeSpy/cursorManager.d.ts.map +1 -0
- package/dist/src/genomeSpy/cursorManager.js +131 -0
- package/dist/src/genomeSpy/headlessBootstrap.d.ts +113 -0
- package/dist/src/genomeSpy/headlessBootstrap.d.ts.map +1 -0
- package/dist/src/genomeSpy/headlessBootstrap.js +246 -0
- package/dist/src/genomeSpy/interactionController.d.ts +10 -1
- package/dist/src/genomeSpy/interactionController.d.ts.map +1 -1
- package/dist/src/genomeSpy/interactionController.js +448 -40
- package/dist/src/genomeSpy/interactionDispatcher.d.ts +50 -0
- package/dist/src/genomeSpy/interactionDispatcher.d.ts.map +1 -0
- package/dist/src/genomeSpy/interactionDispatcher.js +203 -0
- package/dist/src/genomeSpy/renderCoordinator.js +1 -1
- package/dist/src/genomeSpy/viewContextFactory.d.ts +4 -2
- package/dist/src/genomeSpy/viewContextFactory.d.ts.map +1 -1
- package/dist/src/genomeSpy/viewContextFactory.js +12 -4
- package/dist/src/genomeSpy/viewDataInit.d.ts.map +1 -1
- package/dist/src/genomeSpy/viewDataInit.js +7 -3
- package/dist/src/genomeSpy.d.ts +1 -114
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +7 -614
- package/dist/src/genomeSpyBase.d.ts +133 -0
- package/dist/src/genomeSpyBase.d.ts.map +1 -0
- package/dist/src/genomeSpyBase.js +719 -0
- package/dist/src/gl/arrayBuilder.d.ts.map +1 -1
- package/dist/src/gl/arrayBuilder.js +0 -3
- package/dist/src/gl/canvasSizeHelper.d.ts +74 -0
- package/dist/src/gl/canvasSizeHelper.d.ts.map +1 -0
- package/dist/src/gl/canvasSizeHelper.js +203 -0
- package/dist/src/gl/colorUtils.d.ts.map +1 -1
- package/dist/src/gl/colorUtils.js +3 -0
- package/dist/src/gl/dataToVertices.d.ts.map +1 -1
- package/dist/src/gl/dataToVertices.js +13 -8
- package/dist/src/gl/glslScaleGenerator.d.ts +2 -2
- package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
- package/dist/src/gl/glslScaleGenerator.js +5 -7
- package/dist/src/gl/webGLHelper.d.ts +25 -11
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +59 -33
- package/dist/src/index.d.ts +3 -9
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -111
- package/dist/src/marks/__snapshots__/shaderSnapshot.test.js.snap +4462 -0
- package/dist/src/marks/link.d.ts.map +1 -1
- package/dist/src/marks/link.js +5 -26
- package/dist/src/marks/mark.d.ts +8 -1
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +67 -21
- package/dist/src/marks/markUtils.d.ts +18 -1
- package/dist/src/marks/markUtils.d.ts.map +1 -1
- package/dist/src/marks/markUtils.js +52 -4
- package/dist/src/marks/point.d.ts.map +1 -1
- package/dist/src/marks/point.js +6 -26
- package/dist/src/marks/rect.d.ts.map +1 -1
- package/dist/src/marks/rect.js +13 -21
- package/dist/src/marks/rule.d.ts +7 -2
- package/dist/src/marks/rule.d.ts.map +1 -1
- package/dist/src/marks/rule.js +125 -16
- package/dist/src/marks/text.d.ts.map +1 -1
- package/dist/src/marks/text.js +5 -47
- package/dist/src/minimal.d.ts +8 -0
- package/dist/src/minimal.d.ts.map +1 -0
- package/dist/src/minimal.js +21 -0
- package/dist/src/paramRuntime/viewParamRuntime.d.ts +19 -0
- package/dist/src/paramRuntime/viewParamRuntime.d.ts.map +1 -1
- package/dist/src/paramRuntime/viewParamRuntime.js +35 -0
- package/dist/src/scale/scale.d.ts.map +1 -1
- package/dist/src/scale/scale.js +13 -7
- package/dist/src/scales/axisResolution.d.ts.map +1 -1
- package/dist/src/scales/axisResolution.js +9 -5
- package/dist/src/scales/domainPlanner.d.ts +58 -7
- package/dist/src/scales/domainPlanner.d.ts.map +1 -1
- package/dist/src/scales/domainPlanner.js +395 -40
- package/dist/src/scales/indexLikeDomainUtils.d.ts +29 -0
- package/dist/src/scales/indexLikeDomainUtils.d.ts.map +1 -0
- package/dist/src/scales/indexLikeDomainUtils.js +67 -0
- package/dist/src/scales/resolutionMemberOrder.d.ts +15 -0
- package/dist/src/scales/resolutionMemberOrder.d.ts.map +1 -0
- package/dist/src/scales/resolutionMemberOrder.js +22 -0
- package/dist/src/scales/scaleInstanceManager.d.ts +2 -1
- package/dist/src/scales/scaleInstanceManager.d.ts.map +1 -1
- package/dist/src/scales/scaleInstanceManager.js +10 -11
- package/dist/src/scales/scaleInteractionController.d.ts.map +1 -1
- package/dist/src/scales/scaleInteractionController.js +59 -18
- package/dist/src/scales/scalePropsResolver.d.ts +3 -1
- package/dist/src/scales/scalePropsResolver.d.ts.map +1 -1
- package/dist/src/scales/scalePropsResolver.js +83 -6
- package/dist/src/scales/scaleResolution.d.ts +39 -0
- package/dist/src/scales/scaleResolution.d.ts.map +1 -1
- package/dist/src/scales/scaleResolution.js +504 -82
- package/dist/src/scales/scaleResolutionTestUtils.d.ts +21 -0
- package/dist/src/scales/scaleResolutionTestUtils.d.ts.map +1 -0
- package/dist/src/scales/scaleResolutionTestUtils.js +37 -0
- package/dist/src/scales/scaleRules.d.ts.map +1 -1
- package/dist/src/scales/scaleRules.js +16 -2
- package/dist/src/scales/selectionDomainUtils.d.ts +52 -0
- package/dist/src/scales/selectionDomainUtils.d.ts.map +1 -0
- package/dist/src/scales/selectionDomainUtils.js +194 -0
- package/dist/src/scales/zoomDomainUtils.d.ts +18 -0
- package/dist/src/scales/zoomDomainUtils.d.ts.map +1 -0
- package/dist/src/scales/zoomDomainUtils.js +69 -0
- package/dist/src/screenshotHarness.d.ts +16 -0
- package/dist/src/screenshotHarness.d.ts.map +1 -0
- package/dist/src/screenshotHarness.js +241 -0
- package/dist/src/singlePageApp.js +1 -1
- package/dist/src/spec/axis.d.ts +41 -30
- package/dist/src/spec/channel.d.ts +15 -9
- package/dist/src/spec/config.d.ts +264 -0
- package/dist/src/spec/data.d.ts +30 -3
- package/dist/src/spec/decoration.d.ts +51 -0
- package/dist/src/spec/exampleFiles.d.ts +12 -0
- package/dist/src/spec/exampleFiles.d.ts.map +1 -0
- package/dist/src/spec/exampleFiles.js +52 -0
- package/dist/src/spec/font.d.ts +1 -1
- package/dist/src/spec/genome.d.ts +22 -2
- package/dist/src/spec/mark.d.ts +97 -13
- package/dist/src/spec/parameter.d.ts +62 -5
- package/dist/src/spec/root.d.ts +34 -1
- package/dist/src/spec/scale.d.ts +46 -5
- package/dist/src/spec/title.d.ts +13 -2
- package/dist/src/spec/tooltip.d.ts +1 -1
- package/dist/src/spec/transform.d.ts +39 -4
- package/dist/src/spec/view.d.ts +67 -19
- package/dist/src/styles/genome-spy.css +63 -55
- package/dist/src/styles/genome-spy.css.d.ts +1 -1
- package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
- package/dist/src/styles/genome-spy.css.js +31 -22
- package/dist/src/testSetup.d.ts +2 -0
- package/dist/src/testSetup.d.ts.map +1 -0
- package/dist/src/testSetup.js +5 -0
- package/dist/src/tooltip/dataTooltipHandler.js +66 -11
- package/dist/src/tooltip/tooltipContext.d.ts.map +1 -1
- package/dist/src/tooltip/tooltipContext.js +3 -2
- package/dist/src/types/embedApi.d.ts +26 -0
- package/dist/src/types/encoder.d.ts +17 -15
- package/dist/src/types/scaleResolutionApi.d.ts +20 -0
- package/dist/src/types/viewContext.d.ts +23 -1
- package/dist/src/utils/expression.d.ts +2 -2
- package/dist/src/utils/expression.d.ts.map +1 -1
- package/dist/src/utils/expression.js +63 -8
- package/dist/src/utils/field.d.ts.map +1 -1
- package/dist/src/utils/field.js +0 -1
- package/dist/src/utils/inertia.d.ts.map +1 -1
- package/dist/src/utils/inertia.js +0 -1
- package/dist/src/utils/inferSpecBaseUrl.d.ts +14 -0
- package/dist/src/utils/inferSpecBaseUrl.d.ts.map +1 -0
- package/dist/src/utils/inferSpecBaseUrl.js +73 -0
- package/dist/src/utils/inputBinding.d.ts +1 -1
- package/dist/src/utils/interaction.d.ts +109 -0
- package/dist/src/utils/interaction.d.ts.map +1 -0
- package/dist/src/utils/interaction.js +200 -0
- package/dist/src/utils/interactionEvent.d.ts +62 -33
- package/dist/src/utils/interactionEvent.d.ts.map +1 -1
- package/dist/src/utils/interactionEvent.js +86 -48
- package/dist/src/utils/kWayMerge.js +1 -1
- package/dist/src/utils/mergeObjects.d.ts.map +1 -1
- package/dist/src/utils/mergeObjects.js +0 -2
- package/dist/src/utils/radixSort.d.ts.map +1 -1
- package/dist/src/utils/radixSort.js +0 -2
- package/dist/src/utils/throttle.d.ts.map +1 -1
- package/dist/src/utils/throttle.js +0 -2
- package/dist/src/utils/ui/tooltip.d.ts +1 -0
- package/dist/src/utils/ui/tooltip.d.ts.map +1 -1
- package/dist/src/utils/ui/tooltip.js +1 -0
- package/dist/src/utils/url.js +1 -1
- package/dist/src/view/axisGridView.d.ts +1 -1
- package/dist/src/view/axisGridView.d.ts.map +1 -1
- package/dist/src/view/axisGridView.js +2 -47
- package/dist/src/view/axisView.d.ts +2 -3
- package/dist/src/view/axisView.d.ts.map +1 -1
- package/dist/src/view/axisView.js +251 -106
- package/dist/src/view/concatView.d.ts +2 -1
- package/dist/src/view/concatView.d.ts.map +1 -1
- package/dist/src/view/concatView.js +4 -2
- package/dist/src/view/containerMutationHelper.d.ts +3 -0
- package/dist/src/view/containerMutationHelper.d.ts.map +1 -1
- package/dist/src/view/containerMutationHelper.js +12 -1
- package/dist/src/view/dataReadiness.d.ts +2 -2
- package/dist/src/view/dataReadiness.d.ts.map +1 -1
- package/dist/src/view/dataReadiness.js +63 -58
- package/dist/src/view/facetView.d.ts +1 -1
- package/dist/src/view/facetView.js +4 -4
- package/dist/src/view/flowBuilder.js +2 -2
- package/dist/src/view/gridView/gridChild.d.ts +13 -0
- package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
- package/dist/src/view/gridView/gridChild.js +247 -49
- package/dist/src/view/gridView/gridView.d.ts.map +1 -1
- package/dist/src/view/gridView/gridView.js +296 -99
- package/dist/src/view/gridView/keyboardZoomController.d.ts +2 -2
- package/dist/src/view/gridView/keyboardZoomController.d.ts.map +1 -1
- package/dist/src/view/gridView/keyboardZoomController.js +1 -1
- package/dist/src/view/gridView/scrollbar.d.ts.map +1 -1
- package/dist/src/view/gridView/scrollbar.js +4 -2
- package/dist/src/view/gridView/selectionRect.d.ts +4 -0
- package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
- package/dist/src/view/gridView/selectionRect.js +20 -1
- package/dist/src/view/gridView/separatorView.d.ts +1 -0
- package/dist/src/view/gridView/separatorView.d.ts.map +1 -1
- package/dist/src/view/gridView/separatorView.js +9 -0
- package/dist/src/view/interactionRouting.d.ts +20 -0
- package/dist/src/view/interactionRouting.d.ts.map +1 -0
- package/dist/src/view/interactionRouting.js +53 -0
- package/dist/src/view/layerView.d.ts.map +1 -1
- package/dist/src/view/layerView.js +12 -9
- package/dist/src/view/layout/grid.js +1 -1
- package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts.map +1 -1
- package/dist/src/view/renderingContext/bufferedViewRenderingContext.js +0 -2
- package/dist/src/view/testUtils.d.ts +17 -3
- package/dist/src/view/testUtils.d.ts.map +1 -1
- package/dist/src/view/testUtils.js +62 -69
- package/dist/src/view/title.d.ts +8 -1
- package/dist/src/view/title.d.ts.map +1 -1
- package/dist/src/view/title.js +66 -76
- package/dist/src/view/unitView.d.ts +1 -1
- package/dist/src/view/unitView.d.ts.map +1 -1
- package/dist/src/view/unitView.js +67 -17
- package/dist/src/view/view.d.ts +76 -30
- package/dist/src/view/view.d.ts.map +1 -1
- package/dist/src/view/view.js +136 -47
- package/dist/src/view/viewFactory.d.ts +11 -3
- package/dist/src/view/viewFactory.d.ts.map +1 -1
- package/dist/src/view/viewFactory.js +37 -11
- package/dist/src/view/viewUtils.d.ts.map +1 -1
- package/dist/src/view/viewUtils.js +41 -5
- package/dist/src/view/zoom.d.ts +15 -3
- package/dist/src/view/zoom.d.ts.map +1 -1
- package/dist/src/view/zoom.js +375 -80
- package/package.json +20 -10
- package/dist/bundle/AbortablePromiseCache-Dj0vzLnp.js +0 -149
- package/dist/bundle/browser-0iNU5Wit.js +0 -138
- package/dist/bundle/index-BYsZN7b0.js +0 -1597
- package/dist/bundle/index-C3kClAEN.js +0 -1771
- package/dist/bundle/index-C7wOh6y1.js +0 -657
- package/dist/bundle/index-CRaQAuki.js +0 -326
- package/dist/bundle/index-D9v1PCj9.js +0 -507
- package/dist/bundle/index-GDOuv_D5.js +0 -266
- package/dist/bundle/index-Gt44EOIH.js +0 -628
- package/dist/bundle/inflate-GtwLkvSP.js +0 -1048
- package/dist/bundle/parquetRead-BnAGCa4_.js +0 -1663
- package/dist/bundle/unzip-Bac01w6X.js +0 -1492
- package/dist/src/config/scaleDefaults.d.ts +0 -8
- package/dist/src/config/scaleDefaults.d.ts.map +0 -1
- package/dist/src/config/scaleDefaults.js +0 -45
|
@@ -24,10 +24,21 @@ import {
|
|
|
24
24
|
} from "./scaleResolutionConstants.js";
|
|
25
25
|
|
|
26
26
|
import { getAccessorDomainKey } from "../encoder/accessor.js";
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
isPrimaryPositionalChannel,
|
|
29
|
+
isSecondaryChannel,
|
|
30
|
+
} from "../encoder/encoder.js";
|
|
28
31
|
import { NominalDomain } from "../utils/domainArray.js";
|
|
29
32
|
import { shallowArrayEquals } from "../utils/arrayUtils.js";
|
|
30
33
|
import createIndexer from "../utils/indexer.js";
|
|
34
|
+
import { getCachedOrCall, invalidate } from "../utils/propertyCacher.js";
|
|
35
|
+
import { resolveUrl } from "../utils/url.js";
|
|
36
|
+
import {
|
|
37
|
+
findIntervalSelectionBindingOwners,
|
|
38
|
+
normalizeIntervalForSelection,
|
|
39
|
+
requireIntervalSelection,
|
|
40
|
+
} from "./selectionDomainUtils.js";
|
|
41
|
+
import { toExternalIndexLikeInterval } from "./indexLikeDomainUtils.js";
|
|
31
42
|
|
|
32
43
|
// Register scaleLocus to Vega-Scale.
|
|
33
44
|
// Loci are discrete but the scale's domain can be adjusted in a continuous manner.
|
|
@@ -111,6 +122,16 @@ export default class ScaleResolution {
|
|
|
111
122
|
|
|
112
123
|
#categoricalIndexerExplicit = false;
|
|
113
124
|
|
|
125
|
+
/** @type {(() => void)[]} */
|
|
126
|
+
#selectionDomainParamUnsubscribers = [];
|
|
127
|
+
|
|
128
|
+
#selectionReverseSyncSuppressionDepth = 0;
|
|
129
|
+
|
|
130
|
+
#ignoreSelectionInitial = false;
|
|
131
|
+
|
|
132
|
+
/** @type {[number, number] | null | undefined} */
|
|
133
|
+
#lastLinkedSelectionInterval = undefined;
|
|
134
|
+
|
|
114
135
|
/**
|
|
115
136
|
* @param {Channel} channel
|
|
116
137
|
*/
|
|
@@ -124,10 +145,11 @@ export default class ScaleResolution {
|
|
|
124
145
|
|
|
125
146
|
this.#domainAggregator = new DomainPlanner({
|
|
126
147
|
getMembers: () => this.#getActiveMembers(),
|
|
148
|
+
getAllMembers: () => this.#members,
|
|
127
149
|
getDataMembers: () =>
|
|
128
150
|
this.#getActiveMembers(this.#dataDomainMembers),
|
|
129
151
|
getType: () => this.type,
|
|
130
|
-
getLocusExtent: () => this.#getLocusExtent(),
|
|
152
|
+
getLocusExtent: (assembly) => this.#getLocusExtent(assembly),
|
|
131
153
|
fromComplexInterval: this.fromComplexInterval.bind(this),
|
|
132
154
|
});
|
|
133
155
|
|
|
@@ -143,8 +165,7 @@ export default class ScaleResolution {
|
|
|
143
165
|
getAnimator: () => this.#viewContext.animator,
|
|
144
166
|
getInitialDomainSnapshot: () =>
|
|
145
167
|
this.#domainAggregator.initialDomainSnapshot,
|
|
146
|
-
getResetDomain: () =>
|
|
147
|
-
this.#domainAggregator.getConfiguredOrDefaultDomain(),
|
|
168
|
+
getResetDomain: () => this.#getConfiguredOrDefaultDomain(),
|
|
148
169
|
fromComplexInterval: this.fromComplexInterval.bind(this),
|
|
149
170
|
getGenomeExtent: () => this.#getLocusExtent(),
|
|
150
171
|
});
|
|
@@ -200,21 +221,24 @@ export default class ScaleResolution {
|
|
|
200
221
|
}
|
|
201
222
|
|
|
202
223
|
/**
|
|
224
|
+
* @param {import("../spec/scale.js").Scale["assembly"]} [assembly]
|
|
203
225
|
* @returns {number[]}
|
|
204
226
|
*/
|
|
205
|
-
#getLocusExtent() {
|
|
206
|
-
return getGenomeExtent(this.#getGenomeSource());
|
|
227
|
+
#getLocusExtent(assembly) {
|
|
228
|
+
return getGenomeExtent(this.#getGenomeSource(assembly));
|
|
207
229
|
}
|
|
208
230
|
|
|
209
231
|
/**
|
|
232
|
+
* @param {import("../spec/scale.js").Scale["assembly"]} [assembly]
|
|
210
233
|
* @returns {import("../genome/scaleLocus.js").GenomeSource}
|
|
211
234
|
*/
|
|
212
|
-
#getGenomeSource() {
|
|
235
|
+
#getGenomeSource(assembly) {
|
|
213
236
|
if (this.type !== LOCUS) {
|
|
214
237
|
return undefined;
|
|
215
238
|
}
|
|
216
239
|
return /** @type {import("../genome/scaleLocus.js").GenomeSource} */ (
|
|
217
|
-
this.#scaleManager.scale ??
|
|
240
|
+
this.#scaleManager.scale ??
|
|
241
|
+
this.#scaleManager.getLocusGenome(assembly)
|
|
218
242
|
);
|
|
219
243
|
}
|
|
220
244
|
|
|
@@ -242,6 +266,13 @@ export default class ScaleResolution {
|
|
|
242
266
|
* @param {ScaleResolutionEventType} type
|
|
243
267
|
*/
|
|
244
268
|
#notifyListeners(type) {
|
|
269
|
+
if (
|
|
270
|
+
type === "domain" &&
|
|
271
|
+
this.#selectionReverseSyncSuppressionDepth === 0
|
|
272
|
+
) {
|
|
273
|
+
this.syncLinkedSelectionFromDomain();
|
|
274
|
+
}
|
|
275
|
+
|
|
245
276
|
for (const listener of this.#listeners[type].values()) {
|
|
246
277
|
listener({
|
|
247
278
|
type,
|
|
@@ -250,14 +281,139 @@ export default class ScaleResolution {
|
|
|
250
281
|
}
|
|
251
282
|
}
|
|
252
283
|
|
|
284
|
+
/**
|
|
285
|
+
* @param {() => void} callback
|
|
286
|
+
*/
|
|
287
|
+
#withSelectionReverseSyncSuppressed(callback) {
|
|
288
|
+
this.#selectionReverseSyncSuppressionDepth += 1;
|
|
289
|
+
try {
|
|
290
|
+
callback();
|
|
291
|
+
} finally {
|
|
292
|
+
this.#selectionReverseSyncSuppressionDepth -= 1;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
syncLinkedSelectionFromDomain() {
|
|
297
|
+
const linkInfo =
|
|
298
|
+
this.#domainAggregator.getSelectionConfiguredDomainBindingInfo();
|
|
299
|
+
if (!linkInfo || !this.isZoomable()) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const selection = requireIntervalSelection(
|
|
304
|
+
linkInfo.runtime.getValue(linkInfo.param),
|
|
305
|
+
linkInfo.param
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
const interval = this.#normalizeDomainIntervalForLinkedSelection(
|
|
309
|
+
this.getScale().domain()
|
|
310
|
+
);
|
|
311
|
+
if (!interval) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const fallbackInterval =
|
|
316
|
+
this.#normalizeDomainIntervalForLinkedSelection(
|
|
317
|
+
this.#domainAggregator.getDefaultDomain(true)
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
const syncedInterval =
|
|
321
|
+
fallbackInterval && shallowArrayEquals(interval, fallbackInterval)
|
|
322
|
+
? null
|
|
323
|
+
: interval;
|
|
324
|
+
|
|
325
|
+
const previousInterval = selection.intervals[linkInfo.encoding] ?? null;
|
|
326
|
+
if (intervalsEqual(previousInterval, syncedInterval)) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
linkInfo.runtime.setValue(linkInfo.param, {
|
|
331
|
+
...selection,
|
|
332
|
+
type: "interval",
|
|
333
|
+
intervals: {
|
|
334
|
+
...selection.intervals,
|
|
335
|
+
[linkInfo.encoding]: syncedInterval,
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* @param {any[]} domain
|
|
342
|
+
* @returns {[number, number] | undefined}
|
|
343
|
+
*/
|
|
344
|
+
#normalizeDomainIntervalForLinkedSelection(domain) {
|
|
345
|
+
return normalizeIntervalForSelection(domain, this.zoomExtent);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
#getLinkedSelectionInfo() {
|
|
349
|
+
return this.#domainAggregator.getSelectionConfiguredDomainBindingInfo();
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
#shouldIncludeSelectionInitial() {
|
|
353
|
+
return !this.#ignoreSelectionInitial;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* @param {boolean} [extractDataDomain]
|
|
358
|
+
* @param {import("../spec/scale.js").Scale["assembly"]} [locusAssembly]
|
|
359
|
+
* @returns {any[]}
|
|
360
|
+
*/
|
|
361
|
+
#getConfiguredOrDefaultDomain(extractDataDomain = false, locusAssembly) {
|
|
362
|
+
return this.#domainAggregator.getConfiguredOrDefaultDomain(
|
|
363
|
+
extractDataDomain,
|
|
364
|
+
locusAssembly,
|
|
365
|
+
{
|
|
366
|
+
includeSelectionInitial: this.#shouldIncludeSelectionInitial(),
|
|
367
|
+
}
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* @returns {boolean}
|
|
373
|
+
*/
|
|
374
|
+
#hasConfiguredDomain() {
|
|
375
|
+
return this.#domainAggregator.hasConfiguredDomain({
|
|
376
|
+
includeSelectionInitial: this.#shouldIncludeSelectionInitial(),
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* @param {import("./domainPlanner.js").SelectionDomainLinkInfo} linkInfo
|
|
382
|
+
* @returns {[number, number] | null}
|
|
383
|
+
*/
|
|
384
|
+
#getCurrentLinkedSelectionInterval(linkInfo) {
|
|
385
|
+
const selection = requireIntervalSelection(
|
|
386
|
+
linkInfo.runtime.getValue(linkInfo.param),
|
|
387
|
+
linkInfo.param
|
|
388
|
+
);
|
|
389
|
+
const interval = selection.intervals[linkInfo.encoding];
|
|
390
|
+
return interval && interval.length === 2
|
|
391
|
+
? /** @type {[number, number]} */ (interval)
|
|
392
|
+
: null;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* @param {[number, number] | null} previousInterval
|
|
397
|
+
* @param {[number, number] | null} nextInterval
|
|
398
|
+
*/
|
|
399
|
+
#updateSelectionInitialBypass(previousInterval, nextInterval) {
|
|
400
|
+
if (nextInterval) {
|
|
401
|
+
this.#ignoreSelectionInitial = false;
|
|
402
|
+
} else if (previousInterval) {
|
|
403
|
+
this.#ignoreSelectionInitial = true;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
253
407
|
/**
|
|
254
408
|
* Add a view to this resolution.
|
|
255
409
|
* N.B. This is expected to be called in depth-first order
|
|
256
410
|
*
|
|
257
411
|
* @param {ScaleResolutionMember} newMember
|
|
412
|
+
* @returns {ScaleResolutionMember}
|
|
258
413
|
*/
|
|
259
414
|
#addMember(newMember) {
|
|
260
|
-
const
|
|
415
|
+
const member = normalizeMember(newMember);
|
|
416
|
+
const { channel, channelDef } = member;
|
|
261
417
|
|
|
262
418
|
// A convenience hack for cases where the new member should adapt
|
|
263
419
|
// the scale type to the existing one. For example: SelectionRect
|
|
@@ -283,6 +439,20 @@ export default class ScaleResolution {
|
|
|
283
439
|
// @ts-expect-error "sample" is not really a channel with scale
|
|
284
440
|
const type = channel == "sample" ? "nominal" : channelDef.type;
|
|
285
441
|
const name = channelDef?.scale?.name;
|
|
442
|
+
const explicitScaleType = channelDef.scale?.type;
|
|
443
|
+
const effectiveScaleType =
|
|
444
|
+
explicitScaleType ??
|
|
445
|
+
(type === INDEX || type === LOCUS ? type : undefined);
|
|
446
|
+
|
|
447
|
+
if (
|
|
448
|
+
effectiveScaleType &&
|
|
449
|
+
[INDEX, LOCUS].includes(effectiveScaleType) &&
|
|
450
|
+
!isPrimaryPositionalChannel(this.channel)
|
|
451
|
+
) {
|
|
452
|
+
throw new Error(
|
|
453
|
+
`Index and locus scales are only supported on positional channels (x/y). Channel "${this.channel}" resolves to scale type "${effectiveScaleType}".`
|
|
454
|
+
);
|
|
455
|
+
}
|
|
286
456
|
|
|
287
457
|
if (name) {
|
|
288
458
|
if (this.name !== undefined && name != this.name) {
|
|
@@ -297,20 +467,26 @@ export default class ScaleResolution {
|
|
|
297
467
|
if (!this.type) {
|
|
298
468
|
this.type = type;
|
|
299
469
|
} else if (type !== this.type && !isSecondaryChannel(channel)) {
|
|
470
|
+
// TODO: Revisit shared discrete positional scales when
|
|
471
|
+
// implementing Vega-Lite-like band-vs-point inference.
|
|
472
|
+
// Nominal/ordinal members should be able to share a scale even
|
|
473
|
+
// if one member wants "point" and another wants "band"; the
|
|
474
|
+
// merged result should resolve to "band". Explicit
|
|
475
|
+
// user-specified incompatible scale types should still error.
|
|
300
476
|
// TODO: Include a reference to the layer
|
|
301
477
|
throw new Error(
|
|
302
478
|
`Can not use shared scale for different data types: ${this.type} vs. ${type}. Use "resolve: independent" for channel ${this.channel}`
|
|
303
479
|
);
|
|
304
|
-
// Actually, point scale could be changed into band scale
|
|
305
|
-
// TODO: Use the same merging logic as in: https://github.com/vega/vega-lite/blob/master/src/scale.ts
|
|
306
480
|
}
|
|
307
481
|
}
|
|
308
482
|
|
|
309
|
-
this.#members.add(
|
|
310
|
-
if (
|
|
311
|
-
this.#dataDomainMembers.add(
|
|
483
|
+
this.#members.add(member);
|
|
484
|
+
if (member.contributesToDomain) {
|
|
485
|
+
this.#dataDomainMembers.add(member);
|
|
312
486
|
}
|
|
313
|
-
this.#
|
|
487
|
+
this.#invalidateConfiguredDomain();
|
|
488
|
+
this.#refreshSelectionDomainParamSubscriptions();
|
|
489
|
+
return member;
|
|
314
490
|
}
|
|
315
491
|
|
|
316
492
|
/**
|
|
@@ -318,23 +494,64 @@ export default class ScaleResolution {
|
|
|
318
494
|
* @returns {() => boolean}
|
|
319
495
|
*/
|
|
320
496
|
registerMember(member) {
|
|
321
|
-
this.#addMember(member);
|
|
497
|
+
const registeredMember = this.#addMember(member);
|
|
322
498
|
return () => {
|
|
323
|
-
const removed = this.#members.delete(
|
|
499
|
+
const removed = this.#members.delete(registeredMember);
|
|
324
500
|
if (removed) {
|
|
325
|
-
this.#dataDomainMembers.delete(
|
|
326
|
-
this.#
|
|
501
|
+
this.#dataDomainMembers.delete(registeredMember);
|
|
502
|
+
this.#invalidateConfiguredDomain();
|
|
503
|
+
this.#refreshSelectionDomainParamSubscriptions();
|
|
327
504
|
}
|
|
328
505
|
return removed && this.#members.size === 0;
|
|
329
506
|
};
|
|
330
507
|
}
|
|
331
508
|
|
|
332
509
|
dispose() {
|
|
510
|
+
this.#clearSelectionDomainParamSubscriptions();
|
|
333
511
|
this.#listeners.domain.clear();
|
|
334
512
|
this.#listeners.range.clear();
|
|
335
513
|
this.#scaleManager.dispose();
|
|
336
514
|
}
|
|
337
515
|
|
|
516
|
+
#clearSelectionDomainParamSubscriptions() {
|
|
517
|
+
for (const unsubscribe of this.#selectionDomainParamUnsubscribers) {
|
|
518
|
+
unsubscribe();
|
|
519
|
+
}
|
|
520
|
+
this.#selectionDomainParamUnsubscribers = [];
|
|
521
|
+
this.#lastLinkedSelectionInterval = undefined;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
#refreshSelectionDomainParamSubscriptions() {
|
|
525
|
+
this.#clearSelectionDomainParamSubscriptions();
|
|
526
|
+
|
|
527
|
+
if (this.#members.size === 0) {
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const linkInfo = this.#getLinkedSelectionInfo();
|
|
532
|
+
if (!linkInfo) {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
this.#lastLinkedSelectionInterval =
|
|
537
|
+
this.#getCurrentLinkedSelectionInterval(linkInfo);
|
|
538
|
+
|
|
539
|
+
this.#selectionDomainParamUnsubscribers.push(
|
|
540
|
+
linkInfo.runtime.subscribe(linkInfo.param, () => {
|
|
541
|
+
const previousInterval = this.#lastLinkedSelectionInterval;
|
|
542
|
+
const currentInterval =
|
|
543
|
+
this.#getCurrentLinkedSelectionInterval(linkInfo);
|
|
544
|
+
this.#updateSelectionInitialBypass(
|
|
545
|
+
previousInterval,
|
|
546
|
+
currentInterval
|
|
547
|
+
);
|
|
548
|
+
this.#lastLinkedSelectionInterval = currentInterval;
|
|
549
|
+
this.#invalidateConfiguredDomain();
|
|
550
|
+
this.reconfigureDomain();
|
|
551
|
+
})
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
|
|
338
555
|
#hasRenderedMember() {
|
|
339
556
|
for (const member of this.#members) {
|
|
340
557
|
if (member.view.hasRendered()) {
|
|
@@ -386,11 +603,11 @@ export default class ScaleResolution {
|
|
|
386
603
|
/**
|
|
387
604
|
* Returns true if the domain has been defined explicitly, i.e. not extracted from the data.
|
|
388
605
|
*/
|
|
389
|
-
|
|
390
|
-
return this.#
|
|
606
|
+
isDomainDefinedExplicitly() {
|
|
607
|
+
return this.#hasConfiguredDomain();
|
|
391
608
|
}
|
|
392
609
|
|
|
393
|
-
|
|
610
|
+
isDomainInitialized() {
|
|
394
611
|
const s = this.#scaleManager.scale;
|
|
395
612
|
if (!s) {
|
|
396
613
|
return false;
|
|
@@ -416,14 +633,92 @@ export default class ScaleResolution {
|
|
|
416
633
|
* @returns {import("../spec/scale.js").Scale}
|
|
417
634
|
*/
|
|
418
635
|
#getMergedScaleProps() {
|
|
419
|
-
return
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
636
|
+
return getCachedOrCall(this, "mergedScaleProps", () => {
|
|
637
|
+
const props = resolveScalePropsBase({
|
|
638
|
+
channel: this.channel,
|
|
639
|
+
dataType: this.type,
|
|
640
|
+
members: this.#members,
|
|
641
|
+
isExplicitDomain: this.isDomainDefinedExplicitly(),
|
|
642
|
+
configScopes: this.#firstMemberView.getConfigScopes(),
|
|
643
|
+
});
|
|
644
|
+
this.#validateLinkedSelectionConfiguration(props);
|
|
645
|
+
return props;
|
|
424
646
|
});
|
|
425
647
|
}
|
|
426
648
|
|
|
649
|
+
#invalidateMergedScaleProps() {
|
|
650
|
+
invalidate(this, "mergedScaleProps");
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
#invalidateConfiguredDomain() {
|
|
654
|
+
this.#domainAggregator.invalidateConfiguredDomain();
|
|
655
|
+
this.#invalidateMergedScaleProps();
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* @param {import("../spec/scale.js").Scale} props
|
|
660
|
+
*/
|
|
661
|
+
#validateLinkedSelectionConfiguration(props) {
|
|
662
|
+
const linkInfo = this.#getLinkedSelectionInfo();
|
|
663
|
+
if (!linkInfo || props === null || props.type === "null") {
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
const isZoomable =
|
|
668
|
+
isContinuous(props.type) && !isDiscrete(props.type) && !!props.zoom;
|
|
669
|
+
|
|
670
|
+
if (linkInfo.hasInitial && !isZoomable) {
|
|
671
|
+
throw new Error(
|
|
672
|
+
`Selection domain reference "${linkInfo.param}.${linkInfo.encoding}" cannot use "initial" with a non-zoomable ${this.channel} scale. ` +
|
|
673
|
+
`Enable zoom on the linked scale or remove "initial".`
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Returns locus assembly requirements without initializing the scale.
|
|
680
|
+
*
|
|
681
|
+
* This is intentionally side-effect free: it only inspects merged scale
|
|
682
|
+
* properties from registered members and does not touch default domains or
|
|
683
|
+
* instantiate scale instances.
|
|
684
|
+
*
|
|
685
|
+
* @returns {{
|
|
686
|
+
* assembly: import("../spec/scale.js").Scale["assembly"] | undefined,
|
|
687
|
+
* needsDefaultAssembly: boolean
|
|
688
|
+
* }}
|
|
689
|
+
*/
|
|
690
|
+
getAssemblyRequirement() {
|
|
691
|
+
const props = this.#getMergedScaleProps();
|
|
692
|
+
if (props === null || props.type === "null" || props.type !== LOCUS) {
|
|
693
|
+
return {
|
|
694
|
+
assembly: undefined,
|
|
695
|
+
needsDefaultAssembly: false,
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
return {
|
|
700
|
+
assembly: props.assembly,
|
|
701
|
+
needsDefaultAssembly: props.assembly === undefined,
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Returns the resolved scale type without instantiating the scale.
|
|
707
|
+
*
|
|
708
|
+
* Useful during view construction, before assembly preflight has loaded
|
|
709
|
+
* URL-backed locus genomes.
|
|
710
|
+
*
|
|
711
|
+
* @returns {import("../spec/scale.js").Scale["type"] | undefined}
|
|
712
|
+
*/
|
|
713
|
+
getResolvedScaleType() {
|
|
714
|
+
const props = this.#getMergedScaleProps();
|
|
715
|
+
if (props === null || props.type === "null") {
|
|
716
|
+
return undefined;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
return props.type;
|
|
720
|
+
}
|
|
721
|
+
|
|
427
722
|
/**
|
|
428
723
|
* Returns the merged scale properties supplemented with inferred properties
|
|
429
724
|
* and domain.
|
|
@@ -439,13 +734,15 @@ export default class ScaleResolution {
|
|
|
439
734
|
return { type: "null" };
|
|
440
735
|
}
|
|
441
736
|
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
737
|
+
const resolvedProps = { ...props };
|
|
738
|
+
|
|
739
|
+
const domain = this.#getConfiguredOrDefaultDomain(
|
|
740
|
+
extractDataDomain,
|
|
741
|
+
resolvedProps.type === LOCUS ? resolvedProps.assembly : undefined
|
|
742
|
+
);
|
|
446
743
|
|
|
447
|
-
if (isDiscrete(
|
|
448
|
-
const isExplicit = this
|
|
744
|
+
if (isDiscrete(resolvedProps.type)) {
|
|
745
|
+
const isExplicit = this.isDomainDefinedExplicitly();
|
|
449
746
|
const indexer = this.#getCategoricalIndexer(isExplicit);
|
|
450
747
|
if (domain != null) {
|
|
451
748
|
if (
|
|
@@ -461,7 +758,7 @@ export default class ScaleResolution {
|
|
|
461
758
|
const indexedDomain = indexer
|
|
462
759
|
.domain()
|
|
463
760
|
.filter((value) => active.has(value));
|
|
464
|
-
|
|
761
|
+
resolvedProps.domain =
|
|
465
762
|
indexedDomain.length > 0
|
|
466
763
|
? /** @type {import("../spec/scale.js").ScalarDomain} */ (
|
|
467
764
|
indexedDomain
|
|
@@ -469,7 +766,7 @@ export default class ScaleResolution {
|
|
|
469
766
|
: new NominalDomain();
|
|
470
767
|
} else {
|
|
471
768
|
const indexedDomain = indexer.domain();
|
|
472
|
-
|
|
769
|
+
resolvedProps.domain =
|
|
473
770
|
indexedDomain.length > 0
|
|
474
771
|
? /** @type {import("../spec/scale.js").ScalarDomain} */ (
|
|
475
772
|
indexedDomain
|
|
@@ -477,18 +774,21 @@ export default class ScaleResolution {
|
|
|
477
774
|
: new NominalDomain();
|
|
478
775
|
}
|
|
479
776
|
// Scale props are spec-shaped; keep the indexer off the public type.
|
|
480
|
-
/** @type {any} */ (
|
|
777
|
+
/** @type {any} */ (resolvedProps).domainIndexer = indexer;
|
|
481
778
|
} else if (domain && domain.length > 0) {
|
|
482
|
-
|
|
779
|
+
resolvedProps.domain = domain;
|
|
483
780
|
}
|
|
484
781
|
|
|
485
|
-
if (!
|
|
782
|
+
if (!resolvedProps.domain && resolvedProps.domainMid !== undefined) {
|
|
486
783
|
// Initialize with a bogus domain so that scale.js can inject the domainMid.
|
|
487
784
|
// The number of domain elements must be know before the glsl scale is generated.
|
|
488
|
-
|
|
785
|
+
resolvedProps.domain = [
|
|
786
|
+
resolvedProps.domainMin ?? 0,
|
|
787
|
+
resolvedProps.domainMax ?? 1,
|
|
788
|
+
];
|
|
489
789
|
}
|
|
490
790
|
|
|
491
|
-
return
|
|
791
|
+
return resolvedProps;
|
|
492
792
|
}
|
|
493
793
|
|
|
494
794
|
/**
|
|
@@ -512,15 +812,17 @@ export default class ScaleResolution {
|
|
|
512
812
|
* or when scale properties are otherwise re-resolved from the view hierarchy.
|
|
513
813
|
*/
|
|
514
814
|
reconfigure() {
|
|
515
|
-
this.#
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
this.#
|
|
522
|
-
|
|
523
|
-
|
|
815
|
+
this.#withSelectionReverseSyncSuppressed(() => {
|
|
816
|
+
this.#invalidateConfiguredDomain();
|
|
817
|
+
const state = this.#computeScaleState(true);
|
|
818
|
+
if (!state) {
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
this.#applyReconfigure(state, (scale, props) =>
|
|
822
|
+
this.#scaleManager.reconfigureScale(props)
|
|
823
|
+
);
|
|
824
|
+
this.#finalizeReconfigure(state);
|
|
825
|
+
});
|
|
524
826
|
}
|
|
525
827
|
|
|
526
828
|
/**
|
|
@@ -530,28 +832,32 @@ export default class ScaleResolution {
|
|
|
530
832
|
*
|
|
531
833
|
*/
|
|
532
834
|
reconfigureDomain() {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
targetDomain
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
835
|
+
this.#withSelectionReverseSyncSuppressed(() => {
|
|
836
|
+
this.#invalidateMergedScaleProps();
|
|
837
|
+
const state = this.#computeScaleState(true, true);
|
|
838
|
+
if (!state) {
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
const { domainConfig, targetDomain } = state;
|
|
842
|
+
const domainMatches =
|
|
843
|
+
targetDomain != null &&
|
|
844
|
+
shallowArrayEquals(targetDomain, state.scale.domain());
|
|
845
|
+
|
|
846
|
+
if (targetDomain != null && !domainMatches) {
|
|
847
|
+
this.#applyReconfigure(state, (scale) => {
|
|
848
|
+
scale.domain(targetDomain);
|
|
849
|
+
if (domainConfig.applyOrdinalUnknown) {
|
|
850
|
+
// Keep ordinal unknown handling close to the domain write so
|
|
851
|
+
// domainImplicit semantics stay aligned with the applied domain.
|
|
852
|
+
/** @type {any} */ (scale).unknown(
|
|
853
|
+
domainConfig.ordinalUnknown
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
this.#finalizeReconfigure(state);
|
|
859
|
+
this.syncLinkedSelectionFromDomain();
|
|
860
|
+
});
|
|
555
861
|
}
|
|
556
862
|
|
|
557
863
|
/**
|
|
@@ -562,6 +868,7 @@ export default class ScaleResolution {
|
|
|
562
868
|
* props: import("../spec/scale.js").Scale,
|
|
563
869
|
* previousDomain: any[],
|
|
564
870
|
* domainWasInitialized: boolean,
|
|
871
|
+
* hasSelectionConfiguredDomain: boolean,
|
|
565
872
|
* domainConfig?: ReturnType<typeof configureDomain>,
|
|
566
873
|
* targetDomain?: any[] | null,
|
|
567
874
|
* } | undefined}
|
|
@@ -577,7 +884,9 @@ export default class ScaleResolution {
|
|
|
577
884
|
scale,
|
|
578
885
|
props: this.#getScaleProps(extractDataDomain),
|
|
579
886
|
previousDomain: scale.domain(),
|
|
580
|
-
domainWasInitialized: this
|
|
887
|
+
domainWasInitialized: this.isDomainInitialized(),
|
|
888
|
+
hasSelectionConfiguredDomain:
|
|
889
|
+
this.#domainAggregator.hasSelectionConfiguredDomain(),
|
|
581
890
|
};
|
|
582
891
|
|
|
583
892
|
if (includeDomainConfig) {
|
|
@@ -610,15 +919,26 @@ export default class ScaleResolution {
|
|
|
610
919
|
* scale: ScaleWithProps,
|
|
611
920
|
* previousDomain: any[],
|
|
612
921
|
* domainWasInitialized: boolean,
|
|
922
|
+
* hasSelectionConfiguredDomain: boolean,
|
|
613
923
|
* }} inputs
|
|
614
924
|
*/
|
|
615
925
|
#finalizeReconfigure(inputs) {
|
|
616
|
-
const {
|
|
926
|
+
const {
|
|
927
|
+
scale,
|
|
928
|
+
previousDomain,
|
|
929
|
+
domainWasInitialized,
|
|
930
|
+
hasSelectionConfiguredDomain,
|
|
931
|
+
} = inputs;
|
|
932
|
+
|
|
933
|
+
const initialDomainSnapshot = hasSelectionConfiguredDomain
|
|
934
|
+
? this.#domainAggregator.getDefaultDomain(true)
|
|
935
|
+
: undefined;
|
|
617
936
|
|
|
618
937
|
if (
|
|
619
938
|
this.#domainAggregator.captureInitialDomain(
|
|
620
939
|
scale,
|
|
621
|
-
domainWasInitialized
|
|
940
|
+
domainWasInitialized,
|
|
941
|
+
initialDomainSnapshot
|
|
622
942
|
)
|
|
623
943
|
) {
|
|
624
944
|
// Domain changes were suppressed during reconfigure; notify explicitly.
|
|
@@ -633,12 +953,22 @@ export default class ScaleResolution {
|
|
|
633
953
|
);
|
|
634
954
|
|
|
635
955
|
if (action === "restore") {
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
956
|
+
if (hasSelectionConfiguredDomain) {
|
|
957
|
+
// Selection-linked domains are the source of truth and must not
|
|
958
|
+
// be overridden by previously zoomed domains.
|
|
959
|
+
this.#notifyListeners("domain");
|
|
960
|
+
} else {
|
|
961
|
+
// Don't mess with zoomed views, restore the previous domain
|
|
962
|
+
this.#scaleManager.withDomainNotificationsSuppressed(() => {
|
|
963
|
+
scale.domain(previousDomain);
|
|
964
|
+
});
|
|
965
|
+
}
|
|
640
966
|
} else if (action === "animate") {
|
|
641
|
-
if (
|
|
967
|
+
if (hasSelectionConfiguredDomain) {
|
|
968
|
+
// Linked domains can update continuously (e.g., brushing), so
|
|
969
|
+
// skip zoomTo transitions and apply domain updates directly.
|
|
970
|
+
this.#notifyListeners("domain");
|
|
971
|
+
} else if (this.#hasRenderedMember()) {
|
|
642
972
|
// It can be zoomed, so lets make a smooth transition.
|
|
643
973
|
// Restore the previous domain and zoom smoothly to the new domain.
|
|
644
974
|
this.#scaleManager.withDomainNotificationsSuppressed(() => {
|
|
@@ -712,10 +1042,39 @@ export default class ScaleResolution {
|
|
|
712
1042
|
*/
|
|
713
1043
|
getComplexDomain() {
|
|
714
1044
|
return /** @type {NumericDomain | ComplexDomain} */ (
|
|
715
|
-
toComplexInterval(
|
|
1045
|
+
toComplexInterval(
|
|
1046
|
+
this.#getGenomeSource(),
|
|
1047
|
+
toExternalIndexLikeInterval(this.type, this.getDomain())
|
|
1048
|
+
)
|
|
716
1049
|
);
|
|
717
1050
|
}
|
|
718
1051
|
|
|
1052
|
+
/**
|
|
1053
|
+
* Returns metadata about a selection-linked domain, if present.
|
|
1054
|
+
*/
|
|
1055
|
+
getLinkedSelectionDomainInfo() {
|
|
1056
|
+
const linkInfo = this.#getLinkedSelectionInfo();
|
|
1057
|
+
if (!linkInfo) {
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
const root = this.#firstMemberView.getLayoutAncestors().at(-1);
|
|
1062
|
+
const persist = root
|
|
1063
|
+
? findIntervalSelectionBindingOwners(
|
|
1064
|
+
root,
|
|
1065
|
+
linkInfo.runtime,
|
|
1066
|
+
linkInfo.param,
|
|
1067
|
+
linkInfo.encoding
|
|
1068
|
+
).some((owner) => owner.param.persist !== false)
|
|
1069
|
+
: false;
|
|
1070
|
+
|
|
1071
|
+
return {
|
|
1072
|
+
param: linkInfo.param,
|
|
1073
|
+
encoding: linkInfo.encoding,
|
|
1074
|
+
persist,
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
|
|
719
1078
|
/**
|
|
720
1079
|
* Return true if the scale is zoomable and the current domain differs from the initial domain.
|
|
721
1080
|
*
|
|
@@ -729,8 +1088,14 @@ export default class ScaleResolution {
|
|
|
729
1088
|
* Returns true if zooming is supported and allowed in view spec.
|
|
730
1089
|
*/
|
|
731
1090
|
isZoomable() {
|
|
732
|
-
|
|
733
|
-
|
|
1091
|
+
const props = this.#getMergedScaleProps();
|
|
1092
|
+
if (props === null || props.type === "null") {
|
|
1093
|
+
return false;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
return (
|
|
1097
|
+
isContinuous(props.type) && !isDiscrete(props.type) && !!props.zoom
|
|
1098
|
+
);
|
|
734
1099
|
}
|
|
735
1100
|
|
|
736
1101
|
/**
|
|
@@ -847,3 +1212,60 @@ export default class ScaleResolution {
|
|
|
847
1212
|
return /** @type {number[]} */ (interval);
|
|
848
1213
|
}
|
|
849
1214
|
}
|
|
1215
|
+
|
|
1216
|
+
/**
|
|
1217
|
+
* @param {number[] | null} a
|
|
1218
|
+
* @param {number[] | null} b
|
|
1219
|
+
* @returns {boolean}
|
|
1220
|
+
*/
|
|
1221
|
+
function intervalsEqual(a, b) {
|
|
1222
|
+
if (a === b) {
|
|
1223
|
+
return true;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
if (!a || !b) {
|
|
1227
|
+
return false;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
return a.length === b.length && shallowArrayEquals(a, b);
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
/**
|
|
1234
|
+
* Normalizes member-specific scale URLs so that inline `scale.assembly.url`
|
|
1235
|
+
* values resolve against the member view's base URL before scale props are
|
|
1236
|
+
* merged.
|
|
1237
|
+
*
|
|
1238
|
+
* @template {ChannelWithScale}[T=ChannelWithScale]
|
|
1239
|
+
* @param {ScaleResolutionMember<T>} member
|
|
1240
|
+
* @returns {ScaleResolutionMember<T>}
|
|
1241
|
+
*/
|
|
1242
|
+
function normalizeMember(member) {
|
|
1243
|
+
const scale = member.channelDef.scale;
|
|
1244
|
+
const assembly = scale?.assembly;
|
|
1245
|
+
if (!scale || !assembly || typeof assembly !== "object") {
|
|
1246
|
+
return member;
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
if (!("url" in assembly)) {
|
|
1250
|
+
return member;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
const resolvedUrl = resolveUrl(member.view.getBaseUrl(), assembly.url);
|
|
1254
|
+
if (resolvedUrl === assembly.url) {
|
|
1255
|
+
return member;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
return {
|
|
1259
|
+
...member,
|
|
1260
|
+
channelDef: {
|
|
1261
|
+
...member.channelDef,
|
|
1262
|
+
scale: {
|
|
1263
|
+
...scale,
|
|
1264
|
+
assembly: {
|
|
1265
|
+
...assembly,
|
|
1266
|
+
url: resolvedUrl,
|
|
1267
|
+
},
|
|
1268
|
+
},
|
|
1269
|
+
},
|
|
1270
|
+
};
|
|
1271
|
+
}
|