@jbrowse/core 5.0.0-beta.1 → 5.0.0-beta.11
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 +1709 -390
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.js +5 -5
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.d.ts +3 -5
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.js +34 -29
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCard.js +1 -4
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.d.ts +11 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.js +37 -14
- package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.d.ts +1 -1
- package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.js +15 -31
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +4 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.js +12 -25
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetailsFrame.d.ts +11 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetailsFrame.js +11 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.d.ts +8 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.js +24 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Formatter.js +6 -4
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.d.ts +4 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.js +17 -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 +6 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +7 -18
- package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.d.ts +16 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.js +49 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/util.d.ts +0 -8
- package/esm/BaseFeatureWidget/BaseFeatureDetail/util.js +6 -29
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceContents.js +7 -34
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.d.ts +2 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceName.js +2 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/TranscriptSelector.js +3 -1
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.d.ts +12 -0
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.js +12 -5
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/useSequenceData.js +8 -5
- package/esm/BaseFeatureWidget/configSchema.d.ts +1 -1
- package/esm/BaseFeatureWidget/formatDetails.d.ts +13 -29
- package/esm/BaseFeatureWidget/formatDetails.js +62 -83
- package/esm/BaseFeatureWidget/index.d.ts +2 -1
- package/esm/BaseFeatureWidget/stateModelFactory.d.ts +42 -29
- package/esm/BaseFeatureWidget/stateModelFactory.js +98 -98
- package/esm/BaseFeatureWidget/types.d.ts +12 -6
- package/esm/BaseFeatureWidget/util.d.ts +0 -10
- package/esm/BaseFeatureWidget/util.js +0 -17
- package/esm/CorePlugin.js +34 -3
- package/esm/PluginLoader.d.ts +24 -13
- package/esm/PluginLoader.js +167 -51
- package/esm/PluginManager.d.ts +130 -24
- package/esm/PluginManager.js +180 -32
- package/esm/ReExports/MuiDataGridReExports.d.ts +1 -0
- package/esm/ReExports/MuiDataGridReExports.js +2 -2
- package/esm/ReExports/coreModules.generated.d.ts +2 -0
- package/esm/ReExports/coreModules.generated.js +530 -0
- package/esm/ReExports/coreWorkerModules.generated.d.ts +2 -0
- package/esm/ReExports/coreWorkerModules.generated.js +490 -0
- package/esm/ReExports/frameworkModules.d.ts +2 -0
- package/esm/ReExports/frameworkModules.js +68 -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 +528 -79
- package/esm/ReExports/modules.d.ts +1 -1
- package/esm/ReExports/modules.js +10 -165
- package/esm/ReExports/registry.d.ts +1 -0
- package/esm/ReExports/registry.js +23 -5
- package/esm/ReExports/uiStub.d.ts +3 -0
- package/esm/ReExports/uiStub.js +33 -0
- package/esm/ReExports/workerModules.d.ts +2 -0
- package/esm/ReExports/workerModules.js +11 -0
- package/esm/TextSearch/TextSearchManager.d.ts +27 -13
- package/esm/TextSearch/TextSearchManager.js +77 -36
- package/esm/TextSearch/places.d.ts +12 -0
- package/esm/TextSearch/places.js +94 -0
- package/esm/assemblyManager/assembly.d.ts +21 -19
- package/esm/assemblyManager/assembly.js +28 -26
- package/esm/assemblyManager/assemblyAdapters.d.ts +1 -1
- package/esm/assemblyManager/assemblyAdapters.js +8 -2
- package/esm/assemblyManager/assemblyConfigSchema.d.ts +31 -90
- package/esm/assemblyManager/assemblyConfigSchema.js +35 -47
- package/esm/assemblyManager/assemblyManager.d.ts +35 -180
- package/esm/assemblyManager/assemblyManager.js +47 -51
- package/esm/assemblyManager/expandAssemblyConfigShorthand.d.ts +25 -18
- package/esm/assemblyManager/expandAssemblyConfigShorthand.js +78 -49
- package/esm/assemblyManager/geneticCodes.js +2 -5
- package/esm/assemblyManager/getSequenceAdapterConfig.d.ts +10 -0
- package/esm/assemblyManager/getSequenceAdapterConfig.js +10 -0
- package/esm/assemblyManager/indexAssemblyNames.d.ts +9 -0
- package/esm/assemblyManager/indexAssemblyNames.js +22 -0
- package/esm/assemblyManager/loadRefNameMap.d.ts +1 -1
- package/esm/assemblyManager/loadRefNameMap.js +4 -9
- package/esm/assemblyManager/refNameMapKey.d.ts +7 -0
- package/esm/assemblyManager/refNameMapKey.js +12 -0
- package/esm/checkPlugins.d.ts +2 -0
- package/esm/checkPlugins.js +38 -17
- package/esm/configuration/bamIndexFields.d.ts +49 -0
- package/esm/configuration/bamIndexFields.js +41 -0
- package/esm/configuration/configurationSchema.d.ts +101 -71
- package/esm/configuration/configurationSchema.js +207 -134
- package/esm/configuration/configurationSchemaUnion.d.ts +39 -0
- package/esm/configuration/configurationSchemaUnion.js +56 -0
- package/esm/configuration/configurationSlot.d.ts +150 -60
- package/esm/configuration/configurationSlot.js +103 -75
- package/esm/configuration/fillLocations.d.ts +14 -0
- package/esm/configuration/fillLocations.js +14 -0
- 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/fullConfSnapshot.d.ts +4 -19
- package/esm/configuration/fullConfSnapshot.js +30 -52
- package/esm/configuration/getConf.d.ts +45 -41
- package/esm/configuration/getConf.js +111 -44
- package/esm/configuration/index.d.ts +26 -11
- package/esm/configuration/index.js +16 -7
- package/esm/configuration/indexType.d.ts +26 -0
- package/esm/configuration/indexType.js +38 -0
- package/esm/configuration/mergeFormatCallbacks.d.ts +6 -7
- package/esm/configuration/mergeFormatCallbacks.js +13 -10
- package/esm/configuration/plot.d.ts +61 -0
- package/esm/configuration/plot.js +142 -0
- package/esm/configuration/readConfObject.d.ts +2 -24
- package/esm/configuration/readConfObject.js +20 -63
- package/esm/configuration/requirements.d.ts +37 -0
- package/esm/configuration/requirements.js +88 -0
- package/esm/configuration/schemaRegistry.d.ts +32 -15
- package/esm/configuration/schemaRegistry.js +33 -35
- package/esm/configuration/schemaTypes.d.ts +21 -5
- package/esm/configuration/schemaTypes.js +66 -55
- package/esm/configuration/slotFacade.d.ts +12 -29
- package/esm/configuration/slotFacade.js +44 -23
- package/esm/configuration/snapshotPreprocess.d.ts +43 -0
- package/esm/configuration/snapshotPreprocess.js +161 -0
- package/esm/configuration/tabixIndexFields.d.ts +30 -4
- package/esm/configuration/tabixIndexFields.js +21 -4
- package/esm/configuration/tabixShorthand.d.ts +34 -17
- package/esm/configuration/tabixShorthand.js +49 -22
- package/esm/configuration/types.d.ts +182 -43
- package/esm/configuration/uriShorthand.d.ts +9 -0
- package/esm/configuration/uriShorthand.js +16 -0
- package/esm/data_adapters/BaseAdapter/BaseAdapter.d.ts +13 -19
- package/esm/data_adapters/BaseAdapter/BaseAdapter.js +12 -19
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +40 -2
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +68 -5
- package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +40 -0
- package/esm/data_adapters/BaseAdapter/featureDensity.js +31 -0
- package/esm/data_adapters/BaseAdapter/index.d.ts +23 -3
- package/esm/data_adapters/BaseAdapter/index.js +1 -0
- package/esm/data_adapters/BaseAdapter/rowSources.d.ts +37 -0
- package/esm/data_adapters/BaseAdapter/rowSources.js +7 -0
- package/esm/data_adapters/BaseAdapter/stats.d.ts +33 -1
- package/esm/data_adapters/BaseAdapter/stats.js +52 -13
- package/esm/data_adapters/BaseAdapter/types.d.ts +8 -12
- package/esm/data_adapters/BaseAdapter/zoomRange.d.ts +10 -0
- package/esm/data_adapters/CytobandAdapter/CytobandAdapter.js +1 -1
- package/esm/data_adapters/CytobandAdapter/configSchema.d.ts +7 -11
- package/esm/data_adapters/CytobandAdapter/configSchema.js +3 -17
- package/esm/data_adapters/dataAdapterCache.d.ts +19 -2
- package/esm/data_adapters/dataAdapterCache.js +44 -10
- package/esm/data_adapters/getFeatureAdapter.d.ts +6 -4
- package/esm/data_adapters/getFeatureAdapter.js +8 -8
- package/esm/data_adapters/getSequenceSubAdapter.d.ts +7 -9
- package/esm/data_adapters/getSequenceSubAdapter.js +8 -10
- package/esm/pluggableElementTypes/AdapterType.d.ts +8 -8
- package/esm/pluggableElementTypes/AdapterType.js +1 -1
- package/esm/pluggableElementTypes/DisplayType.d.ts +53 -16
- package/esm/pluggableElementTypes/DisplayType.js +28 -12
- package/esm/pluggableElementTypes/LazyStateModelElement.d.ts +32 -0
- package/esm/pluggableElementTypes/LazyStateModelElement.js +77 -0
- package/esm/pluggableElementTypes/PluggableElementBase.d.ts +3 -5
- package/esm/pluggableElementTypes/PluggableElementBase.js +3 -5
- package/esm/pluggableElementTypes/RpcMethodType.d.ts +11 -1
- package/esm/pluggableElementTypes/RpcMethodType.js +25 -9
- package/esm/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions.d.ts +1 -2
- package/esm/pluggableElementTypes/TextSearchAdapterType.d.ts +7 -7
- package/esm/pluggableElementTypes/ViewType.d.ts +20 -4
- package/esm/pluggableElementTypes/ViewType.js +32 -4
- package/esm/pluggableElementTypes/WidgetType.d.ts +6 -0
- package/esm/pluggableElementTypes/WidgetType.js +6 -0
- package/esm/pluggableElementTypes/addMenuItems.d.ts +3 -2
- package/esm/pluggableElementTypes/extendElementType.d.ts +1 -2
- package/esm/pluggableElementTypes/extendElementType.js +9 -5
- package/esm/pluggableElementTypes/index.d.ts +2 -1
- package/esm/pluggableElementTypes/index.js +2 -9
- package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +19 -9
- package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +122 -28
- package/esm/pluggableElementTypes/models/BaseDisplayModel.js +155 -11
- package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +65 -16
- package/esm/pluggableElementTypes/models/BaseTrackModel.js +179 -117
- package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +87 -18
- package/esm/pluggableElementTypes/models/BaseViewModel.js +54 -11
- package/esm/pluggableElementTypes/models/InternetAccountModel.d.ts +26 -16
- package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +15 -11
- package/esm/pluggableElementTypes/models/assertDisplayContract.js +25 -32
- 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 +108 -147
- package/esm/pluggableElementTypes/models/baseTrackConfig.js +96 -73
- package/esm/pluggableElementTypes/models/components/SaveTrackData.js +4 -6
- 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 +23 -13
- package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.js +80 -48
- package/esm/pluggableElementTypes/models/index.d.ts +2 -3
- package/esm/pluggableElementTypes/models/index.js +2 -3
- package/esm/pluggableElementTypes/models/migrateTrackConfig.d.ts +15 -1
- package/esm/pluggableElementTypes/models/migrateTrackConfig.js +85 -25
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.d.ts +4 -3
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.js +141 -19
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/types.d.ts +3 -3
- package/esm/pluginDefinitions.d.ts +34 -7
- package/esm/pluginDefinitions.js +54 -20
- package/esm/rpc/BaseRpcDriver.d.ts +2 -2
- package/esm/rpc/BaseRpcDriver.js +25 -30
- package/esm/rpc/MainThreadRpcDriver.d.ts +2 -2
- package/esm/rpc/MainThreadRpcDriver.js +13 -8
- package/esm/rpc/RpcClient.d.ts +18 -6
- package/esm/rpc/RpcClient.js +51 -16
- package/esm/rpc/RpcManager.d.ts +14 -10
- package/esm/rpc/RpcManager.js +11 -1
- package/esm/rpc/RpcRegistry.d.ts +40 -7
- package/esm/rpc/RpcServer.d.ts +3 -1
- package/esm/rpc/RpcServer.js +19 -12
- package/esm/rpc/WebWorkerRpcDriver.d.ts +11 -4
- package/esm/rpc/WebWorkerRpcDriver.js +64 -68
- package/esm/rpc/byteBudget.d.ts +20 -5
- package/esm/rpc/byteBudget.js +16 -5
- package/esm/rpc/configSchema.d.ts +7 -21
- package/esm/rpc/coreRpcMethods.d.ts +4 -0
- package/esm/rpc/coreRpcMethods.js +4 -0
- package/esm/rpc/methods/CoreGetEncodedFeature.d.ts +13 -0
- package/esm/rpc/methods/CoreGetEncodedFeature.js +32 -0
- package/esm/rpc/methods/CoreGetEncodedLayers.d.ts +16 -0
- package/esm/rpc/methods/CoreGetEncodedLayers.js +59 -0
- package/esm/rpc/methods/CoreGetExportData.js +3 -4
- package/esm/rpc/methods/CoreGetFeatureDensity.d.ts +11 -0
- package/esm/rpc/methods/CoreGetFeatureDensity.js +22 -0
- package/esm/rpc/methods/CoreGetFeatures.js +3 -5
- package/esm/rpc/methods/CoreGetRefNames.js +2 -12
- package/esm/rpc/methods/CoreGetRegionByteEstimate.js +1 -1
- package/esm/rpc/methods/CoreGetSequence.js +2 -2
- package/esm/rpc/methods/CoreLoadAdapterCode.d.ts +13 -0
- package/esm/rpc/methods/CoreLoadAdapterCode.js +16 -0
- package/esm/rpc/methods/layerFeatures.d.ts +33 -0
- package/esm/rpc/methods/layerFeatures.js +29 -0
- package/esm/svg/SvgExport.js +6 -7
- package/esm/svg/SvgThemeProviders.d.ts +12 -0
- package/esm/svg/SvgThemeProviders.js +15 -0
- package/esm/svg/exportViewSvg.d.ts +28 -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/svgId.d.ts +1 -1
- package/esm/svg/svgId.js +1 -1
- package/esm/svg/svgReady.d.ts +9 -7
- package/esm/svg/svgReady.js +8 -7
- package/esm/svg/trackNames.d.ts +7 -5
- package/esm/svg/trackNames.js +12 -9
- package/esm/svg/wrapSvgExport.js +6 -74
- package/esm/ui/AddCustomPluginDialog.js +3 -8
- package/esm/ui/AppReadyMarker.d.ts +45 -0
- package/esm/ui/AppReadyMarker.js +89 -0
- package/esm/ui/BaseExportSvgDialog.d.ts +1 -1
- package/esm/ui/CascadingMenu.js +181 -104
- package/esm/ui/DropDownMenu.js +2 -1
- package/esm/ui/ErrorBanner.js +1 -1
- package/esm/ui/ErrorBoundary.d.ts +2 -2
- package/esm/ui/ErrorMessageStackTraceContents.js +2 -1
- package/esm/ui/ErrorMessageStackTraceDialog.js +5 -11
- package/esm/ui/ExportSvgDialog.d.ts +1 -1
- package/esm/ui/FileDropZone.js +2 -1
- 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 -50
- 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/LegendSwatchGlyph.js +26 -21
- package/esm/ui/LoadingOverlay.d.ts +14 -0
- package/esm/ui/LoadingOverlay.js +4 -2
- package/esm/ui/MenuTypes.d.ts +23 -53
- package/esm/ui/MenuTypes.js +3 -0
- package/esm/ui/MonospaceTextField.d.ts +2 -1
- package/esm/ui/MonospaceTextField.js +23 -20
- package/esm/ui/PaletteContext.d.ts +10 -5
- package/esm/ui/PaletteContext.js +44 -6
- package/esm/ui/RefNameAutocomplete/SearchOption.d.ts +13 -0
- package/esm/ui/RefNameAutocomplete/SearchOption.js +45 -0
- package/esm/ui/RefNameAutocomplete/index.d.ts +1 -2
- package/esm/ui/RefNameAutocomplete/index.js +8 -2
- package/esm/ui/RefNameAutocomplete/util.d.ts +13 -0
- package/esm/ui/RefNameAutocomplete/util.js +42 -1
- package/esm/ui/ResizeHandle.d.ts +3 -1
- package/esm/ui/ResizeHandle.js +44 -11
- package/esm/ui/ScrollChrome.d.ts +13 -0
- package/esm/ui/ScrollChrome.js +11 -0
- package/esm/ui/ScrollEdgeShadow.d.ts +6 -9
- package/esm/ui/ScrollEdgeShadow.js +14 -35
- package/esm/ui/ScrollZoomToggle.d.ts +4 -27
- package/esm/ui/ScrollZoomToggle.js +34 -51
- package/esm/ui/SessionJsonPanel.d.ts +3 -0
- package/esm/ui/SessionJsonPanel.js +14 -0
- package/esm/ui/SettingsChangesTable.d.ts +1 -0
- package/esm/ui/SettingsChangesTable.js +49 -11
- package/esm/ui/ShareLinkField.d.ts +1 -3
- package/esm/ui/ShareLinkField.js +13 -40
- package/esm/ui/SizeSliderRow.d.ts +1 -3
- package/esm/ui/SizeSliderRow.js +4 -6
- package/esm/ui/SnackbarModel.js +79 -67
- package/esm/ui/StatusProgressBar.js +2 -2
- package/esm/ui/SvgColorLegend.d.ts +9 -4
- package/esm/ui/SvgColorLegend.js +82 -41
- package/esm/ui/VerticalScrollbar.d.ts +13 -34
- package/esm/ui/VerticalScrollbar.js +29 -83
- package/esm/ui/ViewLoadingScreen.d.ts +5 -4
- package/esm/ui/ViewLoadingScreen.js +8 -32
- package/esm/ui/colorScale.d.ts +92 -0
- package/esm/ui/colorScale.js +72 -0
- package/esm/ui/colors.d.ts +64 -0
- package/esm/ui/colors.js +230 -1
- package/esm/ui/hoverBoxStyle.d.ts +14 -2
- package/esm/ui/hoverBoxStyle.js +17 -2
- package/esm/ui/index.d.ts +12 -12
- package/esm/ui/index.js +14 -22
- package/esm/ui/launchViewMenu.js +15 -5
- package/esm/ui/legendMenuItem.d.ts +10 -32
- package/esm/ui/legendMenuItem.js +9 -36
- package/esm/ui/legendSpec.d.ts +15 -8
- package/esm/ui/legendSpec.js +14 -23
- package/esm/ui/makeSizeMenu.d.ts +0 -6
- package/esm/ui/makeSizeMenu.js +6 -30
- package/esm/ui/measureLegendText.js +1 -1
- package/esm/ui/menuItemAdornment.d.ts +9 -20
- package/esm/ui/menuItemAdornment.js +10 -32
- package/esm/ui/menuItems.d.ts +2 -7
- package/esm/ui/menuItems.js +1 -6
- package/esm/ui/multiTrackMenuItems.d.ts +6 -0
- package/esm/ui/palette.d.ts +118 -116
- package/esm/ui/palette.js +114 -75
- package/esm/ui/replaceViewAction.d.ts +1 -1
- package/esm/ui/replaceViewAction.js +1 -1
- package/esm/ui/theme.d.ts +43 -119
- package/esm/ui/theme.js +62 -78
- package/esm/ui/toggleMenuItems.d.ts +1 -3
- package/esm/ui/toggleMenuItems.js +6 -5
- package/esm/ui/useAssemblySelection.d.ts +4 -4
- package/esm/ui/viewHeaderHeight.d.ts +1 -0
- package/esm/ui/viewHeaderHeight.js +1 -0
- package/esm/util/Base1DUtils.d.ts +5 -3
- package/esm/util/Base1DUtils.js +14 -6
- package/esm/util/Base1DViewModel.d.ts +2 -1
- package/esm/util/Base1DViewModel.js +3 -2
- package/esm/util/SvgCanvas.d.ts +15 -13
- package/esm/util/SvgCanvas.js +76 -56
- package/esm/util/TimeTraveller.d.ts +3 -0
- package/esm/util/TimeTraveller.js +34 -2
- package/esm/util/aborting.d.ts +39 -0
- package/esm/util/aborting.js +88 -6
- package/esm/util/adapterMetadata.d.ts +1 -1
- package/esm/util/adapterMetadata.js +6 -5
- package/esm/util/addAndShowTrack.d.ts +2 -5
- package/esm/util/addAndShowTrack.js +5 -1
- package/esm/util/addRelativeUris.d.ts +17 -5
- package/esm/util/addRelativeUris.js +46 -10
- package/esm/util/addTrackFromWidget.d.ts +2 -5
- package/esm/util/addTrackFromWidget.js +5 -4
- package/esm/util/aggregateFieldName.d.ts +10 -0
- package/esm/util/aggregateFieldName.js +8 -0
- package/esm/util/analytics.js +46 -13
- 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/bandHeight.d.ts +10 -0
- package/esm/util/bandHeight.js +29 -0
- package/esm/util/bandLayout.d.ts +4 -4
- package/esm/util/bandLayout.js +4 -4
- package/esm/util/baseDisplayConfig.d.ts +8 -0
- package/esm/util/baseDisplayConfig.js +27 -0
- package/esm/util/bezierConnector.d.ts +4 -3
- package/esm/util/bezierConnector.js +38 -45
- package/esm/util/bgzfWorkerPool.d.ts +20 -74
- package/esm/util/bgzfWorkerPool.js +20 -74
- package/esm/util/binnedAggregate.d.ts +17 -0
- package/esm/util/binnedAggregate.js +275 -0
- package/esm/util/cacheBudgets.d.ts +22 -19
- package/esm/util/cacheBudgets.js +22 -19
- package/esm/util/cachedSetup.d.ts +16 -6
- package/esm/util/cachedSetup.js +108 -38
- package/esm/util/categoricalField.d.ts +56 -0
- package/esm/util/categoricalField.js +73 -0
- package/esm/util/cellMatches.d.ts +23 -0
- package/esm/util/cellMatches.js +264 -0
- package/esm/util/cellsStep.d.ts +29 -0
- package/esm/util/cellsStep.js +437 -0
- package/esm/util/clampToContig.d.ts +17 -0
- package/esm/util/clampToContig.js +19 -0
- package/esm/util/coarseStripHTML.js +1 -2
- 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 +3 -3
- package/esm/util/colorBits.js +19 -44
- package/esm/util/colorRamp.d.ts +49 -5
- package/esm/util/colorRamp.js +169 -18
- package/esm/util/colorScale.d.ts +156 -0
- package/esm/util/colorScale.js +243 -0
- package/esm/util/colorSchemes.d.ts +21 -0
- package/esm/util/colorSchemes.js +30 -0
- package/esm/util/copyToClipboard.js +8 -1
- package/esm/util/{createStopTokenRotation.d.ts → createAbortRotation.d.ts} +21 -23
- package/esm/util/{createStopTokenRotation.js → createAbortRotation.js} +21 -52
- package/esm/util/createSvgRasterCanvas.d.ts +10 -0
- 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 +8 -13
- package/esm/util/expandLooseSearchIndex.d.ts +19 -0
- package/esm/util/expandLooseSearchIndex.js +29 -0
- package/esm/util/featureTable.d.ts +224 -0
- package/esm/util/featureTable.js +366 -0
- package/esm/util/featureTransforms.d.ts +81 -0
- package/esm/util/featureTransforms.js +1231 -0
- package/esm/util/featureTypes.d.ts +24 -0
- package/esm/util/featureTypes.js +35 -0
- package/esm/util/fetchAndMaybeUnzip.js +16 -9
- package/esm/util/fetchContext.d.ts +7 -8
- package/esm/util/fetchContext.js +3 -3
- package/esm/util/fetchHub.d.ts +4 -2
- package/esm/util/fetchHub.js +2 -2
- package/esm/util/fetchPhases.d.ts +10 -10
- 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/formatBytes.js +1 -1
- package/esm/util/formatGuessers.d.ts +25 -14
- package/esm/util/formatGuessers.js +42 -27
- package/esm/util/formatRelativeTime.js +1 -1
- package/esm/util/freezeDeep.d.ts +8 -10
- package/esm/util/freezeDeep.js +8 -10
- package/esm/util/getLocationUri.d.ts +2 -1
- package/esm/util/getLocationUri.js +8 -2
- package/esm/util/groupKeys.d.ts +76 -0
- package/esm/util/groupKeys.js +156 -0
- package/esm/util/highlights.d.ts +10 -6
- package/esm/util/highlights.js +12 -25
- package/esm/util/hooks.d.ts +31 -2
- package/esm/util/hooks.js +72 -3
- package/esm/util/index.d.ts +11 -11
- package/esm/util/index.js +11 -10
- package/esm/util/indexCandidates.d.ts +1 -31
- package/esm/util/indexCandidates.js +5 -63
- package/esm/util/installFetch.d.ts +77 -37
- package/esm/util/installFetch.js +65 -38
- package/esm/util/installInitAutorun.d.ts +14 -13
- package/esm/util/installInitAutorun.js +17 -17
- package/esm/util/installPrerequisiteFetch.d.ts +115 -0
- package/esm/util/installPrerequisiteFetch.js +111 -0
- package/esm/util/intervals.js +9 -4
- package/esm/util/io/index.js +22 -15
- package/esm/util/isDataCurrent.d.ts +7 -5
- package/esm/util/isDataCurrent.js +9 -6
- package/esm/util/isTextEntryFocused.d.ts +7 -0
- package/esm/util/isTextEntryFocused.js +16 -0
- 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 +32 -57
- package/esm/util/jexlFilters.js +31 -29
- package/esm/util/jexlStrings.d.ts +3 -4
- package/esm/util/jexlStrings.js +2 -3
- package/esm/util/layouts/GranularRectLayout.d.ts +8 -1
- package/esm/util/layouts/GranularRectLayout.js +25 -8
- package/esm/util/lazyAfterAttach.d.ts +13 -0
- package/esm/util/lazyAfterAttach.js +31 -0
- package/esm/util/lazyWithPreload.d.ts +19 -0
- package/esm/util/lazyWithPreload.js +27 -0
- package/esm/util/legendCandidates.d.ts +72 -0
- package/esm/util/legendCandidates.js +138 -0
- package/esm/util/locString.js +5 -2
- package/esm/util/localStorage.js +4 -4
- package/esm/util/markEncoding.d.ts +150 -0
- package/esm/util/markEncoding.js +885 -0
- package/esm/util/markEncodingTypes.d.ts +595 -0
- package/esm/util/markEncodingTypes.js +8 -0
- package/esm/util/mst-reflection.d.ts +2 -20
- package/esm/util/mst-reflection.js +3 -53
- package/esm/util/mstUtils.d.ts +31 -23
- package/esm/util/mstUtils.js +39 -24
- 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.d.ts +5 -0
- package/esm/util/openFeatureWidget.js +2 -2
- package/esm/util/openViews.d.ts +17 -0
- package/esm/util/openViews.js +22 -0
- package/esm/util/parentWalk.d.ts +1 -1
- package/esm/util/parentWalk.js +1 -1
- package/esm/util/parseLineByLine.d.ts +4 -5
- package/esm/util/parseLineByLine.js +8 -14
- package/esm/util/pluginStore.d.ts +6 -8
- package/esm/util/pluginStore.js +17 -16
- package/esm/util/preloadComponent.d.ts +5 -0
- package/esm/util/preloadComponent.js +11 -0
- package/esm/util/progress.d.ts +22 -22
- package/esm/util/progress.js +27 -26
- package/esm/util/quantileExtent.d.ts +49 -0
- package/esm/util/quantileExtent.js +162 -0
- package/esm/util/range.d.ts +13 -9
- package/esm/util/range.js +17 -8
- package/esm/util/renameRegions.d.ts +26 -6
- package/esm/util/renameRegions.js +68 -54
- package/esm/util/renderToStaticMarkup.js +24 -14
- package/esm/util/rxjs.d.ts +23 -8
- package/esm/util/rxjs.js +61 -15
- package/esm/util/samplesTsv.d.ts +49 -0
- package/esm/util/samplesTsv.js +86 -0
- package/esm/util/scheduleDetachedDestroy.d.ts +18 -0
- package/esm/util/scheduleDetachedDestroy.js +24 -0
- package/esm/util/scrollLatch.d.ts +1 -0
- package/esm/util/scrollLatch.js +8 -0
- package/esm/util/selectEncodedFeature.d.ts +16 -0
- package/esm/util/selectEncodedFeature.js +34 -0
- package/esm/util/sessionSharing.d.ts +7 -5
- package/esm/util/sessionSharing.js +23 -23
- package/esm/util/shapeNameList.d.ts +2 -0
- package/esm/util/shapeNameList.js +6 -0
- package/esm/util/shapeNames.d.ts +7 -0
- package/esm/util/shapeNames.js +11 -0
- package/esm/util/simpleFeature.d.ts +0 -1
- package/esm/util/springAnimate.js +1 -1
- package/esm/util/starFusion.d.ts +26 -0
- package/esm/util/starFusion.js +37 -0
- package/esm/util/stepTables.d.ts +96 -0
- package/esm/util/stepTables.js +277 -0
- package/esm/util/svAlt.d.ts +145 -0
- package/esm/util/svAlt.js +364 -0
- package/esm/util/svgColorProps.d.ts +11 -0
- package/esm/util/svgColorProps.js +28 -1
- package/esm/util/systemColorScheme.d.ts +12 -0
- package/esm/util/systemColorScheme.js +27 -0
- package/esm/util/tabix.d.ts +19 -10
- package/esm/util/tabix.js +19 -14
- package/esm/util/thresholdScale.d.ts +91 -0
- package/esm/util/thresholdScale.js +166 -0
- package/esm/util/timeGate.d.ts +4 -5
- package/esm/util/timeGate.js +4 -5
- package/esm/util/trackConfigDelta.d.ts +26 -26
- package/esm/util/trackConfigDelta.js +63 -47
- package/esm/util/tracks.d.ts +120 -66
- package/esm/util/tracks.js +501 -151
- package/esm/util/translateTranscript.d.ts +44 -0
- package/esm/util/translateTranscript.js +102 -0
- package/esm/util/types/data.d.ts +0 -2
- package/esm/util/types/index.d.ts +121 -22
- package/esm/util/types/index.js +9 -0
- package/esm/util/types/mst.d.ts +3 -0
- package/esm/util/types/mst.js +4 -0
- package/esm/util/types/renameIds.d.ts +1 -0
- package/esm/util/types/renameIds.js +29 -0
- package/esm/util/types/services.d.ts +1 -1
- package/esm/util/unknownSnapshotKeys.d.ts +53 -0
- package/esm/util/unknownSnapshotKeys.js +76 -0
- package/esm/util/useFeatureSequence.js +5 -5
- package/esm/util/useFetch.d.ts +3 -4
- package/esm/util/useFetch.js +19 -10
- package/esm/util/useFetchPlugins.d.ts +6 -2
- package/esm/util/useFetchPlugins.js +7 -3
- package/esm/util/usePanZoom.js +10 -3
- package/esm/util/usePanelVirtualScroll.d.ts +7 -35
- package/esm/util/usePanelVirtualScroll.js +9 -36
- package/esm/util/useRafCommit.js +1 -0
- 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 -74
- package/esm/util/viewHighlights.d.ts +3 -0
- package/esm/util/viewHighlights.js +5 -0
- package/esm/util/viewStatus.d.ts +47 -15
- package/esm/util/viewStatus.js +34 -0
- package/esm/util/wheelZoom.d.ts +7 -1
- package/esm/util/wheelZoom.js +85 -19
- package/esm/util/whenViewSettled.d.ts +55 -8
- package/esm/util/whenViewSettled.js +56 -7
- package/esm/util/withFeatureDetails.js +4 -0
- package/esm/util/withLaunchInput.d.ts +174 -0
- package/esm/util/withLaunchInput.js +274 -0
- package/package.json +75 -24
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Position.d.ts +0 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Position.js +0 -8
- package/esm/BaseFeatureWidget/BaseFeatureDetail/types.d.ts +0 -8
- 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/index.d.ts +0 -1
- package/esm/ReExports/index.js +0 -1
- package/esm/ReExports/publicUtil.d.ts +0 -1
- package/esm/ReExports/publicUtil.js +0 -28
- package/esm/configuration/promotableDefaults.d.ts +0 -199
- package/esm/configuration/promotableDefaults.js +0 -326
- package/esm/configuration/promotablePin.d.ts +0 -55
- package/esm/configuration/promotablePin.js +0 -1
- package/esm/configuration/promotableResolve.d.ts +0 -108
- package/esm/configuration/promotableResolve.js +0 -117
- package/esm/configuration/promotableSlots.d.ts +0 -12
- package/esm/configuration/promotableSlots.js +0 -45
- package/esm/configuration/slotShape.d.ts +0 -12
- package/esm/configuration/slotShape.js +0 -84
- package/esm/pluggableElementTypes/models/HighlightsMixin.d.ts +0 -51
- package/esm/pluggableElementTypes/models/HighlightsMixin.js +0 -78
- package/esm/ui/PinAdornment.d.ts +0 -5
- package/esm/ui/PinAdornment.js +0 -79
- package/esm/ui/SvgGradientLegend.d.ts +0 -26
- package/esm/ui/SvgGradientLegend.js +0 -26
- package/esm/ui/highlightChipReveal.d.ts +0 -32
- package/esm/ui/highlightChipReveal.js +0 -39
- package/esm/ui/promotableMenuItems.d.ts +0 -19
- package/esm/ui/promotableMenuItems.js +0 -89
- package/esm/ui/promotablePinCoverage.d.ts +0 -44
- package/esm/ui/promotablePinCoverage.js +0 -87
- package/esm/util/applyInitSettings.d.ts +0 -79
- package/esm/util/applyInitSettings.js +0 -91
- package/esm/util/openDisplays.d.ts +0 -23
- package/esm/util/openDisplays.js +0 -79
- package/esm/util/stopToken.d.ts +0 -211
- package/esm/util/stopToken.js +0 -438
- /package/esm/{BaseFeatureWidget/BaseFeatureDetail/types.js → data_adapters/BaseAdapter/zoomRange.js} +0 -0
|
@@ -0,0 +1,885 @@
|
|
|
1
|
+
import { makeScoreNormalizer, rampMidNorm, scaleTypeCode, } from '@jbrowse/render-core/scoreScale';
|
|
2
|
+
import { rampMidT } from '@jbrowse/render-core/shaders/colorRampLut';
|
|
3
|
+
import { RAMP_NO_VALUE_BITS } from '@jbrowse/render-core/shaders/markColorConsts';
|
|
4
|
+
import { GLYPH_DISC } from '@jbrowse/render-core/shaders/pointMarkConsts';
|
|
5
|
+
import { categoricalScale } from '../ui/colors.js';
|
|
6
|
+
import { categoricalField } from './categoricalField.js';
|
|
7
|
+
import { MISCONFIGURED_COLOR, NO_CATEGORY_COLOR } from './color/index.js';
|
|
8
|
+
import { cssColorToABGR, packAbgr } from './colorBits.js';
|
|
9
|
+
import { rampDomain, rampLutOf } from './colorRamp.js';
|
|
10
|
+
import { asTable, numberReaderOf, readerOf } from './featureTable.js';
|
|
11
|
+
import { fieldReader, isPlainFieldRef } from './fieldReader.js';
|
|
12
|
+
import Flatbush from './flatbush/index.js';
|
|
13
|
+
import { valueText } from './groupKeys.js';
|
|
14
|
+
import { isJexl, stringToJexlExpression } from './jexlStrings.js';
|
|
15
|
+
import { numericValue } from './numericValue.js';
|
|
16
|
+
import { scaleExtent } from './quantileExtent.js';
|
|
17
|
+
import { SHAPE_CODES, SHAPE_NAMES } from './shapeNames.js';
|
|
18
|
+
import { buildJexlContext } from './simpleFeature.js';
|
|
19
|
+
import { isMissing, thresholdCuts, thresholdIndex, thresholdPalette, } from './thresholdScale.js';
|
|
20
|
+
export { COLOR_SCHEMES } from './colorSchemes.js';
|
|
21
|
+
export { NO_VALUE_LABEL } from './categoricalField.js';
|
|
22
|
+
export const DEFAULT_MARK_COLOR = '#0068d1';
|
|
23
|
+
export const DEFAULT_SIZE_RANGE_PX = [1, 6];
|
|
24
|
+
/**
|
|
25
|
+
* #api
|
|
26
|
+
* The misconfiguration grey packed as the encoder paints it: a `jexl:` colour
|
|
27
|
+
* that answered no string, a ramp value that is no number, text a threshold
|
|
28
|
+
* cannot read.
|
|
29
|
+
*/
|
|
30
|
+
export const MISCONFIGURED_ABGR = cssColorToABGR(MISCONFIGURED_COLOR);
|
|
31
|
+
/**
|
|
32
|
+
* #api
|
|
33
|
+
* The no-value grey packed as the encoder paints it: a feature with nothing in
|
|
34
|
+
* the field a threshold reads.
|
|
35
|
+
*/
|
|
36
|
+
export const NO_VALUE_ABGR = cssColorToABGR(NO_CATEGORY_COLOR);
|
|
37
|
+
const FALLBACK_COLOR = MISCONFIGURED_ABGR;
|
|
38
|
+
function jexlExpression(ref, jexl) {
|
|
39
|
+
if (!jexl) {
|
|
40
|
+
throw new Error(`a jexl: channel needs a jexl instance (${ref})`);
|
|
41
|
+
}
|
|
42
|
+
return stringToJexlExpression(ref, jexl);
|
|
43
|
+
}
|
|
44
|
+
function channelReader(table, ref, jexl) {
|
|
45
|
+
if (typeof ref === 'function') {
|
|
46
|
+
return i => ref(table.row(i));
|
|
47
|
+
}
|
|
48
|
+
if (isPlainFieldRef(ref)) {
|
|
49
|
+
return readerOf(table.column(ref));
|
|
50
|
+
}
|
|
51
|
+
const read = fieldReader(ref, jexl);
|
|
52
|
+
return i => read(table.row(i));
|
|
53
|
+
}
|
|
54
|
+
// A text channel's reader, printing a float32 lane's value at the digits the
|
|
55
|
+
// lane holds rather than the double it widens to: 0.3865, not 0.3865000009.
|
|
56
|
+
function textChannelReader(table, ref, jexl) {
|
|
57
|
+
const read = channelReader(table, ref, jexl);
|
|
58
|
+
const column = typeof ref !== 'function' && isPlainFieldRef(ref)
|
|
59
|
+
? table.column(ref)
|
|
60
|
+
: undefined;
|
|
61
|
+
return column?.kind === 'number' && column.values instanceof Float32Array
|
|
62
|
+
? i => {
|
|
63
|
+
const v = read(i);
|
|
64
|
+
return typeof v === 'number' && !Number.isInteger(v)
|
|
65
|
+
? String(Number(v.toPrecision(7)))
|
|
66
|
+
: valueText(v);
|
|
67
|
+
}
|
|
68
|
+
: i => valueText(read(i));
|
|
69
|
+
}
|
|
70
|
+
function numberChannelReader(table, ref, jexl) {
|
|
71
|
+
if (typeof ref !== 'function' && isPlainFieldRef(ref)) {
|
|
72
|
+
return numberReaderOf(table.column(ref));
|
|
73
|
+
}
|
|
74
|
+
const read = channelReader(table, ref, jexl);
|
|
75
|
+
return i => numericValue(read(i));
|
|
76
|
+
}
|
|
77
|
+
function isShapeName(shape) {
|
|
78
|
+
return shape in SHAPE_CODES;
|
|
79
|
+
}
|
|
80
|
+
// A shape named outright is its code, which fills the lane without reading a
|
|
81
|
+
// row.
|
|
82
|
+
function shapeReader(table, shape, jexl) {
|
|
83
|
+
if (shape === undefined) {
|
|
84
|
+
return GLYPH_DISC;
|
|
85
|
+
}
|
|
86
|
+
if (typeof shape === 'function') {
|
|
87
|
+
return i => shape(table.row(i));
|
|
88
|
+
}
|
|
89
|
+
if (isShapeName(shape)) {
|
|
90
|
+
return SHAPE_CODES[shape];
|
|
91
|
+
}
|
|
92
|
+
const expr = jexlExpression(shape, jexl);
|
|
93
|
+
return i => {
|
|
94
|
+
const v = expr.eval(buildJexlContext({ feature: table.row(i) }));
|
|
95
|
+
return typeof v === 'string' && isShapeName(v) ? SHAPE_CODES[v] : GLYPH_DISC;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function lutColorAt(lut, t) {
|
|
99
|
+
const entries = lut.length / 4;
|
|
100
|
+
const i = Math.min(entries - 1, Math.max(0, Math.round(t * (entries - 1))));
|
|
101
|
+
const o = i * 4;
|
|
102
|
+
return packAbgr(lut[o], lut[o + 1], lut[o + 2], lut[o + 3]);
|
|
103
|
+
}
|
|
104
|
+
function numberSource(table, ref, jexl) {
|
|
105
|
+
return {
|
|
106
|
+
lane: laneOf(table, ref),
|
|
107
|
+
read: numberChannelReader(table, ref, jexl),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function laneOf(table, ref) {
|
|
111
|
+
if (typeof ref === 'function' || !isPlainFieldRef(ref)) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
const column = table.column(ref);
|
|
115
|
+
return column.kind === 'number' ? column : undefined;
|
|
116
|
+
}
|
|
117
|
+
// A stacked row reads as `Number` reads it, where a quantitative channel reads
|
|
118
|
+
// text by `numericValue`'s rules.
|
|
119
|
+
function rowSource(table, ref, jexl) {
|
|
120
|
+
const read = channelReader(table, ref, jexl);
|
|
121
|
+
return { lane: laneOf(table, ref), read: i => Number(read(i)) };
|
|
122
|
+
}
|
|
123
|
+
function isUnsigned(values) {
|
|
124
|
+
return (values instanceof Uint32Array ||
|
|
125
|
+
values instanceof Uint16Array ||
|
|
126
|
+
values instanceof Uint8Array);
|
|
127
|
+
}
|
|
128
|
+
// A lane of whole numbers holds no NaN or infinity, so it places every row.
|
|
129
|
+
function isWhole(source) {
|
|
130
|
+
const values = source.lane?.values;
|
|
131
|
+
return (values !== undefined &&
|
|
132
|
+
!(values instanceof Float32Array || values instanceof Float64Array));
|
|
133
|
+
}
|
|
134
|
+
// The one index a loop reads a lane through for instance `k`: the kept row,
|
|
135
|
+
// the lane's own index, or both composed. A loop tests for it once and runs
|
|
136
|
+
// with no branch per element, which V8 does not hoist for it.
|
|
137
|
+
function laneIndex(kept, at) {
|
|
138
|
+
if (!kept || !at) {
|
|
139
|
+
return kept ?? at;
|
|
140
|
+
}
|
|
141
|
+
const index = new Uint32Array(kept.length);
|
|
142
|
+
for (let k = 0; k < kept.length; k++) {
|
|
143
|
+
index[k] = at[kept[k]];
|
|
144
|
+
}
|
|
145
|
+
return index;
|
|
146
|
+
}
|
|
147
|
+
// `out[k]`, the value instance `k` reads; into an unsigned lane a negative
|
|
148
|
+
// stops at 0 rather than wrapping.
|
|
149
|
+
function fillNumbers(out, { lane, read }, kept, count) {
|
|
150
|
+
const unsigned = out instanceof Uint32Array;
|
|
151
|
+
if (!lane) {
|
|
152
|
+
for (let k = 0; k < count; k++) {
|
|
153
|
+
const v = read(kept ? kept[k] : k);
|
|
154
|
+
out[k] = unsigned && v < 0 ? 0 : v;
|
|
155
|
+
}
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const { values } = lane;
|
|
159
|
+
const index = laneIndex(kept, lane.at);
|
|
160
|
+
if (!index && (!unsigned || isUnsigned(values))) {
|
|
161
|
+
out.set(values.subarray(0, count));
|
|
162
|
+
}
|
|
163
|
+
else if (!index) {
|
|
164
|
+
for (let k = 0; k < count; k++) {
|
|
165
|
+
const v = values[k];
|
|
166
|
+
out[k] = v < 0 ? 0 : v;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else if (unsigned) {
|
|
170
|
+
for (let k = 0; k < count; k++) {
|
|
171
|
+
const v = values[index[k]];
|
|
172
|
+
out[k] = v < 0 ? 0 : v;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
for (let k = 0; k < count; k++) {
|
|
177
|
+
out[k] = values[index[k]];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// The rows that place, and their `x`, `x2` and `y` written: every row where
|
|
182
|
+
// all three are lanes of whole numbers, and otherwise each whose three read
|
|
183
|
+
// finite. A position before the sequence's first base, a flank run off the
|
|
184
|
+
// start or an `END=0`, stops at 0 rather than wrapping the unsigned lane.
|
|
185
|
+
function admit(sources, out, n, report) {
|
|
186
|
+
const { x, x2, y } = sources;
|
|
187
|
+
if (isWhole(x) && isWhole(x2) && (!y || isWhole(y))) {
|
|
188
|
+
fillNumbers(out.x, x, undefined, n);
|
|
189
|
+
fillNumbers(out.x2, x2, undefined, n);
|
|
190
|
+
if (y && out.y) {
|
|
191
|
+
fillNumbers(out.y, y, undefined, n);
|
|
192
|
+
}
|
|
193
|
+
return { kept: undefined, count: n, skippedPosition: 0 };
|
|
194
|
+
}
|
|
195
|
+
const kept = new Uint32Array(n);
|
|
196
|
+
const { x: xs, x2: x2s, y: ys } = out;
|
|
197
|
+
const lanes = unindexedLanes(x, x2, y);
|
|
198
|
+
if (lanes) {
|
|
199
|
+
const { count, skippedPosition } = admitLanes(lanes, out, kept, n);
|
|
200
|
+
return {
|
|
201
|
+
kept: count === n ? undefined : kept.subarray(0, count),
|
|
202
|
+
count,
|
|
203
|
+
skippedPosition,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
const readX = x.read;
|
|
207
|
+
const readX2 = x2.read;
|
|
208
|
+
const readY = y?.read;
|
|
209
|
+
let count = 0;
|
|
210
|
+
let skippedPosition = 0;
|
|
211
|
+
for (let i = 0; i < n; i++) {
|
|
212
|
+
report?.(i);
|
|
213
|
+
const xv = readX(i);
|
|
214
|
+
const x2v = readX2(i);
|
|
215
|
+
const yv = readY ? readY(i) : 0;
|
|
216
|
+
if (!Number.isFinite(xv) || !Number.isFinite(x2v)) {
|
|
217
|
+
skippedPosition++;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (!Number.isFinite(yv)) {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
xs[count] = xv < 0 ? 0 : xv;
|
|
224
|
+
x2s[count] = x2v < 0 ? 0 : x2v;
|
|
225
|
+
if (ys) {
|
|
226
|
+
ys[count] = yv;
|
|
227
|
+
}
|
|
228
|
+
kept[count++] = i;
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
kept: count === n ? undefined : kept.subarray(0, count),
|
|
232
|
+
count,
|
|
233
|
+
skippedPosition,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function unindexedLanes(x, x2, y) {
|
|
237
|
+
const lanes = [x.lane, x2.lane, y?.lane];
|
|
238
|
+
return lanes[0] &&
|
|
239
|
+
!lanes[0].at &&
|
|
240
|
+
lanes[1] &&
|
|
241
|
+
!lanes[1].at &&
|
|
242
|
+
(!y || (lanes[2] && !lanes[2].at))
|
|
243
|
+
? { x: lanes[0].values, x2: lanes[1].values, y: lanes[2]?.values }
|
|
244
|
+
: undefined;
|
|
245
|
+
}
|
|
246
|
+
// `admit`'s walk read straight off lanes with no index, so no row costs a
|
|
247
|
+
// call: with a `y` lane in one loop and without one in another, since V8
|
|
248
|
+
// would test for it on every row.
|
|
249
|
+
function admitLanes(lanes, out, kept, n) {
|
|
250
|
+
const { x: xl, x2: x2l, y: yl } = lanes;
|
|
251
|
+
const { x: xs, x2: x2s } = out;
|
|
252
|
+
let count = 0;
|
|
253
|
+
let skippedPosition = 0;
|
|
254
|
+
if (yl) {
|
|
255
|
+
const ys = out.y;
|
|
256
|
+
for (let i = 0; i < n; i++) {
|
|
257
|
+
const xv = xl[i];
|
|
258
|
+
const x2v = x2l[i];
|
|
259
|
+
const yv = yl[i];
|
|
260
|
+
if (!Number.isFinite(xv) || !Number.isFinite(x2v)) {
|
|
261
|
+
skippedPosition++;
|
|
262
|
+
}
|
|
263
|
+
else if (Number.isFinite(yv)) {
|
|
264
|
+
xs[count] = xv < 0 ? 0 : xv;
|
|
265
|
+
x2s[count] = x2v < 0 ? 0 : x2v;
|
|
266
|
+
ys[count] = yv;
|
|
267
|
+
kept[count++] = i;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
for (let i = 0; i < n; i++) {
|
|
273
|
+
const xv = xl[i];
|
|
274
|
+
const x2v = x2l[i];
|
|
275
|
+
if (!Number.isFinite(xv) || !Number.isFinite(x2v)) {
|
|
276
|
+
skippedPosition++;
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
xs[count] = xv < 0 ? 0 : xv;
|
|
280
|
+
x2s[count] = x2v < 0 ? 0 : x2v;
|
|
281
|
+
kept[count++] = i;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return { count, skippedPosition };
|
|
286
|
+
}
|
|
287
|
+
// The categorical arm `color` and `shape` share: `out[k]` the lane value of
|
|
288
|
+
// the entry instance `k`'s key takes, `''` the key of none, and the keys met
|
|
289
|
+
// with their entries in the field's order. A key's entry is its own whatever
|
|
290
|
+
// else was met, so two regions agree on every key they share. Over a category
|
|
291
|
+
// column each label is keyed once, and the lane written by its code.
|
|
292
|
+
function paintCategories(table, ref, jexl, categories, within, out, entryOf, laneValue) {
|
|
293
|
+
const { kept, count, report } = within;
|
|
294
|
+
const resolved = new Map();
|
|
295
|
+
const resolve = (key) => {
|
|
296
|
+
let r = resolved.get(key);
|
|
297
|
+
if (r === undefined) {
|
|
298
|
+
const entry = entryOf(key);
|
|
299
|
+
r = { entry, value: laneValue(entry) };
|
|
300
|
+
resolved.set(key, r);
|
|
301
|
+
}
|
|
302
|
+
return r;
|
|
303
|
+
};
|
|
304
|
+
const column = typeof ref !== 'function' && isPlainFieldRef(ref)
|
|
305
|
+
? table.column(ref)
|
|
306
|
+
: undefined;
|
|
307
|
+
let met;
|
|
308
|
+
if (column?.kind === 'category') {
|
|
309
|
+
const { codes, labels } = column;
|
|
310
|
+
const keyOfCode = labels.map(label => categories.key(label));
|
|
311
|
+
const valueOfCode = Uint32Array.from(keyOfCode, key => resolve(key).value);
|
|
312
|
+
const metCode = new Uint8Array(labels.length);
|
|
313
|
+
const index = laneIndex(kept, column.at);
|
|
314
|
+
if (index) {
|
|
315
|
+
for (let k = 0; k < count; k++) {
|
|
316
|
+
const code = codes[index[k]];
|
|
317
|
+
metCode[code] = 1;
|
|
318
|
+
out[k] = valueOfCode[code];
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
for (let k = 0; k < count; k++) {
|
|
323
|
+
const code = codes[k];
|
|
324
|
+
metCode[code] = 1;
|
|
325
|
+
out[k] = valueOfCode[code];
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
met = new Set(keyOfCode.filter((_, code) => metCode[code]));
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
const read = channelReader(table, ref, jexl);
|
|
332
|
+
for (let k = 0; k < count; k++) {
|
|
333
|
+
report?.(k);
|
|
334
|
+
out[k] = resolve(categories.key(read(kept ? kept[k] : k))).value;
|
|
335
|
+
}
|
|
336
|
+
met = resolved.keys();
|
|
337
|
+
}
|
|
338
|
+
return [...met]
|
|
339
|
+
.sort(categories.compare)
|
|
340
|
+
.map(value => ({ value, entry: resolved.get(value).entry }));
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* #api
|
|
344
|
+
* The hit index over `count` instances: each a box from `x` to `x2` at its
|
|
345
|
+
* `y`, or at 0 for a mark with no value.
|
|
346
|
+
*/
|
|
347
|
+
export function hitIndexOf(x, x2, y, count = x.length) {
|
|
348
|
+
const fb = new Flatbush(count, undefined, Float64Array);
|
|
349
|
+
for (let i = 0; i < count; i++) {
|
|
350
|
+
const v = y ? y[i] : 0;
|
|
351
|
+
const a = x[i];
|
|
352
|
+
const b = x2[i];
|
|
353
|
+
fb.add(Math.min(a, b), v, Math.max(a, b), v);
|
|
354
|
+
}
|
|
355
|
+
fb.finish();
|
|
356
|
+
return fb;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* #api
|
|
360
|
+
* {@link HitIndexed} over what the worker shipped.
|
|
361
|
+
*/
|
|
362
|
+
export function withHitIndex(channels) {
|
|
363
|
+
const { flatbushData } = channels;
|
|
364
|
+
return {
|
|
365
|
+
...channels,
|
|
366
|
+
flatbush: flatbushData ? Flatbush.from(flatbushData) : undefined,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* #api
|
|
371
|
+
* Evaluate one encoding over a feature list into dense channel arrays for
|
|
372
|
+
* the lanes named, the scale table each scaled channel came from, the `y`
|
|
373
|
+
* extremes and — when `index` is among the lanes — a hit index.
|
|
374
|
+
*
|
|
375
|
+
* A feature whose `x`, `x2` or (declared and asked-for) `y` is not finite is
|
|
376
|
+
* skipped and counted in `skipped`, so every array stays index-aligned with
|
|
377
|
+
* the Flatbush. Pure: the RPC around it owns the adapter, the filters and the
|
|
378
|
+
* transferables.
|
|
379
|
+
*
|
|
380
|
+
* Columnar: one pass admits the rows over `x`, `x2` and `y` alone, and none
|
|
381
|
+
* runs where all three are lanes of whole numbers; every other lane is then
|
|
382
|
+
* filled in its own loop over the admitted rows, a lane straight off a typed
|
|
383
|
+
* column and a categorical over a `category` column per label.
|
|
384
|
+
*/
|
|
385
|
+
export function encodeFeatures(input, encoding, lanes, ctx = {}) {
|
|
386
|
+
const { jexl, report } = ctx;
|
|
387
|
+
const table = asTable(input);
|
|
388
|
+
const n = table.length;
|
|
389
|
+
const has = (lane) => lanes.includes(lane);
|
|
390
|
+
const { x2: x2Encoding, y: yEncoding, row: rowEncoding, text: textEncoding, size: sizeEncoding, shape: shapeEncoding, } = encoding;
|
|
391
|
+
const x2Locus = typeof x2Encoding === 'object' ? x2Encoding : undefined;
|
|
392
|
+
const ySource = has('y') && yEncoding !== undefined
|
|
393
|
+
? numberSource(table, yEncoding, jexl)
|
|
394
|
+
: undefined;
|
|
395
|
+
const xs = new Uint32Array(n);
|
|
396
|
+
const x2s = new Uint32Array(n);
|
|
397
|
+
const ys = has('y') ? new Float32Array(n) : undefined;
|
|
398
|
+
const { kept, count, skippedPosition } = admit({
|
|
399
|
+
x: numberSource(table, encoding.x ?? 'start', jexl),
|
|
400
|
+
x2: numberSource(table, typeof x2Encoding === 'object' ? x2Encoding.pos : (x2Encoding ?? 'end'), jexl),
|
|
401
|
+
y: ySource,
|
|
402
|
+
}, { x: xs, x2: x2s, y: ys }, n, report);
|
|
403
|
+
const rowAt = (k) => (kept ? kept[k] : k);
|
|
404
|
+
const y = ys?.subarray(0, count);
|
|
405
|
+
let yMin = Infinity;
|
|
406
|
+
let yMax = -Infinity;
|
|
407
|
+
if (ySource && y) {
|
|
408
|
+
for (let k = 0; k < count; k++) {
|
|
409
|
+
const v = y[k];
|
|
410
|
+
if (v < yMin) {
|
|
411
|
+
yMin = v;
|
|
412
|
+
}
|
|
413
|
+
if (v > yMax) {
|
|
414
|
+
yMax = v;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
let x2Ref;
|
|
419
|
+
const x2RefNames = [];
|
|
420
|
+
if (has('x2Ref')) {
|
|
421
|
+
x2Ref = new Uint32Array(count);
|
|
422
|
+
const readChrom = x2Locus
|
|
423
|
+
? channelReader(table, x2Locus.chrom, jexl)
|
|
424
|
+
: undefined;
|
|
425
|
+
const readRefName = readerOf(table.column('refName'));
|
|
426
|
+
const refIndex = new Map();
|
|
427
|
+
for (let k = 0; k < count; k++) {
|
|
428
|
+
report?.(k);
|
|
429
|
+
const r = rowAt(k);
|
|
430
|
+
const there = readChrom
|
|
431
|
+
? valueText(readChrom(r))
|
|
432
|
+
: readRefName(r);
|
|
433
|
+
let ref = refIndex.get(there);
|
|
434
|
+
if (ref === undefined) {
|
|
435
|
+
ref = x2RefNames.length;
|
|
436
|
+
refIndex.set(there, ref);
|
|
437
|
+
x2RefNames.push(there);
|
|
438
|
+
}
|
|
439
|
+
x2Ref[k] = ref;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
const sizeRef = has('size') &&
|
|
443
|
+
sizeEncoding !== undefined &&
|
|
444
|
+
typeof sizeEncoding !== 'number'
|
|
445
|
+
? typeof sizeEncoding === 'string'
|
|
446
|
+
? { field: sizeEncoding }
|
|
447
|
+
: sizeEncoding
|
|
448
|
+
: undefined;
|
|
449
|
+
const size = sizeRef ? new Float32Array(count) : undefined;
|
|
450
|
+
if (sizeRef && size) {
|
|
451
|
+
fillNumbers(size, numberSource(table, sizeRef.field, jexl), kept, count);
|
|
452
|
+
}
|
|
453
|
+
const row = has('row') ? new Uint32Array(count) : undefined;
|
|
454
|
+
if (row && typeof rowEncoding === 'object') {
|
|
455
|
+
if (rowEncoding instanceof Uint32Array && !kept) {
|
|
456
|
+
row.set(rowEncoding.subarray(0, count));
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
for (let k = 0; k < count; k++) {
|
|
460
|
+
const rv = rowEncoding[rowAt(k)];
|
|
461
|
+
row[k] = rv > 0 ? rv : 0;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
else if (row &&
|
|
466
|
+
rowEncoding !== undefined &&
|
|
467
|
+
typeof rowEncoding !== 'object') {
|
|
468
|
+
fillNumbers(row, rowSource(table, rowEncoding, jexl), kept, count);
|
|
469
|
+
}
|
|
470
|
+
const text = has('text') ? new Array(count) : undefined;
|
|
471
|
+
if (text) {
|
|
472
|
+
if (textEncoding === undefined) {
|
|
473
|
+
text.fill('');
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
const read = textChannelReader(table, textEncoding, jexl);
|
|
477
|
+
for (let k = 0; k < count; k++) {
|
|
478
|
+
report?.(k);
|
|
479
|
+
text[k] = read(rowAt(k));
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
const glyph = has('glyph') ? new Uint8Array(count) : undefined;
|
|
484
|
+
let shapeScale;
|
|
485
|
+
if (glyph && typeof shapeEncoding === 'object') {
|
|
486
|
+
const shapeField = categoricalField(shapeEncoding.field, {
|
|
487
|
+
domain: shapeEncoding.domain?.map(String),
|
|
488
|
+
});
|
|
489
|
+
const range = shapeEncoding.range ?? SHAPE_NAMES;
|
|
490
|
+
const shapeOf = categoricalScale(shapeField.domain, range, {
|
|
491
|
+
fallback: range.length > shapeField.domain.length ? [] : SHAPE_NAMES,
|
|
492
|
+
});
|
|
493
|
+
const entries = paintCategories(table, shapeEncoding.field, jexl, shapeField, { kept, count, report }, glyph, (key) => (key === '' ? 'circle' : shapeOf(key)), name => SHAPE_CODES[name]);
|
|
494
|
+
shapeScale = {
|
|
495
|
+
kind: 'shape',
|
|
496
|
+
field: shapeEncoding.field,
|
|
497
|
+
domain: [...shapeField.domain],
|
|
498
|
+
...(shapeEncoding.range ? { range: [...shapeEncoding.range] } : {}),
|
|
499
|
+
entries: entries.map(e => ({ value: e.value, shape: e.entry })),
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
else if (glyph && typeof shapeEncoding !== 'object') {
|
|
503
|
+
const shape = shapeReader(table, shapeEncoding, jexl);
|
|
504
|
+
if (typeof shape === 'number') {
|
|
505
|
+
glyph.fill(shape);
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
for (let k = 0; k < count; k++) {
|
|
509
|
+
report?.(k);
|
|
510
|
+
glyph[k] = shape(rowAt(k));
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
const colorEncoding = encoding.color ?? DEFAULT_MARK_COLOR;
|
|
515
|
+
const declaredScale = typeof colorEncoding === 'object' ? colorEncoding : undefined;
|
|
516
|
+
const rampEncoding = declaredScale &&
|
|
517
|
+
(declaredScale.scale === 'linear' || declaredScale.scale === 'log')
|
|
518
|
+
? declaredScale
|
|
519
|
+
: undefined;
|
|
520
|
+
const thresholdEncoding = declaredScale?.scale === 'threshold' ? declaredScale : undefined;
|
|
521
|
+
// Which side of the wire a quantitative colour resolves on is the caller's
|
|
522
|
+
// lane choice: a mark that reads the scale itself names `colorValue` and
|
|
523
|
+
// gets the raw values, so a ramp's domain unions over the regions and a
|
|
524
|
+
// threshold's cuts move as uniforms. Anything else names `color` and the
|
|
525
|
+
// encoder resolves per region. A colour over the field `y` plots is the `y`
|
|
526
|
+
// lane itself, aliased rather than copied.
|
|
527
|
+
const quantitative = rampEncoding ?? thresholdEncoding;
|
|
528
|
+
const colorReadsY = quantitative !== undefined &&
|
|
529
|
+
has('colorValue') &&
|
|
530
|
+
y !== undefined &&
|
|
531
|
+
typeof yEncoding === 'string' &&
|
|
532
|
+
quantitative.field === yEncoding;
|
|
533
|
+
const colorValue = quantitative && has('colorValue')
|
|
534
|
+
? colorReadsY
|
|
535
|
+
? y
|
|
536
|
+
: new Float32Array(count)
|
|
537
|
+
: undefined;
|
|
538
|
+
const colorKey = declaredScale?.scale === 'categorical' && has('colorKey')
|
|
539
|
+
? new Uint32Array(count)
|
|
540
|
+
: undefined;
|
|
541
|
+
const paintsColor = has('color') && !colorValue && !colorKey;
|
|
542
|
+
const unscaled = paintsColor && declaredScale?.scale !== 'categorical' && !quantitative
|
|
543
|
+
? unscaledColor(table, colorEncoding, jexl)
|
|
544
|
+
: undefined;
|
|
545
|
+
const color = paintsColor && typeof unscaled !== 'number'
|
|
546
|
+
? new Uint32Array(count)
|
|
547
|
+
: undefined;
|
|
548
|
+
const scaled = paintsColor || colorValue || colorKey ? declaredScale : undefined;
|
|
549
|
+
const categoryLane = colorKey ?? color;
|
|
550
|
+
let scale;
|
|
551
|
+
let missingMet = false;
|
|
552
|
+
let notNumberMet = false;
|
|
553
|
+
if (scaled?.scale === 'categorical' && categoryLane) {
|
|
554
|
+
const colorField = categoricalField(scaled.field, {
|
|
555
|
+
domain: scaled.domain?.map(String),
|
|
556
|
+
range: scaled.range,
|
|
557
|
+
});
|
|
558
|
+
let resolved = 0;
|
|
559
|
+
const entries = paintCategories(table, scaled.field, jexl, colorField, { kept, count, report }, categoryLane, key => ({
|
|
560
|
+
color: cssColorToABGR(colorField.color(key)),
|
|
561
|
+
order: resolved++,
|
|
562
|
+
}), entry => (colorKey ? entry.order : entry.color));
|
|
563
|
+
if (colorKey) {
|
|
564
|
+
const position = new Uint32Array(resolved);
|
|
565
|
+
for (const [i, e] of entries.entries()) {
|
|
566
|
+
position[e.entry.order] = i;
|
|
567
|
+
}
|
|
568
|
+
for (let k = 0; k < count; k++) {
|
|
569
|
+
colorKey[k] = position[colorKey[k]];
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
scale = {
|
|
573
|
+
kind: 'categorical',
|
|
574
|
+
field: scaled.field,
|
|
575
|
+
domain: [...colorField.domain],
|
|
576
|
+
...(scaled.range ? { range: [...scaled.range] } : {}),
|
|
577
|
+
...(keysAreNumeric(entries) ? { numericKeys: true } : {}),
|
|
578
|
+
entries: entries.map(e => ({ value: e.value, color: e.entry.color })),
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
else if (scaled && quantitative) {
|
|
582
|
+
// The raw values, where they are kept: a ramp's always, a threshold's
|
|
583
|
+
// where the caller resolves it; the encoder resolves a threshold into
|
|
584
|
+
// packed colours only for a caller naming `color` alone.
|
|
585
|
+
const values = colorValue ?? (rampEncoding ? new Float32Array(count) : undefined);
|
|
586
|
+
const read = channelReader(table, quantitative.field, jexl);
|
|
587
|
+
if (values && !colorReadsY) {
|
|
588
|
+
const bits = new Uint32Array(values.buffer, values.byteOffset, count);
|
|
589
|
+
for (let k = 0; k < count; k++) {
|
|
590
|
+
report?.(k);
|
|
591
|
+
const v = read(rowAt(k));
|
|
592
|
+
if (isMissing(v)) {
|
|
593
|
+
bits[k] = RAMP_NO_VALUE_BITS;
|
|
594
|
+
missingMet = true;
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
values[k] = numericValue(v);
|
|
598
|
+
notNumberMet ||= Number.isNaN(values[k]);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
if (thresholdEncoding) {
|
|
603
|
+
const cuts = thresholdCuts(thresholdEncoding.domain ?? []);
|
|
604
|
+
if (color) {
|
|
605
|
+
const binColors = Uint32Array.from(thresholdPalette(cuts.length + 1, thresholdEncoding.range), c => cssColorToABGR(c));
|
|
606
|
+
// in float32 on both sides, as the shader and the key compare, so a
|
|
607
|
+
// value off a float32 lane sits at a cut like 0.7 rather than under it
|
|
608
|
+
const cuts32 = cuts.map(cut => Math.fround(cut));
|
|
609
|
+
for (let k = 0; k < count; k++) {
|
|
610
|
+
report?.(k);
|
|
611
|
+
const v = read(rowAt(k));
|
|
612
|
+
const bin = thresholdIndex(Math.fround(numericValue(v)), cuts32);
|
|
613
|
+
if (bin >= 0) {
|
|
614
|
+
color[k] = binColors[bin];
|
|
615
|
+
}
|
|
616
|
+
else if (isMissing(v)) {
|
|
617
|
+
color[k] = NO_VALUE_ABGR;
|
|
618
|
+
missingMet = true;
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
color[k] = FALLBACK_COLOR;
|
|
622
|
+
notNumberMet = true;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
scale = {
|
|
627
|
+
kind: 'threshold',
|
|
628
|
+
field: thresholdEncoding.field,
|
|
629
|
+
domain: cuts,
|
|
630
|
+
...(thresholdEncoding.range
|
|
631
|
+
? { range: [...thresholdEncoding.range] }
|
|
632
|
+
: {}),
|
|
633
|
+
...(missingMet ? { missing: true } : {}),
|
|
634
|
+
...(notNumberMet ? { notNumber: true } : {}),
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
else if (rampEncoding && values) {
|
|
638
|
+
scale = rampScale(rampEncoding, values, count, color, {
|
|
639
|
+
missingMet,
|
|
640
|
+
notNumberMet,
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
else if (color && typeof unscaled === 'function') {
|
|
645
|
+
for (let k = 0; k < count; k++) {
|
|
646
|
+
report?.(k);
|
|
647
|
+
color[k] = unscaled(rowAt(k));
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
let sizeScale;
|
|
651
|
+
if (sizeRef && size) {
|
|
652
|
+
const scale = sizeRef.scale ?? 'linear';
|
|
653
|
+
const extent = scaleExtent(size, count, scale);
|
|
654
|
+
const { domainMin, domainMax } = sizeRef;
|
|
655
|
+
sizeScale = {
|
|
656
|
+
field: sizeRef.field,
|
|
657
|
+
scale,
|
|
658
|
+
domain: rampDomain(domainMin, domainMax, extent),
|
|
659
|
+
pinned: [domainMin !== undefined, domainMax !== undefined],
|
|
660
|
+
range: sizeRef.range ?? DEFAULT_SIZE_RANGE_PX,
|
|
661
|
+
extent,
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
const x = xs.subarray(0, count);
|
|
665
|
+
const x2 = x2s.subarray(0, count);
|
|
666
|
+
const flatbushData = has('index') && count > 0 ? hitIndexOf(x, x2, y, count).data : undefined;
|
|
667
|
+
const encoded = {
|
|
668
|
+
count,
|
|
669
|
+
skipped: n - count,
|
|
670
|
+
skippedPosition,
|
|
671
|
+
x,
|
|
672
|
+
x2,
|
|
673
|
+
yMin,
|
|
674
|
+
yMax,
|
|
675
|
+
};
|
|
676
|
+
if (kept) {
|
|
677
|
+
encoded.featureIndex = kept;
|
|
678
|
+
}
|
|
679
|
+
if (y) {
|
|
680
|
+
encoded.y = y;
|
|
681
|
+
}
|
|
682
|
+
if (row) {
|
|
683
|
+
encoded.row = row;
|
|
684
|
+
}
|
|
685
|
+
if (typeof unscaled === 'number') {
|
|
686
|
+
encoded.color = unscaled;
|
|
687
|
+
}
|
|
688
|
+
else if (color) {
|
|
689
|
+
encoded.color = color;
|
|
690
|
+
}
|
|
691
|
+
if (colorValue) {
|
|
692
|
+
// the y view itself where the colour reads y, so a reader can tell
|
|
693
|
+
encoded.colorValue = colorValue;
|
|
694
|
+
}
|
|
695
|
+
if (colorKey) {
|
|
696
|
+
encoded.colorKey = colorKey;
|
|
697
|
+
}
|
|
698
|
+
if (glyph) {
|
|
699
|
+
encoded.glyph = glyph;
|
|
700
|
+
}
|
|
701
|
+
if (text) {
|
|
702
|
+
encoded.text = text;
|
|
703
|
+
}
|
|
704
|
+
if (size) {
|
|
705
|
+
encoded.size = size;
|
|
706
|
+
}
|
|
707
|
+
if (x2Ref) {
|
|
708
|
+
encoded.x2Ref = x2Ref;
|
|
709
|
+
encoded.x2RefNames = x2RefNames;
|
|
710
|
+
}
|
|
711
|
+
if (sizeScale) {
|
|
712
|
+
encoded.sizeScale = sizeScale;
|
|
713
|
+
}
|
|
714
|
+
if (flatbushData) {
|
|
715
|
+
encoded.flatbushData = flatbushData;
|
|
716
|
+
}
|
|
717
|
+
if (scale) {
|
|
718
|
+
encoded.scale = scale;
|
|
719
|
+
}
|
|
720
|
+
if (shapeScale) {
|
|
721
|
+
encoded.shapeScale = shapeScale;
|
|
722
|
+
}
|
|
723
|
+
return encoded;
|
|
724
|
+
}
|
|
725
|
+
// A ramp's table over the values it met, painting `color` through it where
|
|
726
|
+
// the encoder resolves the scale.
|
|
727
|
+
function rampScale(rampEncoding, values, count, color, met) {
|
|
728
|
+
const extent = scaleExtent(values, count, rampEncoding.scale, rampEncoding.domainQuantile);
|
|
729
|
+
const { domainMin, domainMax, domainMid, domainQuantile, range, scheme, reverse, } = rampEncoding;
|
|
730
|
+
const { domain, lut, colorOf } = continuousColorScale(rampEncoding, extent);
|
|
731
|
+
if (color) {
|
|
732
|
+
const bits = new Uint32Array(values.buffer, values.byteOffset, count);
|
|
733
|
+
for (let k = 0; k < count; k++) {
|
|
734
|
+
color[k] =
|
|
735
|
+
bits[k] === RAMP_NO_VALUE_BITS ? NO_VALUE_ABGR : colorOf(values[k]);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
return {
|
|
739
|
+
kind: 'ramp',
|
|
740
|
+
field: rampEncoding.field,
|
|
741
|
+
scale: rampEncoding.scale,
|
|
742
|
+
domain,
|
|
743
|
+
pinned: [domainMin !== undefined, domainMax !== undefined],
|
|
744
|
+
...(domainMid === undefined ? {} : { domainMid }),
|
|
745
|
+
...(range ? { range: [...range] } : {}),
|
|
746
|
+
...(scheme ? { scheme } : {}),
|
|
747
|
+
...(reverse ? { reverse } : {}),
|
|
748
|
+
extent,
|
|
749
|
+
...(domainQuantile !== undefined && domainQuantile < 1
|
|
750
|
+
? { quantile: domainQuantile }
|
|
751
|
+
: {}),
|
|
752
|
+
lut,
|
|
753
|
+
...(met.missingMet ? { missing: true } : {}),
|
|
754
|
+
...(met.notNumberMet ? { notNumber: true } : {}),
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* #api
|
|
759
|
+
* A continuous colour scale over `extent`, the values it met: the domain its
|
|
760
|
+
* declared ends and the extent make, the straight table its stops bake to and
|
|
761
|
+
* where its middle stop sits, and the packed colour a value paints through
|
|
762
|
+
* them: an infinity the end on its side, as a threshold places it, and NaN,
|
|
763
|
+
* text that is no number, the misconfiguration grey. The encoder and every
|
|
764
|
+
* display painting a ramp itself read it, so a value takes one colour whoever
|
|
765
|
+
* paints it.
|
|
766
|
+
*/
|
|
767
|
+
export function continuousColorScale(encoding, extent) {
|
|
768
|
+
const { domainMin, domainMax, domainMid, scale } = encoding;
|
|
769
|
+
const domain = rampDomain(domainMin, domainMax, extent);
|
|
770
|
+
const norm = makeScoreNormalizer(domain[0], domain[1], scaleTypeCode(scale), 1);
|
|
771
|
+
const lut = rampLutOf(encoding);
|
|
772
|
+
const midNorm = rampMidNorm(domain[0], domain[1], scaleTypeCode(scale), domainMid);
|
|
773
|
+
return {
|
|
774
|
+
domain,
|
|
775
|
+
lut,
|
|
776
|
+
midNorm,
|
|
777
|
+
colorOf: (value) => Number.isNaN(value)
|
|
778
|
+
? FALLBACK_COLOR
|
|
779
|
+
: lutColorAt(lut, rampMidT(Number.isFinite(value) ? norm(value) : value > 0 ? 1 : 0, midNorm)),
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* #api
|
|
784
|
+
* A ramp table over `extent`, the union a display took across the regions it
|
|
785
|
+
* loaded: each open end of the domain moved to the union's, the pinned ends
|
|
786
|
+
* kept. The table stays straight and `domainMid` a value, so the middle stop
|
|
787
|
+
* follows the widened domain with no table baked again.
|
|
788
|
+
*/
|
|
789
|
+
export function rampOverExtent(table, extent) {
|
|
790
|
+
const { pinned } = table;
|
|
791
|
+
const domain = rampDomain(pinned[0] ? table.domain[0] : undefined, pinned[1] ? table.domain[1] : undefined, extent);
|
|
792
|
+
return { ...table, extent, domain };
|
|
793
|
+
}
|
|
794
|
+
function keysAreNumeric(entries) {
|
|
795
|
+
const named = entries.filter(e => e.value !== '');
|
|
796
|
+
return named.length > 0 && named.every(e => Number.isFinite(Number(e.value)));
|
|
797
|
+
}
|
|
798
|
+
// `[Infinity, -Infinity]` where no value is finite, which a union of regions'
|
|
799
|
+
// extents passes over.
|
|
800
|
+
/**
|
|
801
|
+
* #api
|
|
802
|
+
* A CSS colour or `jexl:` colour expression as a per-feature packed ABGR —
|
|
803
|
+
* the unscaled arm of {@link ColorEncoding}, on its own for a display that
|
|
804
|
+
* carries a plain `color` slot.
|
|
805
|
+
*/
|
|
806
|
+
export function colorEvaluator(color, jexl) {
|
|
807
|
+
if (isJexl(color)) {
|
|
808
|
+
const expr = jexlExpression(color, jexl);
|
|
809
|
+
// A jexl colour answers from a handful of strings over a million
|
|
810
|
+
// features; parsing each answer once is a third of the arm's cost
|
|
811
|
+
// (packages/core/benches/encodeFeatures.bench.ts).
|
|
812
|
+
const packed = new Map();
|
|
813
|
+
return feature => {
|
|
814
|
+
const v = expr.eval(buildJexlContext({ feature }));
|
|
815
|
+
if (typeof v !== 'string') {
|
|
816
|
+
return FALLBACK_COLOR;
|
|
817
|
+
}
|
|
818
|
+
let c = packed.get(v);
|
|
819
|
+
if (c === undefined) {
|
|
820
|
+
c = cssColorToABGR(v);
|
|
821
|
+
packed.set(v, c);
|
|
822
|
+
}
|
|
823
|
+
return c;
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
const constant = cssColorToABGR(color);
|
|
827
|
+
return () => constant;
|
|
828
|
+
}
|
|
829
|
+
function unscaledColor(table, color, jexl) {
|
|
830
|
+
if (typeof color === 'function') {
|
|
831
|
+
return i => color(table.row(i));
|
|
832
|
+
}
|
|
833
|
+
if (!isJexl(color)) {
|
|
834
|
+
return cssColorToABGR(color);
|
|
835
|
+
}
|
|
836
|
+
const colorOf = colorEvaluator(color, jexl);
|
|
837
|
+
return i => colorOf(table.row(i));
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* #api
|
|
841
|
+
* The input feature instance `i` of `channels` was: `featureIndex[i]`, or `i`
|
|
842
|
+
* itself where the encoder skipped none and so shipped no index.
|
|
843
|
+
*/
|
|
844
|
+
export function featureIndexAt(channels, i) {
|
|
845
|
+
const { featureIndex } = channels;
|
|
846
|
+
return featureIndex ? featureIndex[i] : i;
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* #api
|
|
850
|
+
* The packed colour instance `i` of `channels` paints: `color[i]`, or `color`
|
|
851
|
+
* itself where the colour is a constant and so shipped as one number.
|
|
852
|
+
*/
|
|
853
|
+
export function colorAt(channels, i) {
|
|
854
|
+
const { color } = channels;
|
|
855
|
+
return typeof color === 'number' ? color : color?.[i];
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* #api
|
|
859
|
+
* The buffers an {@link EncodedChannels} owns, for `rpcResult`'s transfer
|
|
860
|
+
* list.
|
|
861
|
+
*/
|
|
862
|
+
export function encodedChannelTransferables(c) {
|
|
863
|
+
// A set, since `colorValue` may be the `y` lane itself and a buffer listed
|
|
864
|
+
// twice fails the transfer.
|
|
865
|
+
const buffers = new Set([c.x.buffer, c.x2.buffer]);
|
|
866
|
+
for (const lane of [
|
|
867
|
+
c.featureIndex,
|
|
868
|
+
c.y,
|
|
869
|
+
c.row,
|
|
870
|
+
typeof c.color === 'number' ? undefined : c.color,
|
|
871
|
+
c.colorValue,
|
|
872
|
+
c.colorKey,
|
|
873
|
+
c.glyph,
|
|
874
|
+
c.size,
|
|
875
|
+
c.x2Ref,
|
|
876
|
+
]) {
|
|
877
|
+
if (lane) {
|
|
878
|
+
buffers.add(lane.buffer);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
if (c.flatbushData) {
|
|
882
|
+
buffers.add(c.flatbushData);
|
|
883
|
+
}
|
|
884
|
+
return [...buffers];
|
|
885
|
+
}
|