@jbrowse/core 5.0.0-beta.7 → 5.0.0-beta.9
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/README.md +427 -130
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.js +5 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.d.ts +3 -5
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.js +8 -9
- package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.js +8 -13
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +2 -1
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.js +3 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.d.ts +8 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.js +24 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.js +5 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/index.d.ts +1 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +1 -4
- package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.d.ts +16 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.js +53 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/util.d.ts +0 -8
- package/esm/BaseFeatureWidget/BaseFeatureDetail/util.js +0 -16
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceContents.js +7 -34
- package/esm/BaseFeatureWidget/configSchema.d.ts +1 -1
- package/esm/BaseFeatureWidget/formatDetails.d.ts +13 -29
- package/esm/BaseFeatureWidget/formatDetails.js +46 -79
- package/esm/BaseFeatureWidget/index.d.ts +1 -0
- package/esm/BaseFeatureWidget/stateModelFactory.d.ts +35 -28
- package/esm/BaseFeatureWidget/stateModelFactory.js +94 -102
- package/esm/BaseFeatureWidget/types.d.ts +3 -0
- package/esm/BaseFeatureWidget/util.d.ts +0 -3
- package/esm/BaseFeatureWidget/util.js +0 -17
- package/esm/PluginLoader.d.ts +14 -9
- package/esm/PluginLoader.js +34 -26
- package/esm/PluginManager.d.ts +4 -4
- package/esm/PluginManager.js +1 -1
- package/esm/ReExports/coreModules.generated.d.ts +2 -0
- package/esm/ReExports/coreModules.generated.js +492 -0
- package/esm/ReExports/coreWorkerModules.generated.d.ts +2 -0
- package/esm/ReExports/coreWorkerModules.generated.js +453 -0
- package/esm/ReExports/frameworkModules.d.ts +2 -0
- package/esm/ReExports/frameworkModules.js +67 -0
- package/esm/ReExports/frameworkShared.d.ts +12 -0
- package/esm/ReExports/frameworkShared.js +16 -0
- package/esm/ReExports/frameworkWorkerModules.generated.d.ts +2 -0
- package/esm/ReExports/frameworkWorkerModules.generated.js +130 -0
- package/esm/ReExports/list.js +493 -79
- package/esm/ReExports/modules.d.ts +1 -1
- package/esm/ReExports/modules.js +10 -87
- package/esm/ReExports/registry.d.ts +1 -0
- package/esm/ReExports/registry.js +23 -5
- package/esm/ReExports/uiStub.d.ts +2 -1
- package/esm/ReExports/uiStub.js +24 -2
- package/esm/ReExports/workerModules.js +8 -12
- package/esm/TextSearch/TextSearchManager.d.ts +3 -12
- package/esm/TextSearch/TextSearchManager.js +22 -10
- package/esm/assemblyManager/assembly.d.ts +10 -14
- package/esm/assemblyManager/assembly.js +10 -14
- package/esm/assemblyManager/assemblyConfigSchema.d.ts +23 -81
- package/esm/assemblyManager/assemblyManager.d.ts +10 -16
- package/esm/assemblyManager/assemblyManager.js +7 -10
- package/esm/assemblyManager/loadRefNameMap.js +3 -3
- package/esm/configuration/configurationSchema.d.ts +75 -31
- package/esm/configuration/configurationSchema.js +74 -40
- package/esm/configuration/configurationSchemaUnion.d.ts +39 -0
- package/esm/configuration/configurationSchemaUnion.js +59 -0
- package/esm/configuration/configurationSlot.d.ts +37 -12
- package/esm/configuration/configurationSlot.js +83 -22
- package/esm/configuration/formatAboutConfigSchema.d.ts +7 -21
- package/esm/configuration/formatDetailsConfigSchema.d.ts +11 -37
- package/esm/configuration/formatDetailsConfigSchema.js +10 -13
- package/esm/configuration/getConf.d.ts +17 -9
- package/esm/configuration/getConf.js +52 -7
- package/esm/configuration/index.d.ts +11 -4
- package/esm/configuration/index.js +7 -4
- package/esm/configuration/mergeFormatCallbacks.d.ts +6 -7
- package/esm/configuration/mergeFormatCallbacks.js +13 -10
- package/esm/configuration/readConfObject.d.ts +2 -22
- package/esm/configuration/readConfObject.js +15 -49
- package/esm/configuration/requirements.d.ts +37 -0
- package/esm/configuration/requirements.js +88 -0
- package/esm/configuration/schemaRegistry.d.ts +21 -1
- package/esm/configuration/schemaRegistry.js +11 -0
- package/esm/configuration/schemaTypes.d.ts +3 -0
- package/esm/configuration/schemaTypes.js +10 -0
- package/esm/configuration/slotFacade.d.ts +35 -4
- package/esm/configuration/slotFacade.js +96 -9
- package/esm/configuration/snapshotPreprocess.d.ts +27 -0
- package/esm/configuration/snapshotPreprocess.js +102 -0
- package/esm/configuration/types.d.ts +161 -22
- package/esm/data_adapters/BaseAdapter/BaseAdapter.d.ts +2 -2
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +11 -2
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +12 -1
- package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +2 -3
- package/esm/data_adapters/BaseAdapter/featureDensity.js +2 -3
- package/esm/data_adapters/BaseAdapter/index.d.ts +22 -3
- package/esm/data_adapters/BaseAdapter/types.d.ts +3 -4
- package/esm/data_adapters/BaseAdapter/zoomRange.d.ts +10 -0
- package/esm/data_adapters/BaseAdapter/zoomRange.js +1 -0
- package/esm/data_adapters/CytobandAdapter/configSchema.d.ts +9 -11
- package/esm/data_adapters/getSequenceSubAdapter.d.ts +1 -3
- package/esm/data_adapters/getSequenceSubAdapter.js +1 -3
- package/esm/pluggableElementTypes/AdapterType.d.ts +7 -7
- package/esm/pluggableElementTypes/RpcMethodType.d.ts +1 -1
- package/esm/pluggableElementTypes/RpcMethodType.js +3 -8
- package/esm/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions.d.ts +1 -2
- package/esm/pluggableElementTypes/TextSearchAdapterType.d.ts +7 -7
- package/esm/pluggableElementTypes/index.d.ts +1 -1
- package/esm/pluggableElementTypes/index.js +1 -1
- package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +17 -7
- package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +45 -48
- package/esm/pluggableElementTypes/models/BaseDisplayModel.js +40 -36
- package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +10 -13
- package/esm/pluggableElementTypes/models/BaseTrackModel.js +6 -6
- package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +37 -17
- package/esm/pluggableElementTypes/models/BaseViewModel.js +25 -10
- package/esm/pluggableElementTypes/models/InternetAccountModel.d.ts +26 -16
- package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +1 -1
- package/esm/pluggableElementTypes/models/baseConnectionConfig.d.ts +22 -18
- package/esm/pluggableElementTypes/models/baseConnectionConfig.js +5 -5
- package/esm/pluggableElementTypes/models/baseInternetAccountConfig.d.ts +26 -31
- package/esm/pluggableElementTypes/models/baseTrackConfig.d.ts +57 -141
- package/esm/pluggableElementTypes/models/baseTrackConfig.js +22 -26
- package/esm/pluggableElementTypes/models/components/SaveTrackData.js +2 -2
- package/esm/pluggableElementTypes/models/components/fetchTrackData.d.ts +3 -4
- package/esm/pluggableElementTypes/models/components/fetchTrackData.js +3 -3
- package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.d.ts +15 -7
- package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.js +38 -29
- package/esm/pluggableElementTypes/models/index.d.ts +1 -2
- package/esm/pluggableElementTypes/models/index.js +1 -2
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.d.ts +3 -3
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.js +4 -4
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/types.d.ts +3 -3
- package/esm/rpc/BaseRpcDriver.d.ts +1 -2
- package/esm/rpc/BaseRpcDriver.js +23 -30
- package/esm/rpc/MainThreadRpcDriver.d.ts +2 -2
- package/esm/rpc/MainThreadRpcDriver.js +13 -8
- package/esm/rpc/RpcClient.d.ts +17 -6
- package/esm/rpc/RpcClient.js +42 -12
- package/esm/rpc/RpcManager.d.ts +8 -10
- package/esm/rpc/RpcManager.js +1 -1
- package/esm/rpc/RpcRegistry.d.ts +8 -2
- package/esm/rpc/RpcServer.d.ts +3 -1
- package/esm/rpc/RpcServer.js +19 -12
- package/esm/rpc/WebWorkerRpcDriver.d.ts +3 -3
- package/esm/rpc/WebWorkerRpcDriver.js +9 -47
- package/esm/rpc/byteBudget.d.ts +3 -5
- package/esm/rpc/byteBudget.js +4 -4
- package/esm/rpc/configSchema.d.ts +7 -21
- package/esm/rpc/coreRpcMethods.d.ts +1 -0
- package/esm/rpc/coreRpcMethods.js +1 -0
- package/esm/rpc/methods/CoreEncodeFeatures.d.ts +6 -5
- package/esm/rpc/methods/CoreEncodeFeatures.js +26 -31
- package/esm/rpc/methods/CoreGetEncodedFeature.d.ts +13 -0
- package/esm/rpc/methods/CoreGetEncodedFeature.js +31 -0
- package/esm/rpc/methods/CoreGetExportData.js +2 -2
- package/esm/rpc/methods/CoreGetFeatureDensity.js +2 -2
- package/esm/rpc/methods/CoreGetFeatures.js +2 -2
- package/esm/rpc/methods/CoreGetSequence.js +2 -2
- package/esm/rpc/methods/layerFeatures.d.ts +26 -0
- package/esm/rpc/methods/layerFeatures.js +40 -0
- package/esm/svg/SvgExport.js +3 -4
- package/esm/svg/SvgThemeProviders.d.ts +12 -0
- package/esm/svg/SvgThemeProviders.js +15 -0
- package/esm/svg/exportViewSvg.d.ts +32 -0
- package/esm/svg/exportViewSvg.js +13 -0
- package/esm/svg/normalizeSvgMarkup.d.ts +7 -0
- package/esm/svg/normalizeSvgMarkup.js +99 -0
- package/esm/svg/serializeSvg.d.ts +7 -0
- package/esm/svg/serializeSvg.js +11 -0
- package/esm/svg/svgReady.d.ts +8 -7
- package/esm/svg/svgReady.js +8 -7
- package/esm/svg/trackNames.d.ts +5 -5
- package/esm/svg/trackNames.js +6 -6
- package/esm/svg/wrapSvgExport.js +6 -74
- package/esm/ui/CascadingMenu.js +83 -86
- package/esm/ui/ErrorMessageStackTraceDialog.js +0 -5
- package/esm/ui/FileSelector/useInternetAccounts.d.ts +156 -96
- package/esm/ui/HoverMenu.d.ts +1 -2
- package/esm/ui/HoverMenu.js +6 -3
- package/esm/ui/JexlFilterDialog.d.ts +13 -10
- package/esm/ui/JexlFilterDialog.js +122 -49
- package/esm/ui/JexlFilterRowEditors.d.ts +15 -0
- package/esm/ui/JexlFilterRowEditors.js +90 -0
- package/esm/ui/LazyBaseTooltip.d.ts +4 -0
- package/esm/ui/LazyBaseTooltip.js +9 -0
- package/esm/ui/LoadingOverlay.js +3 -1
- package/esm/ui/MonospaceTextField.d.ts +2 -1
- package/esm/ui/MonospaceTextField.js +21 -19
- package/esm/ui/PaletteContext.d.ts +7 -9
- package/esm/ui/PaletteContext.js +24 -10
- package/esm/ui/RefNameAutocomplete/index.d.ts +1 -2
- package/esm/ui/RefNameAutocomplete/index.js +1 -1
- package/esm/ui/ScrollChrome.d.ts +6 -9
- package/esm/ui/ScrollChrome.js +5 -6
- package/esm/ui/ScrollEdgeShadow.d.ts +6 -9
- package/esm/ui/ScrollEdgeShadow.js +9 -24
- package/esm/ui/SettingsChangesTable.js +3 -3
- package/esm/ui/VerticalScrollbar.d.ts +13 -34
- package/esm/ui/VerticalScrollbar.js +29 -83
- package/esm/ui/ViewLoadingScreen.d.ts +2 -2
- package/esm/ui/ViewLoadingScreen.js +3 -3
- package/esm/ui/colorScale.d.ts +26 -1
- package/esm/ui/colorScale.js +28 -5
- package/esm/ui/colors.d.ts +49 -1
- package/esm/ui/colors.js +139 -4
- package/esm/ui/hoverBoxStyle.d.ts +14 -2
- package/esm/ui/hoverBoxStyle.js +17 -2
- package/esm/ui/index.d.ts +5 -3
- package/esm/ui/index.js +9 -7
- package/esm/ui/launchViewMenu.js +3 -3
- package/esm/ui/legendSpec.d.ts +2 -0
- package/esm/ui/legendSpec.js +3 -0
- package/esm/ui/palette.d.ts +0 -1
- package/esm/ui/palette.js +3 -27
- package/esm/ui/replaceViewAction.d.ts +1 -1
- package/esm/ui/replaceViewAction.js +1 -1
- package/esm/ui/theme.d.ts +1 -1
- package/esm/ui/theme.js +6 -40
- package/esm/ui/viewHeaderHeight.d.ts +1 -0
- package/esm/ui/viewHeaderHeight.js +1 -0
- package/esm/util/Base1DUtils.d.ts +1 -1
- package/esm/util/Base1DUtils.js +2 -2
- package/esm/util/SvgCanvas.d.ts +15 -13
- package/esm/util/SvgCanvas.js +72 -53
- package/esm/util/aborting.d.ts +39 -0
- package/esm/util/aborting.js +84 -0
- package/esm/util/adapterMetadata.d.ts +1 -1
- package/esm/util/adapterMetadata.js +6 -6
- package/esm/util/addAndShowTrack.d.ts +1 -4
- package/esm/util/addRelativeUris.d.ts +10 -2
- package/esm/util/addRelativeUris.js +22 -7
- package/esm/util/addTrackFromWidget.d.ts +2 -5
- package/esm/util/animationAllowed.d.ts +9 -0
- package/esm/util/animationAllowed.js +13 -0
- package/esm/util/applyRowResizeWheel.d.ts +10 -5
- package/esm/util/applyRowResizeWheel.js +10 -21
- package/esm/util/bandLayout.d.ts +4 -4
- package/esm/util/bandLayout.js +4 -4
- package/esm/util/bezierConnector.js +5 -4
- package/esm/util/bgzfWorkerPool.d.ts +20 -74
- package/esm/util/bgzfWorkerPool.js +20 -74
- package/esm/util/cachedSetup.d.ts +1 -1
- package/esm/util/cachedSetup.js +2 -2
- package/esm/util/categoricalField.d.ts +37 -0
- package/esm/util/categoricalField.js +52 -0
- package/esm/util/color/cssColorsLevel4.d.ts +1 -0
- package/esm/util/color/cssColorsLevel4.js +1 -0
- package/esm/util/color/index.d.ts +5 -3
- package/esm/util/color/index.js +7 -4
- package/esm/util/colorBits.d.ts +1 -2
- package/esm/util/colorBits.js +17 -39
- package/esm/util/colorRamp.d.ts +27 -1
- package/esm/util/colorRamp.js +56 -2
- package/esm/util/colorSchemes.d.ts +9 -0
- package/esm/util/colorSchemes.js +7 -0
- package/esm/util/{createStopTokenRotation.d.ts → createAbortRotation.d.ts} +11 -14
- package/esm/util/{createStopTokenRotation.js → createAbortRotation.js} +14 -26
- package/esm/util/cssColorParse.d.ts +15 -0
- package/esm/util/cssColorParse.js +53 -0
- package/esm/util/diagonalizeRegions.d.ts +2 -3
- package/esm/util/diagonalizeRegions.js +7 -12
- package/esm/util/expandLooseSearchIndex.d.ts +7 -0
- package/esm/util/expandLooseSearchIndex.js +25 -0
- package/esm/util/featureTransforms.d.ts +30 -3
- package/esm/util/featureTransforms.js +233 -36
- package/esm/util/fetchAndMaybeUnzip.js +5 -6
- package/esm/util/fetchContext.d.ts +5 -6
- package/esm/util/fetchContext.js +1 -1
- package/esm/util/fetchHub.d.ts +3 -1
- package/esm/util/fetchHub.js +2 -2
- package/esm/util/fetchSeq.d.ts +2 -3
- package/esm/util/fetchSeq.js +2 -2
- package/esm/util/fieldReader.d.ts +17 -0
- package/esm/util/fieldReader.js +62 -0
- package/esm/util/groupKeys.d.ts +75 -0
- package/esm/util/groupKeys.js +152 -0
- package/esm/util/highlights.d.ts +6 -4
- package/esm/util/highlights.js +12 -25
- package/esm/util/hooks.d.ts +1 -2
- package/esm/util/hooks.js +1 -2
- package/esm/util/index.d.ts +3 -3
- package/esm/util/index.js +4 -3
- package/esm/util/indexCandidates.js +1 -1
- package/esm/util/installFetch.d.ts +13 -10
- package/esm/util/installFetch.js +11 -10
- package/esm/util/installPrerequisiteFetch.d.ts +5 -3
- package/esm/util/installPrerequisiteFetch.js +3 -4
- package/esm/util/io/index.js +12 -12
- package/esm/util/isDataCurrent.d.ts +7 -5
- package/esm/util/isDataCurrent.js +9 -6
- package/esm/util/jexl.js +24 -21
- package/esm/util/jexlFilterRows.d.ts +89 -0
- package/esm/util/jexlFilterRows.js +252 -0
- package/esm/util/jexlFilters.d.ts +7 -5
- package/esm/util/jexlStrings.d.ts +3 -4
- package/esm/util/jexlStrings.js +2 -3
- package/esm/util/legendCandidates.d.ts +31 -27
- package/esm/util/legendCandidates.js +79 -53
- package/esm/util/localStorage.js +4 -4
- package/esm/util/markEncoding.d.ts +32 -16
- package/esm/util/markEncoding.js +177 -150
- package/esm/util/markEncodingTypes.d.ts +137 -66
- package/esm/util/mstUtils.d.ts +19 -22
- package/esm/util/mstUtils.js +19 -22
- package/esm/util/numericUtils.d.ts +7 -0
- package/esm/util/numericUtils.js +16 -0
- package/esm/util/numericValue.d.ts +14 -0
- package/esm/util/numericValue.js +34 -0
- package/esm/util/openFeatureWidget.js +1 -2
- package/esm/util/openViews.d.ts +1 -0
- package/esm/util/openViews.js +3 -3
- package/esm/util/parseLineByLine.d.ts +3 -4
- package/esm/util/parseLineByLine.js +7 -13
- package/esm/util/progress.d.ts +21 -21
- package/esm/util/progress.js +27 -26
- package/esm/util/renameRegions.d.ts +1 -2
- package/esm/util/renderToStaticMarkup.js +16 -16
- package/esm/util/rxjs.d.ts +7 -8
- package/esm/util/rxjs.js +12 -15
- package/esm/util/simpleFeature.d.ts +0 -1
- package/esm/util/svgColorProps.d.ts +11 -0
- package/esm/util/svgColorProps.js +28 -1
- package/esm/util/tabix.d.ts +3 -4
- package/esm/util/tabix.js +6 -7
- package/esm/util/thresholdScale.d.ts +54 -0
- package/esm/util/thresholdScale.js +112 -0
- package/esm/util/timeGate.d.ts +4 -5
- package/esm/util/timeGate.js +4 -5
- package/esm/util/trackConfigDelta.d.ts +22 -18
- package/esm/util/trackConfigDelta.js +40 -38
- package/esm/util/tracks.d.ts +27 -4
- package/esm/util/tracks.js +116 -43
- package/esm/util/translateTranscript.d.ts +44 -0
- package/esm/util/translateTranscript.js +102 -0
- package/esm/util/types/index.d.ts +19 -7
- package/esm/util/types/services.d.ts +1 -1
- package/esm/util/unknownSnapshotKeys.d.ts +15 -0
- package/esm/util/unknownSnapshotKeys.js +13 -0
- package/esm/util/useFeatureSequence.js +4 -4
- package/esm/util/useFetch.d.ts +3 -4
- package/esm/util/useFetch.js +5 -6
- package/esm/util/usePanelVirtualScroll.d.ts +7 -39
- package/esm/util/usePanelVirtualScroll.js +9 -40
- package/esm/util/useRowVirtualScroll.d.ts +6 -29
- package/esm/util/useRowVirtualScroll.js +8 -49
- package/esm/util/useVirtualScrollWheel.d.ts +20 -4
- package/esm/util/useVirtualScrollWheel.js +40 -84
- package/esm/util/viewHighlights.d.ts +3 -0
- package/esm/util/viewHighlights.js +5 -0
- package/esm/util/viewStatus.d.ts +24 -15
- package/esm/util/viewStatus.js +17 -0
- package/esm/util/withLaunchInput.d.ts +1 -1
- package/esm/util/withLaunchInput.js +0 -4
- package/package.json +26 -12
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.d.ts +0 -80
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.js +0 -583
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.d.ts +0 -141
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.js +0 -1116
- package/esm/ReExports/BaseFeatureDetails.d.ts +0 -1
- package/esm/ReExports/BaseFeatureDetails.js +0 -10
- package/esm/ReExports/barrelOnlyNames.d.ts +0 -5
- package/esm/ReExports/barrelOnlyNames.js +0 -63
- package/esm/ReExports/index.d.ts +0 -1
- package/esm/ReExports/index.js +0 -1
- package/esm/ReExports/publicTracks.d.ts +0 -1
- package/esm/ReExports/publicTracks.js +0 -14
- package/esm/ReExports/publicUi.d.ts +0 -4
- package/esm/ReExports/publicUi.js +0 -33
- package/esm/ReExports/publicUtil.d.ts +0 -1
- package/esm/ReExports/publicUtil.js +0 -32
- package/esm/ReExports/sharedModules.d.ts +0 -96
- package/esm/ReExports/sharedModules.js +0 -66
- package/esm/ReExports/workerNamespaceNames.d.ts +0 -11
- package/esm/ReExports/workerNamespaceNames.js +0 -275
- package/esm/pluggableElementTypes/models/HighlightsMixin.d.ts +0 -51
- package/esm/pluggableElementTypes/models/HighlightsMixin.js +0 -78
- package/esm/ui/highlightChipReveal.d.ts +0 -32
- package/esm/ui/highlightChipReveal.js +0 -39
- package/esm/util/adapterConfigKey.d.ts +0 -12
- package/esm/util/adapterConfigKey.js +0 -14
- package/esm/util/stopToken.d.ts +0 -212
- package/esm/util/stopToken.js +0 -438
|
@@ -1,31 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useRef, useState } from 'react';
|
|
3
|
+
import { observer } from 'mobx-react';
|
|
3
4
|
import { clamp } from '../util/numericUtils.js';
|
|
4
5
|
import { makeStyles } from '../util/tss-react/index.js';
|
|
5
6
|
import { usePointerDrag } from '../util/usePointerDrag.js';
|
|
6
7
|
import { useRafCommit } from '../util/useRafCommit.js';
|
|
7
8
|
import { useVirtualScrollWheel } from '../util/useVirtualScrollWheel.js';
|
|
8
9
|
/**
|
|
9
|
-
* How much of a display's right edge this occupies while it is drawn
|
|
10
|
-
*
|
|
11
|
-
* Exported because the things that have to *clear* it are drawn by the displays
|
|
12
|
-
* that mount it, not by this file: the bottom-right indicator row and the
|
|
13
|
-
* alignments coverage axis label. Both kept a private copy of the number (and
|
|
14
|
-
* the alignments indicator row kept none at all, so its chips were drawn over
|
|
15
|
-
* the thumb), which is a copy that can only be checked by looking at two files
|
|
16
|
-
* at once.
|
|
10
|
+
* How much of a display's right edge this occupies while it is drawn, for the
|
|
11
|
+
* chrome the displays draw beside it.
|
|
17
12
|
*/
|
|
18
13
|
export const VERTICAL_SCROLLBAR_WIDTH = 12;
|
|
19
|
-
/**
|
|
20
|
-
* Where the right edge of anything that has to sit *beside* the thumb goes: the
|
|
21
|
-
* track's width plus a hair of air, so a chip or an axis label doesn't touch it.
|
|
22
|
-
*
|
|
23
|
-
* The four call sites all spelled `VERTICAL_SCROLLBAR_WIDTH + 2` inline, which
|
|
24
|
-
* is the same copy the width constant was exported to stop — one addition
|
|
25
|
-
* further along. The `+ 2` is a gap and belongs to the thing being cleared, not
|
|
26
|
-
* to the scrollbar's own geometry, so it is named rather than folded into the
|
|
27
|
-
* width (`right: 2` on the thumb is a different 2 and must not move with it).
|
|
28
|
-
*/
|
|
14
|
+
/** Where the right edge of something sitting beside the thumb goes. */
|
|
29
15
|
export const VERTICAL_SCROLLBAR_CLEARANCE = VERTICAL_SCROLLBAR_WIDTH + 2;
|
|
30
16
|
const MIN_THUMB_HEIGHT = 20;
|
|
31
17
|
const useStyles = makeStyles()(theme => ({
|
|
@@ -35,12 +21,8 @@ const useStyles = makeStyles()(theme => ({
|
|
|
35
21
|
width: VERTICAL_SCROLLBAR_WIDTH,
|
|
36
22
|
cursor: 'default',
|
|
37
23
|
zIndex: 10,
|
|
38
|
-
//
|
|
39
|
-
// claims a touch drag on this strip as a page scroll and no pointer stream
|
|
40
|
-
// arrives at all, so the thumb simply doesn't drag by finger.
|
|
24
|
+
// without it the browser claims a touch drag as a page scroll
|
|
41
25
|
touchAction: 'none',
|
|
42
|
-
// theme-aware so the thumb stays visible in dark mode (a hardcoded black
|
|
43
|
-
// thumb vanished against a dark canvas)
|
|
44
26
|
'&:hover > *': {
|
|
45
27
|
background: theme.palette.action.active,
|
|
46
28
|
},
|
|
@@ -55,71 +37,41 @@ const useStyles = makeStyles()(theme => ({
|
|
|
55
37
|
},
|
|
56
38
|
}));
|
|
57
39
|
/**
|
|
58
|
-
* Draggable vertical scrollbar overlay for
|
|
59
|
-
*
|
|
60
|
-
* Renders nothing when the content fits the viewport. The thumb geometry and
|
|
61
|
-
* the drag-to-scroll mapping live here so the consumers don't each re-derive
|
|
62
|
-
* them; the wheel handling stays per-display (their gesture semantics differ).
|
|
40
|
+
* Draggable vertical scrollbar overlay for a virtually scrolled display.
|
|
41
|
+
* Renders nothing when the content fits.
|
|
63
42
|
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* `aria-value*` semantics are kept — they cost nothing and expose scroll
|
|
68
|
-
* position to pointer/voice assistive tech.
|
|
43
|
+
* Not a keyboard tab stop: the views have no keyboard navigation to reach the
|
|
44
|
+
* scrolled content, so `tabIndex` would only add noise. The `role="scrollbar"`
|
|
45
|
+
* semantics stay for pointer and voice assistive tech.
|
|
69
46
|
*/
|
|
70
|
-
|
|
47
|
+
const VerticalScrollbar = observer(function VerticalScrollbar({ model, controlsId, top = 0, }) {
|
|
71
48
|
const { classes } = useStyles();
|
|
72
|
-
// ephemeral drag anchor; null when not dragging. Pointer capture (set on the
|
|
73
|
-
// track) delivers move/up here even when the pointer leaves the thin track,
|
|
74
|
-
// and auto-releases on unmount — so no document listeners or effect cleanup.
|
|
75
49
|
const dragRef = useRef(undefined);
|
|
76
50
|
const [trackEl, setTrackEl] = useState(null);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const {
|
|
81
|
-
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// handler to the containing view's scroll-zoom. A native non-passive listener
|
|
86
|
-
// here (via useVirtualScrollWheel) consumes the vertical delta into
|
|
87
|
-
// setScrollTop and stopPropagation keeps it from reaching that scroll-zoom.
|
|
88
|
-
useVirtualScrollWheel(trackEl, (e, applyScroll) => {
|
|
89
|
-
applyScroll(e, { scrollTop, viewportHeight, scrollableHeight }, n => {
|
|
90
|
-
setScrollTop(n);
|
|
91
|
-
});
|
|
51
|
+
const { schedule: scheduleScroll, flush: flushScroll } = useRafCommit((n) => {
|
|
52
|
+
model.setScrollTop(n);
|
|
53
|
+
});
|
|
54
|
+
const { scrollTop, scrollableHeight, scrollViewportHeight: viewportHeight, } = model;
|
|
55
|
+
// Wheeling the scrollbar always scrolls the panel, whatever `scrollZoom`
|
|
56
|
+
// says, and never reaches the view.
|
|
57
|
+
useVirtualScrollWheel(trackEl, model, (e, scroll) => {
|
|
58
|
+
scroll();
|
|
92
59
|
e.stopPropagation();
|
|
93
60
|
});
|
|
94
61
|
const clampedScrollTop = clamp(scrollTop, 0, scrollableHeight);
|
|
95
|
-
|
|
96
|
-
// MIN_THUMB_HEIGHT floor would otherwise exceed viewportHeight, pushing
|
|
97
|
-
// thumbTop negative (thumb drawn above the track) and making usableTrack
|
|
98
|
-
// negative (drag mapping dead)
|
|
62
|
+
const contentHeight = viewportHeight + scrollableHeight;
|
|
99
63
|
const thumbHeight = Math.min(viewportHeight, Math.max(MIN_THUMB_HEIGHT, viewportHeight * (viewportHeight / contentHeight)));
|
|
100
64
|
const usableTrack = viewportHeight - thumbHeight;
|
|
101
|
-
// clamp so a scrollTop past scrollableHeight (virtual-scroll displays don't
|
|
102
|
-
// self-correct like a native overflow container) can't draw the thumb below
|
|
103
|
-
// the track
|
|
104
65
|
const thumbTop = clamp((clampedScrollTop / scrollableHeight) * usableTrack, 0, usableTrack);
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
// existed, which cost two of the bugs it is written to prevent — a right-press
|
|
109
|
-
// started a drag that then ran underneath its own context menu, and a second
|
|
110
|
-
// finger landing mid-drag re-anchored the gesture.
|
|
66
|
+
// A press on the track above or below the thumb pages one viewport toward it
|
|
67
|
+
// rather than starting a drag; `dragRef` staying unset makes the captured
|
|
68
|
+
// moves that follow do nothing.
|
|
111
69
|
const drag = usePointerDrag({
|
|
112
|
-
// Click-to-page: a press on the track above/below the thumb jumps one
|
|
113
|
-
// viewport toward it (like a native scrollbar) rather than starting a drag.
|
|
114
|
-
// The thumb is pointerEvents:none so every press lands on the track; decide
|
|
115
|
-
// page-vs-drag from its Y relative to the thumb. `dragRef` staying undefined
|
|
116
|
-
// is what makes the paging branch ignore the moves that follow — the pointer
|
|
117
|
-
// is captured either way, and a page press simply has nothing to do with them.
|
|
118
70
|
onDragStart: e => {
|
|
119
71
|
const clickY = e.clientY - e.currentTarget.getBoundingClientRect().top;
|
|
120
72
|
if (clickY < thumbTop || clickY > thumbTop + thumbHeight) {
|
|
121
73
|
const dir = clickY < thumbTop ? -1 : 1;
|
|
122
|
-
setScrollTop(clamp(clampedScrollTop + dir * viewportHeight, 0, scrollableHeight));
|
|
74
|
+
model.setScrollTop(clamp(clampedScrollTop + dir * viewportHeight, 0, scrollableHeight));
|
|
123
75
|
}
|
|
124
76
|
else {
|
|
125
77
|
dragRef.current = { startY: e.clientY, startScroll: clampedScrollTop };
|
|
@@ -137,22 +89,16 @@ export default function VerticalScrollbar({ scrollTop, setScrollTop, viewportHei
|
|
|
137
89
|
dragRef.current = undefined;
|
|
138
90
|
},
|
|
139
91
|
});
|
|
140
|
-
//
|
|
141
|
-
// prop-driven condition that flips while mounted, so an early return above
|
|
142
|
-
// `usePointerDrag` would call a different number of hooks per render. The
|
|
143
|
-
// geometry it closes over is computed either way and simply goes unused here —
|
|
144
|
-
// nothing renders, so nothing can dispatch a pointer event at it.
|
|
92
|
+
// below every hook: "the content fits" flips while mounted
|
|
145
93
|
if (scrollableHeight <= 0) {
|
|
146
94
|
return null;
|
|
147
95
|
}
|
|
148
96
|
return (_jsx("div", { ref: setTrackEl, "data-testid": "vertical-scrollbar", "data-gesture-owner": "true", className: classes.track, style: { top, height: viewportHeight }, role: "scrollbar", "aria-label": "Vertical scrollbar", "aria-controls": controlsId, "aria-orientation": "vertical", "aria-valuemin": 0, "aria-valuemax": Math.round(scrollableHeight), "aria-valuenow": Math.round(clampedScrollTop), ...drag,
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
// a right-press the drag ignores still doesn't reach the view. No
|
|
152
|
-
// preventDefault, so the native focus shift can still close open popups
|
|
153
|
-
// and the context menu still opens.
|
|
97
|
+
// every button, so a right-press the drag ignores doesn't pan the view
|
|
98
|
+
// either; no preventDefault, so focus still moves and menus still open
|
|
154
99
|
onPointerDown: e => {
|
|
155
100
|
e.stopPropagation();
|
|
156
101
|
drag.onPointerDown(e);
|
|
157
102
|
}, children: _jsx("div", { className: classes.thumb, style: { top: thumbTop, height: thumbHeight } }) }));
|
|
158
|
-
}
|
|
103
|
+
});
|
|
104
|
+
export default VerticalScrollbar;
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
* {@link LoadingProgress} directly — bare, it renders an unconstrained
|
|
18
18
|
* full-width bar under an unaligned label.
|
|
19
19
|
*/
|
|
20
|
-
export default function ViewLoadingScreen({ message,
|
|
20
|
+
export default function ViewLoadingScreen({ message, progress, source, }: {
|
|
21
21
|
message?: string;
|
|
22
|
-
|
|
22
|
+
progress?: number;
|
|
23
23
|
source?: string;
|
|
24
24
|
}): import("react").JSX.Element;
|
|
@@ -69,8 +69,8 @@ function useStalled(key) {
|
|
|
69
69
|
* {@link LoadingProgress} directly — bare, it renders an unconstrained
|
|
70
70
|
* full-width bar under an unaligned label.
|
|
71
71
|
*/
|
|
72
|
-
export default function ViewLoadingScreen({ message,
|
|
72
|
+
export default function ViewLoadingScreen({ message, progress, source, }) {
|
|
73
73
|
const { classes } = useStyles();
|
|
74
|
-
const stalled = useStalled(`${message}|${
|
|
75
|
-
return (_jsxs("div", { className: classes.root, children: [_jsx(LoadingProgress, { variant: "h6", message: message, fraction:
|
|
74
|
+
const stalled = useStalled(`${message}|${progress}|${source}`);
|
|
75
|
+
return (_jsxs("div", { className: classes.root, children: [_jsx(LoadingProgress, { variant: "h6", message: message, fraction: progress, barClassName: classes.bar }), stalled && source ? (_jsxs(Typography, { variant: "body2", className: classes.stalled, children: ["still waiting on ", source] })) : null] }));
|
|
76
76
|
}
|
package/esm/ui/colorScale.d.ts
CHANGED
|
@@ -7,10 +7,17 @@ import type { LegendSpec, LegendSwatch } from './legendSpec.ts';
|
|
|
7
7
|
*/
|
|
8
8
|
export interface CategoricalEntry {
|
|
9
9
|
value: string;
|
|
10
|
+
/**
|
|
11
|
+
* Every value painted in this row's color where the key is derived from
|
|
12
|
+
* the painting (`derivedColorScale`), `value` being the first; the label
|
|
13
|
+
* names them all. A row declared one value at a time leaves it unset.
|
|
14
|
+
*/
|
|
15
|
+
values?: string[];
|
|
10
16
|
label: string;
|
|
11
17
|
color?: string;
|
|
12
18
|
swatches?: LegendSwatch[];
|
|
13
19
|
hidden?: boolean;
|
|
20
|
+
missing?: boolean;
|
|
14
21
|
}
|
|
15
22
|
/**
|
|
16
23
|
* A color vocabulary: a finite set of values, each drawn in one color. ADR-094's
|
|
@@ -22,6 +29,9 @@ export interface CategoricalScale {
|
|
|
22
29
|
id: string;
|
|
23
30
|
title?: string;
|
|
24
31
|
entries: CategoricalEntry[];
|
|
32
|
+
domain?: readonly string[];
|
|
33
|
+
focusesRows?: boolean;
|
|
34
|
+
note?: string;
|
|
25
35
|
}
|
|
26
36
|
/** One stop of a continuous ramp, `offset` in `[0, 1]`. */
|
|
27
37
|
export interface RampStop {
|
|
@@ -33,7 +43,9 @@ export interface RampStop {
|
|
|
33
43
|
* A scalar through a color ramp: ADR-094's scalar-through-a-scale
|
|
34
44
|
* cardinality. `stops` are what the painter samples — read them out of the
|
|
35
45
|
* same LUT the GPU uploads (`stopsFromRampLut`) so the bar is byte-identical
|
|
36
|
-
* to the plot. `format` prints the domain ends; `
|
|
46
|
+
* to the plot. `format` prints the domain ends; `formatScore` by default, so
|
|
47
|
+
* a domain measured off the data prints `24.4` and not the float it was
|
|
48
|
+
* measured as.
|
|
37
49
|
*/
|
|
38
50
|
export interface RampScale {
|
|
39
51
|
kind: 'ramp';
|
|
@@ -60,5 +72,18 @@ export type ColorScale = CategoricalScale | RampScale;
|
|
|
60
72
|
* name over its values) and a lone ramp's goes on its row.
|
|
61
73
|
*/
|
|
62
74
|
export declare function legendSpecOf(scales: ColorScale[]): LegendSpec;
|
|
75
|
+
/**
|
|
76
|
+
* The no-value row goes after every value, in whatever orders the values: a
|
|
77
|
+
* `domain` never lists it, so ordering by the domain alone ranks it with the
|
|
78
|
+
* values the domain leaves out and the bracket its label starts with floats it
|
|
79
|
+
* above them all. Both places a key is ordered read this — `sectionOf` for the
|
|
80
|
+
* rows it draws, and `derivedColorScale` for the entries it hands back, which a
|
|
81
|
+
* display reads for what its key lists.
|
|
82
|
+
*/
|
|
83
|
+
export declare function missingRowLast(a: {
|
|
84
|
+
missing?: boolean;
|
|
85
|
+
}, b: {
|
|
86
|
+
missing?: boolean;
|
|
87
|
+
}): number;
|
|
63
88
|
/** Whether a scale has anything for a key to show. */
|
|
64
89
|
export declare function colorScaleIsEmpty(scale: ColorScale): boolean;
|
package/esm/ui/colorScale.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { groupKeyComparator } from '../util/groupKeys.js';
|
|
2
|
+
import { formatScore } from '../util/numericUtils.js';
|
|
2
3
|
// A lone ramp names itself on its row: `FloatingLegend` and `legendEntries`
|
|
3
4
|
// draw a section's title only beside other sections, and a bar of numbers
|
|
4
5
|
// with nothing saying what they count is not a key.
|
|
5
|
-
function rampItem({ title, domain, stops, format =
|
|
6
|
+
function rampItem({ title, domain, stops, format = formatScore }, lone) {
|
|
6
7
|
const [min, max] = domain;
|
|
7
8
|
return {
|
|
8
9
|
label: lone ? (title ?? '') : '',
|
|
@@ -10,12 +11,23 @@ function rampItem({ title, domain, stops, format = toLocale }, lone) {
|
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
13
|
function sectionOf(scale, lone) {
|
|
14
|
+
if (scale.kind !== 'categorical') {
|
|
15
|
+
return { id: scale.id, title: scale.title, items: [rampItem(scale, lone)] };
|
|
16
|
+
}
|
|
17
|
+
const items = scale.entries.map(entry => ({ ...entry }));
|
|
18
|
+
const compare = scale.domain?.length
|
|
19
|
+
? groupKeyComparator(scale.domain)
|
|
20
|
+
: undefined;
|
|
21
|
+
// The sort is stable and the value half is skipped without a domain, so a
|
|
22
|
+
// key a display ordered itself keeps that order and only its no-value row
|
|
23
|
+
// moves.
|
|
24
|
+
items.sort((a, b) => missingRowLast(a, b) || (compare ? compare(a.value, b.value) : 0));
|
|
13
25
|
return {
|
|
14
26
|
id: scale.id,
|
|
15
27
|
title: scale.title,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
28
|
+
note: scale.note,
|
|
29
|
+
items,
|
|
30
|
+
focusesRows: scale.focusesRows,
|
|
19
31
|
};
|
|
20
32
|
}
|
|
21
33
|
/**
|
|
@@ -35,6 +47,17 @@ export function legendSpecOf(scales) {
|
|
|
35
47
|
sections: scales.map(scale => sectionOf(scale, scales.length === 1)),
|
|
36
48
|
};
|
|
37
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* The no-value row goes after every value, in whatever orders the values: a
|
|
52
|
+
* `domain` never lists it, so ordering by the domain alone ranks it with the
|
|
53
|
+
* values the domain leaves out and the bracket its label starts with floats it
|
|
54
|
+
* above them all. Both places a key is ordered read this — `sectionOf` for the
|
|
55
|
+
* rows it draws, and `derivedColorScale` for the entries it hands back, which a
|
|
56
|
+
* display reads for what its key lists.
|
|
57
|
+
*/
|
|
58
|
+
export function missingRowLast(a, b) {
|
|
59
|
+
return Number(a.missing ?? false) - Number(b.missing ?? false);
|
|
60
|
+
}
|
|
38
61
|
/** Whether a scale has anything for a key to show. */
|
|
39
62
|
export function colorScaleIsEmpty(scale) {
|
|
40
63
|
return scale.kind === 'categorical' && scale.entries.length === 0;
|
package/esm/ui/colors.d.ts
CHANGED
|
@@ -29,6 +29,23 @@ export declare const paletteColors: {
|
|
|
29
29
|
* Past the end is the caller's problem, and the two callers answer differently
|
|
30
30
|
* on purpose: an attribute palette-by hashes the VALUE (stable across
|
|
31
31
|
* re-palettes), while a by-position painter has no value to hash and wraps.
|
|
32
|
+
*
|
|
33
|
+
* **It holds 14 pairs `similarColors` calls the same** — five schemes' blues,
|
|
34
|
+
* oranges, greens, reds and pinks — and deduping it at construction is the
|
|
35
|
+
* wrong reading of that, measured on the 38 GENCODE gene biotypes. Hashed,
|
|
36
|
+
* which is what a track with no `colorDomain` does, 30 of them land on 22
|
|
37
|
+
* colors and 38 on 26; the loss is the birthday collision on 40 slots, not the
|
|
38
|
+
* near-twins, and only 3 of the pairs they land on read alike. Pruning to the
|
|
39
|
+
* 30 distinct entries makes that 23 and 24, so it costs ten colors and buys
|
|
40
|
+
* nothing.
|
|
41
|
+
*
|
|
42
|
+
* The near-twins bite the PINNED case instead, where a `domain` spends the
|
|
43
|
+
* list in order: 30 listed values take 30 colors today and 7 of those pairs
|
|
44
|
+
* read alike. Ordering the distinct 30 first and the twins behind them fixes
|
|
45
|
+
* that outright (0 pairs at 30 listed values, 11 at 38 where the twins are
|
|
46
|
+
* reached anyway) and costs no colors — but it moves every hashed color in
|
|
47
|
+
* marks, GWAS, canvas, multi-row and the arrangement dialog, so it is a pass
|
|
48
|
+
* with a figure refresh in it.
|
|
32
49
|
*/
|
|
33
50
|
export declare const categoricalPalette: string[];
|
|
34
51
|
/**
|
|
@@ -38,10 +55,41 @@ export declare const categoricalPalette: string[];
|
|
|
38
55
|
* paint it pink. A non-negative integer takes the slot it names, anchored at
|
|
39
56
|
* 1, so `1`, `2`, `3` walk the palette in order and stay distinct; anything
|
|
40
57
|
* else hashes in, stable for the same reason at the cost of an occasional
|
|
41
|
-
* collision.
|
|
58
|
+
* collision. `categoricalScale` is the same rule with a domain.
|
|
42
59
|
*/
|
|
43
60
|
export declare function categoricalValueColor(value: string): string;
|
|
44
61
|
export declare function categoricalValueColor<T>(value: string, palette: readonly T[]): T;
|
|
62
|
+
/**
|
|
63
|
+
* The categorical rule every scaled channel resolves through. With no
|
|
64
|
+
* `domain` a value takes `categoricalValueColor`'s slot in `range`. With one,
|
|
65
|
+
* the listed values take `range` in order, continuing into the `fallback`
|
|
66
|
+
* entries `range` lacks past its end, and any other value takes a slot of the
|
|
67
|
+
* whole list derived from itself that no listed value holds, nor one
|
|
68
|
+
* `isNear` calls the same. A value's entry depends only on the value and the
|
|
69
|
+
* declaration, so every region agrees on it, and adding a listed value moves
|
|
70
|
+
* only the unlisted values on the slots it takes.
|
|
71
|
+
*/
|
|
72
|
+
export declare function categoricalScale<T>(domain: readonly (string | number)[] | undefined, range: readonly T[], { fallback, isNear, }?: {
|
|
73
|
+
fallback?: readonly T[];
|
|
74
|
+
isNear?: (a: T, b: T) => boolean;
|
|
75
|
+
}): (value: string) => T;
|
|
76
|
+
/**
|
|
77
|
+
* Whether two CSS colors read as one: under 0.05 apart in OKLab, where the
|
|
78
|
+
* wide palette's tableau and category10 oranges sit 0.003 apart.
|
|
79
|
+
*/
|
|
80
|
+
export declare function similarColors(a: string, b: string): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* `categoricalScale` for a color channel: `palette` (the wide palette when
|
|
83
|
+
* empty) spent in `domain` order and continued into the wide palette, and an
|
|
84
|
+
* unlisted value never on a listed value's color or one that reads the same.
|
|
85
|
+
*/
|
|
86
|
+
export declare function categoricalColorScale(domain: readonly (string | number)[] | undefined, palette?: readonly string[]): (value: string) => string;
|
|
87
|
+
/**
|
|
88
|
+
* The color one value of a categorical color channel paints, by
|
|
89
|
+
* `categoricalColorScale`. A value-less feature is neutral grey, and an array
|
|
90
|
+
* value joins the way a group key does.
|
|
91
|
+
*/
|
|
92
|
+
export declare function categoricalColor(value: unknown, domain?: readonly string[], palette?: readonly string[]): string;
|
|
45
93
|
/**
|
|
46
94
|
* Deterministic non-negative 32-bit hash of a string.
|
|
47
95
|
*/
|
package/esm/ui/colors.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as convert from '../util/color-bits/convert.js';
|
|
2
|
+
import { NO_CATEGORY_COLOR, relight } from '../util/color/index.js';
|
|
3
|
+
import { cssColorToNormalizedRgb } from '../util/colorBits.js';
|
|
4
|
+
import { valueText } from '../util/groupKeys.js';
|
|
2
5
|
const category10 = [
|
|
3
6
|
'#1f77b4',
|
|
4
7
|
'#ff7f0e',
|
|
@@ -108,16 +111,148 @@ export const paletteColors = {
|
|
|
108
111
|
* Past the end is the caller's problem, and the two callers answer differently
|
|
109
112
|
* on purpose: an attribute palette-by hashes the VALUE (stable across
|
|
110
113
|
* re-palettes), while a by-position painter has no value to hash and wraps.
|
|
114
|
+
*
|
|
115
|
+
* **It holds 14 pairs `similarColors` calls the same** — five schemes' blues,
|
|
116
|
+
* oranges, greens, reds and pinks — and deduping it at construction is the
|
|
117
|
+
* wrong reading of that, measured on the 38 GENCODE gene biotypes. Hashed,
|
|
118
|
+
* which is what a track with no `colorDomain` does, 30 of them land on 22
|
|
119
|
+
* colors and 38 on 26; the loss is the birthday collision on 40 slots, not the
|
|
120
|
+
* near-twins, and only 3 of the pairs they land on read alike. Pruning to the
|
|
121
|
+
* 30 distinct entries makes that 23 and 24, so it costs ten colors and buys
|
|
122
|
+
* nothing.
|
|
123
|
+
*
|
|
124
|
+
* The near-twins bite the PINNED case instead, where a `domain` spends the
|
|
125
|
+
* list in order: 30 listed values take 30 colors today and 7 of those pairs
|
|
126
|
+
* read alike. Ordering the distinct 30 first and the twins behind them fixes
|
|
127
|
+
* that outright (0 pairs at 30 listed values, 11 at 38 where the twins are
|
|
128
|
+
* reached anyway) and costs no colors — but it moves every hashed color in
|
|
129
|
+
* marks, GWAS, canvas, multi-row and the arrangement dialog, so it is a pass
|
|
130
|
+
* with a figure refresh in it.
|
|
111
131
|
*/
|
|
112
132
|
export const categoricalPalette = [
|
|
113
133
|
...new Set([...tableau10, ...set1, ...dark2, ...set2, ...category10].filter(hex => !NEUTRALS.has(hex.toLowerCase()))),
|
|
114
134
|
];
|
|
115
135
|
export function categoricalValueColor(value, palette = categoricalPalette) {
|
|
116
|
-
|
|
136
|
+
return palette[valueSlot(value, palette.length)];
|
|
137
|
+
}
|
|
138
|
+
function valueSlot(value, n) {
|
|
117
139
|
const num = Number(value);
|
|
118
140
|
return value !== '' && Number.isInteger(num) && num >= 0
|
|
119
|
-
?
|
|
120
|
-
:
|
|
141
|
+
? (num + n - 1) % n
|
|
142
|
+
: hashString(value) % n;
|
|
143
|
+
}
|
|
144
|
+
function entryKey(entry) {
|
|
145
|
+
return typeof entry === 'string' ? entry.toLowerCase() : entry;
|
|
146
|
+
}
|
|
147
|
+
// The first slot derived from the value that `taken` does not hold, trying
|
|
148
|
+
// rehashes before walking, so the values landing on a taken slot spread over
|
|
149
|
+
// the free ones instead of piling onto the next.
|
|
150
|
+
function freeSlot(value, size, taken) {
|
|
151
|
+
let slot = valueSlot(value, size);
|
|
152
|
+
for (let salt = 1; taken.has(slot) && salt <= size; salt++) {
|
|
153
|
+
slot = hashString(`${salt}:${value}`) % size;
|
|
154
|
+
}
|
|
155
|
+
for (let step = 0; taken.has(slot) && step < size; step++) {
|
|
156
|
+
slot = (slot + 1) % size;
|
|
157
|
+
}
|
|
158
|
+
return slot;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The categorical rule every scaled channel resolves through. With no
|
|
162
|
+
* `domain` a value takes `categoricalValueColor`'s slot in `range`. With one,
|
|
163
|
+
* the listed values take `range` in order, continuing into the `fallback`
|
|
164
|
+
* entries `range` lacks past its end, and any other value takes a slot of the
|
|
165
|
+
* whole list derived from itself that no listed value holds, nor one
|
|
166
|
+
* `isNear` calls the same. A value's entry depends only on the value and the
|
|
167
|
+
* declaration, so every region agrees on it, and adding a listed value moves
|
|
168
|
+
* only the unlisted values on the slots it takes.
|
|
169
|
+
*/
|
|
170
|
+
export function categoricalScale(domain, range, { fallback = [], isNear, } = {}) {
|
|
171
|
+
const base = range.length ? range : fallback;
|
|
172
|
+
const listed = [...new Set((domain ?? []).map(String))].filter(v => v !== '');
|
|
173
|
+
if (listed.length === 0) {
|
|
174
|
+
return value => base[valueSlot(value, base.length)];
|
|
175
|
+
}
|
|
176
|
+
const seen = new Set(base.map(entryKey));
|
|
177
|
+
const entries = [
|
|
178
|
+
...base,
|
|
179
|
+
...fallback.filter(entry => {
|
|
180
|
+
const key = entryKey(entry);
|
|
181
|
+
return seen.has(key) ? false : (seen.add(key), true);
|
|
182
|
+
}),
|
|
183
|
+
];
|
|
184
|
+
const size = entries.length;
|
|
185
|
+
const rank = new Map(listed.map((value, i) => [value, i]));
|
|
186
|
+
const listedSlots = new Set(listed.map((_, i) => i % size));
|
|
187
|
+
const taken = new Set(entries.flatMap((entry, i) => listedSlots.has(i) ||
|
|
188
|
+
(isNear && [...listedSlots].some(j => isNear(entries[j], entry)))
|
|
189
|
+
? [i]
|
|
190
|
+
: []));
|
|
191
|
+
return value => {
|
|
192
|
+
const i = rank.get(value);
|
|
193
|
+
return entries[i !== undefined
|
|
194
|
+
? i % size
|
|
195
|
+
: taken.size < size
|
|
196
|
+
? freeSlot(value, size, taken)
|
|
197
|
+
: valueSlot(value, size)];
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const oklabByColor = new Map();
|
|
201
|
+
function oklabOf(color) {
|
|
202
|
+
let lab = oklabByColor.get(color);
|
|
203
|
+
if (lab === undefined) {
|
|
204
|
+
lab = convert.xyzd65ToOklab(...convert.xyzd50ToD65(...convert.srgbToXyzd50(...cssColorToNormalizedRgb(color))));
|
|
205
|
+
oklabByColor.set(color, lab);
|
|
206
|
+
}
|
|
207
|
+
return lab;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Whether two CSS colors read as one: under 0.05 apart in OKLab, where the
|
|
211
|
+
* wide palette's tableau and category10 oranges sit 0.003 apart.
|
|
212
|
+
*/
|
|
213
|
+
export function similarColors(a, b) {
|
|
214
|
+
const [l1, a1, b1] = oklabOf(a);
|
|
215
|
+
const [l2, a2, b2] = oklabOf(b);
|
|
216
|
+
return Math.hypot(l1 - l2, a1 - a2, b1 - b2) < 0.05;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* `categoricalScale` for a color channel: `palette` (the wide palette when
|
|
220
|
+
* empty) spent in `domain` order and continued into the wide palette, and an
|
|
221
|
+
* unlisted value never on a listed value's color or one that reads the same.
|
|
222
|
+
*/
|
|
223
|
+
export function categoricalColorScale(domain, palette = []) {
|
|
224
|
+
return categoricalScale(domain, palette, {
|
|
225
|
+
fallback: categoricalPalette,
|
|
226
|
+
isNear: similarColors,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
const MAX_CACHED_SCALES = 16;
|
|
230
|
+
const scaleCache = new Map();
|
|
231
|
+
function cachedColorScale(domain, palette) {
|
|
232
|
+
const key = `${domain.join('\u001F')}\u001E${palette.join('\u001F')}`;
|
|
233
|
+
let scale = scaleCache.get(key);
|
|
234
|
+
if (scale === undefined) {
|
|
235
|
+
if (scaleCache.size >= MAX_CACHED_SCALES) {
|
|
236
|
+
scaleCache.delete(scaleCache.keys().next().value);
|
|
237
|
+
}
|
|
238
|
+
scale = categoricalColorScale(domain, palette);
|
|
239
|
+
scaleCache.set(key, scale);
|
|
240
|
+
}
|
|
241
|
+
return scale;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* The color one value of a categorical color channel paints, by
|
|
245
|
+
* `categoricalColorScale`. A value-less feature is neutral grey, and an array
|
|
246
|
+
* value joins the way a group key does.
|
|
247
|
+
*/
|
|
248
|
+
export function categoricalColor(value, domain = [], palette = []) {
|
|
249
|
+
const label = valueText(value);
|
|
250
|
+
if (label === '') {
|
|
251
|
+
return NO_CATEGORY_COLOR;
|
|
252
|
+
}
|
|
253
|
+
return domain.length === 0 && palette.length === 0
|
|
254
|
+
? categoricalValueColor(label)
|
|
255
|
+
: cachedColorScale(domain, palette)(label);
|
|
121
256
|
}
|
|
122
257
|
// only category10 and set1 are imported by name; the rest are reached through
|
|
123
258
|
// paletteColors above
|
|
@@ -5,7 +5,19 @@ import type { CSSProperties } from 'react';
|
|
|
5
5
|
* washes them out.
|
|
6
6
|
*
|
|
7
7
|
* One definition because the alternative was proven to fail: `highlightBoxColors`
|
|
8
|
-
* exists for the same reason, after two backends drifted apart on their own
|
|
9
|
-
* literals kept in step by a comment.
|
|
8
|
+
* below exists for the same reason, after two backends drifted apart on their own
|
|
9
|
+
* alpha literals kept in step by a comment.
|
|
10
10
|
*/
|
|
11
11
|
export declare const hoverBoxStyle: CSSProperties;
|
|
12
|
+
/**
|
|
13
|
+
* The border and fill of a pinned highlight box, off the palette's highlight
|
|
14
|
+
* hue. The chrome draws it on screen and `renderDisplaySvg` bakes it into the
|
|
15
|
+
* export, so both reach one definition.
|
|
16
|
+
*
|
|
17
|
+
* JBrowse's own `alpha`, not Material UI's: the SVG export reaches this module
|
|
18
|
+
* and should not drag @mui/material along.
|
|
19
|
+
*/
|
|
20
|
+
export declare function highlightBoxColors(highlightMain: string): {
|
|
21
|
+
border: string;
|
|
22
|
+
fill: string;
|
|
23
|
+
};
|
package/esm/ui/hoverBoxStyle.js
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
|
+
import { alpha } from './palette.js';
|
|
1
2
|
/**
|
|
2
3
|
* The hover mark for a cell or block on a canvas display: a white wash plus a
|
|
3
4
|
* dark border, never a color tint — the cell colors are the data, and a tint
|
|
4
5
|
* washes them out.
|
|
5
6
|
*
|
|
6
7
|
* One definition because the alternative was proven to fail: `highlightBoxColors`
|
|
7
|
-
* exists for the same reason, after two backends drifted apart on their own
|
|
8
|
-
* literals kept in step by a comment.
|
|
8
|
+
* below exists for the same reason, after two backends drifted apart on their own
|
|
9
|
+
* alpha literals kept in step by a comment.
|
|
9
10
|
*/
|
|
10
11
|
export const hoverBoxStyle = {
|
|
11
12
|
border: '1px solid rgba(0,0,0,0.5)',
|
|
12
13
|
background: 'rgba(255,255,255,0.3)',
|
|
13
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* The border and fill of a pinned highlight box, off the palette's highlight
|
|
17
|
+
* hue. The chrome draws it on screen and `renderDisplaySvg` bakes it into the
|
|
18
|
+
* export, so both reach one definition.
|
|
19
|
+
*
|
|
20
|
+
* JBrowse's own `alpha`, not Material UI's: the SVG export reaches this module
|
|
21
|
+
* and should not drag @mui/material along.
|
|
22
|
+
*/
|
|
23
|
+
export function highlightBoxColors(highlightMain) {
|
|
24
|
+
return {
|
|
25
|
+
border: alpha(highlightMain, 0.9),
|
|
26
|
+
fill: alpha(highlightMain, 0.25),
|
|
27
|
+
};
|
|
28
|
+
}
|
package/esm/ui/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { type JBrowseTheme, type SerializableThemeArgs, type ThemeMap, colorFwdStrand, colorInterchrom, colorLongInsert, colorLongreadInv,
|
|
1
|
+
export { type JBrowseTheme, type SerializableThemeArgs, type ThemeMap, colorFwdStrand, colorInterchrom, colorLongInsert, colorLongreadInv, colorPairLL, colorPairLR, colorPairLRDark, colorPairRL, colorPairRR, colorRevStrand, colorShortInsert, colorSplitReadInversion, colorSupplementary, colorUnmappedMate, colorUnmappedMateDark, createJBrowseBaseTheme, createJBrowseTheme, createJBrowseThemeFromArgs, defaultThemes, methylated5hmC, methylated5mC, tagColorPalette, unmethylated5mC, } from './theme.ts';
|
|
2
2
|
export { default as BaseExportSvgDialog } from './BaseExportSvgDialog.tsx';
|
|
3
3
|
export type { BaseExportSvgOptions } from './BaseExportSvgDialog.tsx';
|
|
4
4
|
export { default as ExportSvgDialog } from './ExportSvgDialog.tsx';
|
|
@@ -8,7 +8,8 @@ export { default as AssemblySelector } from './AssemblySelector.tsx';
|
|
|
8
8
|
export { useAssemblySelection } from './useAssemblySelection.ts';
|
|
9
9
|
export { useRecentLocations } from './useRecentLocations.ts';
|
|
10
10
|
export type { RecentLocation } from './useRecentLocations.ts';
|
|
11
|
-
export { RefNameAutocompleteEndAdornment,
|
|
11
|
+
export { RefNameAutocompleteEndAdornment, default as RefNameAutocomplete, } from './RefNameAutocomplete/index.tsx';
|
|
12
|
+
export { adornmentReservePx, getInputWidth, } from './RefNameAutocomplete/util.ts';
|
|
12
13
|
export { default as CascadingMenu } from './CascadingMenu.tsx';
|
|
13
14
|
export { default as CascadingMenuButton } from './CascadingMenuButton.tsx';
|
|
14
15
|
export { default as ContextMenu } from './ContextMenu.tsx';
|
|
@@ -60,6 +61,7 @@ export { default as SettingsChangesTable } from './SettingsChangesTable.tsx';
|
|
|
60
61
|
export { default as ActionLink } from './ActionLink.tsx';
|
|
61
62
|
export { default as ExternalLink } from './ExternalLink.tsx';
|
|
62
63
|
export { default as SanitizedHTML } from './SanitizedHTML.tsx';
|
|
64
|
+
export { default as BaseTooltip } from './LazyBaseTooltip.tsx';
|
|
63
65
|
export { default as PluggableComponent } from './PluggableComponent.tsx';
|
|
64
66
|
export { default as PluggableComponents } from './PluggableComponents.tsx';
|
|
65
67
|
export type { ComponentExtensionPointName } from './PluggableComponents.tsx';
|
|
@@ -78,7 +80,7 @@ export { default as Crosshairs } from './Crosshairs.tsx';
|
|
|
78
80
|
export { hoverBoxStyle } from './hoverBoxStyle.ts';
|
|
79
81
|
export { useMouseState, useMouseTracking } from './useMouseTracking.ts';
|
|
80
82
|
export type { MouseState, MouseTracker } from './useMouseTracking.ts';
|
|
81
|
-
export
|
|
83
|
+
export { VIEW_HEADER_HEIGHT } from './viewHeaderHeight.ts';
|
|
82
84
|
export { LEGEND_ROW_HEIGHT, LEGEND_SVG_GUTTER_WIDTH, LEGEND_SWATCH, default as SvgColorLegend, } from './SvgColorLegend.tsx';
|
|
83
85
|
export type { ColorLegendEntry } from './SvgColorLegend.tsx';
|
|
84
86
|
export { measureLegendText } from './measureLegendText.ts';
|