@jbrowse/plugin-linear-genome-view 2.6.1 → 2.6.3
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/dist/BaseLinearDisplay/components/BaseLinearDisplay.js +0 -1
- package/dist/BaseLinearDisplay/components/Block.js +0 -1
- package/dist/BaseLinearDisplay/components/BlockMsg.js +0 -1
- package/dist/BaseLinearDisplay/components/LinearBlocks.js +0 -1
- package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +0 -1
- package/dist/BaseLinearDisplay/components/TooLargeMessage.js +0 -1
- package/dist/BaseLinearDisplay/components/Tooltip.js +0 -1
- package/dist/BaseLinearDisplay/index.js +0 -1
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +0 -1
- package/dist/BaseLinearDisplay/models/FeatureDensityMixin.js +0 -1
- package/dist/BaseLinearDisplay/models/TrackHeightMixin.js +0 -1
- package/dist/BaseLinearDisplay/models/autorunFeatureDensityStats.js +0 -1
- package/dist/BaseLinearDisplay/models/configSchema.js +0 -1
- package/dist/BaseLinearDisplay/models/renderSvg.js +0 -1
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +0 -1
- package/dist/BaseLinearDisplay/models/util.js +0 -1
- package/dist/BasicTrack/configSchema.js +0 -1
- package/dist/BasicTrack/index.js +0 -1
- package/dist/FeatureTrack/configSchema.js +0 -1
- package/dist/FeatureTrack/index.js +0 -1
- package/dist/LaunchLinearGenomeView/index.js +0 -1
- package/dist/LinearBareDisplay/configSchema.js +0 -1
- package/dist/LinearBareDisplay/index.js +0 -1
- package/dist/LinearBareDisplay/model.js +0 -1
- package/dist/LinearBasicDisplay/components/SetMaxHeight.js +0 -1
- package/dist/LinearBasicDisplay/configSchema.js +0 -1
- package/dist/LinearBasicDisplay/index.js +0 -1
- package/dist/LinearBasicDisplay/model.js +0 -1
- package/dist/LinearGenomeView/components/CenterLine.js +0 -1
- package/dist/LinearGenomeView/components/Cytobands.js +0 -1
- package/dist/LinearGenomeView/components/ExportSvgDialog.js +0 -1
- package/dist/LinearGenomeView/components/GetSequenceDialog.js +0 -1
- package/dist/LinearGenomeView/components/Gridlines.js +0 -1
- package/dist/LinearGenomeView/components/Header.js +0 -1
- package/dist/LinearGenomeView/components/ImportForm.js +0 -1
- package/dist/LinearGenomeView/components/LinearGenomeView.js +0 -1
- package/dist/LinearGenomeView/components/MiniControls.js +0 -1
- package/dist/LinearGenomeView/components/OverviewRubberband.js +0 -1
- package/dist/LinearGenomeView/components/OverviewScalebar.js +0 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +0 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +0 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +0 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/index.js +0 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/util.js +0 -1
- package/dist/LinearGenomeView/components/Rubberband.js +0 -1
- package/dist/LinearGenomeView/components/RubberbandSpan.js +0 -1
- package/dist/LinearGenomeView/components/Scalebar.js +0 -1
- package/dist/LinearGenomeView/components/SearchBox.js +0 -1
- package/dist/LinearGenomeView/components/SearchResultsDialog.js +0 -1
- package/dist/LinearGenomeView/components/SearchResultsTable.js +0 -1
- package/dist/LinearGenomeView/components/SequenceSearchDialog.js +0 -1
- package/dist/LinearGenomeView/components/TrackContainer.js +0 -1
- package/dist/LinearGenomeView/components/TrackLabel.js +1 -2
- package/dist/LinearGenomeView/components/TrackLabelContainer.js +0 -1
- package/dist/LinearGenomeView/components/TrackRenderingContainer.js +3 -2
- package/dist/LinearGenomeView/components/TracksContainer.js +0 -1
- package/dist/LinearGenomeView/components/VerticalGuide.js +0 -1
- package/dist/LinearGenomeView/components/ZoomControls.js +0 -1
- package/dist/LinearGenomeView/components/hooks.js +0 -1
- package/dist/LinearGenomeView/components/util.js +0 -1
- package/dist/LinearGenomeView/index.js +0 -1
- package/dist/LinearGenomeView/model.js +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGBackground.js +2 -2
- package/dist/LinearGenomeView/svgcomponents/SVGHeader.js +6 -5
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGRuler.js +6 -4
- package/dist/LinearGenomeView/svgcomponents/SVGScalebar.js +8 -5
- package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.js +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGTracks.js +0 -1
- package/dist/LinearGenomeView/util.js +0 -1
- package/dist/index.js +0 -1
- package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js +0 -1
- package/esm/BaseLinearDisplay/components/Block.js +0 -1
- package/esm/BaseLinearDisplay/components/BlockMsg.js +0 -1
- package/esm/BaseLinearDisplay/components/LinearBlocks.js +0 -1
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +0 -1
- package/esm/BaseLinearDisplay/components/TooLargeMessage.js +0 -1
- package/esm/BaseLinearDisplay/components/Tooltip.js +0 -1
- package/esm/BaseLinearDisplay/index.js +0 -1
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +0 -1
- package/esm/BaseLinearDisplay/models/FeatureDensityMixin.js +0 -1
- package/esm/BaseLinearDisplay/models/TrackHeightMixin.js +0 -1
- package/esm/BaseLinearDisplay/models/autorunFeatureDensityStats.js +0 -1
- package/esm/BaseLinearDisplay/models/configSchema.js +0 -1
- package/esm/BaseLinearDisplay/models/renderSvg.js +0 -1
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +0 -1
- package/esm/BaseLinearDisplay/models/util.js +0 -1
- package/esm/BasicTrack/configSchema.js +0 -1
- package/esm/BasicTrack/index.js +0 -1
- package/esm/FeatureTrack/configSchema.js +0 -1
- package/esm/FeatureTrack/index.js +0 -1
- package/esm/LaunchLinearGenomeView/index.js +0 -1
- package/esm/LinearBareDisplay/configSchema.js +0 -1
- package/esm/LinearBareDisplay/index.js +0 -1
- package/esm/LinearBareDisplay/model.js +0 -1
- package/esm/LinearBasicDisplay/components/SetMaxHeight.js +0 -1
- package/esm/LinearBasicDisplay/configSchema.js +0 -1
- package/esm/LinearBasicDisplay/index.js +0 -1
- package/esm/LinearBasicDisplay/model.js +0 -1
- package/esm/LinearGenomeView/components/CenterLine.js +0 -1
- package/esm/LinearGenomeView/components/Cytobands.js +0 -1
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +0 -1
- package/esm/LinearGenomeView/components/GetSequenceDialog.js +0 -1
- package/esm/LinearGenomeView/components/Gridlines.js +0 -1
- package/esm/LinearGenomeView/components/Header.js +0 -1
- package/esm/LinearGenomeView/components/ImportForm.js +0 -1
- package/esm/LinearGenomeView/components/LinearGenomeView.js +0 -1
- package/esm/LinearGenomeView/components/MiniControls.js +0 -1
- package/esm/LinearGenomeView/components/OverviewRubberband.js +0 -1
- package/esm/LinearGenomeView/components/OverviewScalebar.js +0 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +0 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +0 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +0 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js +0 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/util.js +0 -1
- package/esm/LinearGenomeView/components/Rubberband.js +0 -1
- package/esm/LinearGenomeView/components/RubberbandSpan.js +0 -1
- package/esm/LinearGenomeView/components/Scalebar.js +0 -1
- package/esm/LinearGenomeView/components/SearchBox.js +0 -1
- package/esm/LinearGenomeView/components/SearchResultsDialog.js +0 -1
- package/esm/LinearGenomeView/components/SearchResultsTable.js +0 -1
- package/esm/LinearGenomeView/components/SequenceSearchDialog.js +0 -1
- package/esm/LinearGenomeView/components/TrackContainer.js +0 -1
- package/esm/LinearGenomeView/components/TrackLabel.js +1 -2
- package/esm/LinearGenomeView/components/TrackLabelContainer.js +0 -1
- package/esm/LinearGenomeView/components/TrackRenderingContainer.js +4 -3
- package/esm/LinearGenomeView/components/TracksContainer.js +0 -1
- package/esm/LinearGenomeView/components/VerticalGuide.js +0 -1
- package/esm/LinearGenomeView/components/ZoomControls.js +0 -1
- package/esm/LinearGenomeView/components/hooks.js +0 -1
- package/esm/LinearGenomeView/components/util.js +0 -1
- package/esm/LinearGenomeView/index.js +0 -1
- package/esm/LinearGenomeView/model.js +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGBackground.js +2 -2
- package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +6 -5
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +6 -4
- package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +8 -5
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +0 -1
- package/esm/LinearGenomeView/util.js +0 -1
- package/esm/index.js +0 -1
- package/package.json +4 -4
- package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js.map +0 -1
- package/dist/BaseLinearDisplay/components/Block.js.map +0 -1
- package/dist/BaseLinearDisplay/components/BlockMsg.js.map +0 -1
- package/dist/BaseLinearDisplay/components/LinearBlocks.js.map +0 -1
- package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +0 -1
- package/dist/BaseLinearDisplay/components/TooLargeMessage.js.map +0 -1
- package/dist/BaseLinearDisplay/components/Tooltip.js.map +0 -1
- package/dist/BaseLinearDisplay/index.js.map +0 -1
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +0 -1
- package/dist/BaseLinearDisplay/models/FeatureDensityMixin.js.map +0 -1
- package/dist/BaseLinearDisplay/models/TrackHeightMixin.js.map +0 -1
- package/dist/BaseLinearDisplay/models/autorunFeatureDensityStats.js.map +0 -1
- package/dist/BaseLinearDisplay/models/configSchema.js.map +0 -1
- package/dist/BaseLinearDisplay/models/renderSvg.js.map +0 -1
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +0 -1
- package/dist/BaseLinearDisplay/models/util.js.map +0 -1
- package/dist/BasicTrack/configSchema.js.map +0 -1
- package/dist/BasicTrack/index.js.map +0 -1
- package/dist/FeatureTrack/configSchema.js.map +0 -1
- package/dist/FeatureTrack/index.js.map +0 -1
- package/dist/LaunchLinearGenomeView/index.js.map +0 -1
- package/dist/LinearBareDisplay/configSchema.js.map +0 -1
- package/dist/LinearBareDisplay/index.js.map +0 -1
- package/dist/LinearBareDisplay/model.js.map +0 -1
- package/dist/LinearBasicDisplay/components/SetMaxHeight.js.map +0 -1
- package/dist/LinearBasicDisplay/configSchema.js.map +0 -1
- package/dist/LinearBasicDisplay/index.js.map +0 -1
- package/dist/LinearBasicDisplay/model.js.map +0 -1
- package/dist/LinearGenomeView/components/CenterLine.js.map +0 -1
- package/dist/LinearGenomeView/components/Cytobands.js.map +0 -1
- package/dist/LinearGenomeView/components/ExportSvgDialog.js.map +0 -1
- package/dist/LinearGenomeView/components/GetSequenceDialog.js.map +0 -1
- package/dist/LinearGenomeView/components/Gridlines.js.map +0 -1
- package/dist/LinearGenomeView/components/Header.js.map +0 -1
- package/dist/LinearGenomeView/components/ImportForm.js.map +0 -1
- package/dist/LinearGenomeView/components/LinearGenomeView.js.map +0 -1
- package/dist/LinearGenomeView/components/MiniControls.js.map +0 -1
- package/dist/LinearGenomeView/components/OverviewRubberband.js.map +0 -1
- package/dist/LinearGenomeView/components/OverviewScalebar.js.map +0 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js.map +0 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js.map +0 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js.map +0 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/index.js.map +0 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete/util.js.map +0 -1
- package/dist/LinearGenomeView/components/Rubberband.js.map +0 -1
- package/dist/LinearGenomeView/components/RubberbandSpan.js.map +0 -1
- package/dist/LinearGenomeView/components/Scalebar.js.map +0 -1
- package/dist/LinearGenomeView/components/SearchBox.js.map +0 -1
- package/dist/LinearGenomeView/components/SearchResultsDialog.js.map +0 -1
- package/dist/LinearGenomeView/components/SearchResultsTable.js.map +0 -1
- package/dist/LinearGenomeView/components/SequenceSearchDialog.js.map +0 -1
- package/dist/LinearGenomeView/components/TrackContainer.js.map +0 -1
- package/dist/LinearGenomeView/components/TrackLabel.js.map +0 -1
- package/dist/LinearGenomeView/components/TrackLabelContainer.js.map +0 -1
- package/dist/LinearGenomeView/components/TrackRenderingContainer.js.map +0 -1
- package/dist/LinearGenomeView/components/TracksContainer.js.map +0 -1
- package/dist/LinearGenomeView/components/VerticalGuide.js.map +0 -1
- package/dist/LinearGenomeView/components/ZoomControls.js.map +0 -1
- package/dist/LinearGenomeView/components/hooks.js.map +0 -1
- package/dist/LinearGenomeView/components/util.js.map +0 -1
- package/dist/LinearGenomeView/index.js.map +0 -1
- package/dist/LinearGenomeView/model.js.map +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGBackground.js.map +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGHeader.js.map +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js.map +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGRegionSeparators.js.map +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGRuler.js.map +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGScalebar.js.map +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.js.map +0 -1
- package/dist/LinearGenomeView/svgcomponents/SVGTracks.js.map +0 -1
- package/dist/LinearGenomeView/util.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js.map +0 -1
- package/esm/BaseLinearDisplay/components/Block.js.map +0 -1
- package/esm/BaseLinearDisplay/components/BlockMsg.js.map +0 -1
- package/esm/BaseLinearDisplay/components/LinearBlocks.js.map +0 -1
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +0 -1
- package/esm/BaseLinearDisplay/components/TooLargeMessage.js.map +0 -1
- package/esm/BaseLinearDisplay/components/Tooltip.js.map +0 -1
- package/esm/BaseLinearDisplay/index.js.map +0 -1
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +0 -1
- package/esm/BaseLinearDisplay/models/FeatureDensityMixin.js.map +0 -1
- package/esm/BaseLinearDisplay/models/TrackHeightMixin.js.map +0 -1
- package/esm/BaseLinearDisplay/models/autorunFeatureDensityStats.js.map +0 -1
- package/esm/BaseLinearDisplay/models/configSchema.js.map +0 -1
- package/esm/BaseLinearDisplay/models/renderSvg.js.map +0 -1
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +0 -1
- package/esm/BaseLinearDisplay/models/util.js.map +0 -1
- package/esm/BasicTrack/configSchema.js.map +0 -1
- package/esm/BasicTrack/index.js.map +0 -1
- package/esm/FeatureTrack/configSchema.js.map +0 -1
- package/esm/FeatureTrack/index.js.map +0 -1
- package/esm/LaunchLinearGenomeView/index.js.map +0 -1
- package/esm/LinearBareDisplay/configSchema.js.map +0 -1
- package/esm/LinearBareDisplay/index.js.map +0 -1
- package/esm/LinearBareDisplay/model.js.map +0 -1
- package/esm/LinearBasicDisplay/components/SetMaxHeight.js.map +0 -1
- package/esm/LinearBasicDisplay/configSchema.js.map +0 -1
- package/esm/LinearBasicDisplay/index.js.map +0 -1
- package/esm/LinearBasicDisplay/model.js.map +0 -1
- package/esm/LinearGenomeView/components/CenterLine.js.map +0 -1
- package/esm/LinearGenomeView/components/Cytobands.js.map +0 -1
- package/esm/LinearGenomeView/components/ExportSvgDialog.js.map +0 -1
- package/esm/LinearGenomeView/components/GetSequenceDialog.js.map +0 -1
- package/esm/LinearGenomeView/components/Gridlines.js.map +0 -1
- package/esm/LinearGenomeView/components/Header.js.map +0 -1
- package/esm/LinearGenomeView/components/ImportForm.js.map +0 -1
- package/esm/LinearGenomeView/components/LinearGenomeView.js.map +0 -1
- package/esm/LinearGenomeView/components/MiniControls.js.map +0 -1
- package/esm/LinearGenomeView/components/OverviewRubberband.js.map +0 -1
- package/esm/LinearGenomeView/components/OverviewScalebar.js.map +0 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js.map +0 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js.map +0 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js.map +0 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js.map +0 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete/util.js.map +0 -1
- package/esm/LinearGenomeView/components/Rubberband.js.map +0 -1
- package/esm/LinearGenomeView/components/RubberbandSpan.js.map +0 -1
- package/esm/LinearGenomeView/components/Scalebar.js.map +0 -1
- package/esm/LinearGenomeView/components/SearchBox.js.map +0 -1
- package/esm/LinearGenomeView/components/SearchResultsDialog.js.map +0 -1
- package/esm/LinearGenomeView/components/SearchResultsTable.js.map +0 -1
- package/esm/LinearGenomeView/components/SequenceSearchDialog.js.map +0 -1
- package/esm/LinearGenomeView/components/TrackContainer.js.map +0 -1
- package/esm/LinearGenomeView/components/TrackLabel.js.map +0 -1
- package/esm/LinearGenomeView/components/TrackLabelContainer.js.map +0 -1
- package/esm/LinearGenomeView/components/TrackRenderingContainer.js.map +0 -1
- package/esm/LinearGenomeView/components/TracksContainer.js.map +0 -1
- package/esm/LinearGenomeView/components/VerticalGuide.js.map +0 -1
- package/esm/LinearGenomeView/components/ZoomControls.js.map +0 -1
- package/esm/LinearGenomeView/components/hooks.js.map +0 -1
- package/esm/LinearGenomeView/components/util.js.map +0 -1
- package/esm/LinearGenomeView/index.js.map +0 -1
- package/esm/LinearGenomeView/model.js.map +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGBackground.js.map +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGHeader.js.map +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js.map +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js.map +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.js.map +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js.map +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js.map +0 -1
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.js.map +0 -1
- package/esm/LinearGenomeView/util.js.map +0 -1
- package/esm/index.js.map +0 -1
- package/src/BaseLinearDisplay/components/BaseLinearDisplay.tsx +0 -117
- package/src/BaseLinearDisplay/components/Block.tsx +0 -77
- package/src/BaseLinearDisplay/components/BlockMsg.tsx +0 -42
- package/src/BaseLinearDisplay/components/LinearBlocks.tsx +0 -119
- package/src/BaseLinearDisplay/components/ServerSideRenderedBlockContent.tsx +0 -69
- package/src/BaseLinearDisplay/components/TooLargeMessage.tsx +0 -36
- package/src/BaseLinearDisplay/components/Tooltip.tsx +0 -107
- package/src/BaseLinearDisplay/index.ts +0 -16
- package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +0 -407
- package/src/BaseLinearDisplay/models/FeatureDensityMixin.tsx +0 -213
- package/src/BaseLinearDisplay/models/TrackHeightMixin.tsx +0 -59
- package/src/BaseLinearDisplay/models/autorunFeatureDensityStats.ts +0 -46
- package/src/BaseLinearDisplay/models/configSchema.ts +0 -60
- package/src/BaseLinearDisplay/models/renderSvg.tsx +0 -101
- package/src/BaseLinearDisplay/models/serverSideRenderedBlock.ts +0 -320
- package/src/BaseLinearDisplay/models/util.ts +0 -67
- package/src/BasicTrack/configSchema.ts +0 -24
- package/src/BasicTrack/index.ts +0 -18
- package/src/FeatureTrack/configSchema.ts +0 -28
- package/src/FeatureTrack/index.ts +0 -18
- package/src/LaunchLinearGenomeView/index.ts +0 -66
- package/src/LinearBareDisplay/configSchema.ts +0 -28
- package/src/LinearBareDisplay/index.test.js +0 -34
- package/src/LinearBareDisplay/index.ts +0 -25
- package/src/LinearBareDisplay/model.ts +0 -54
- package/src/LinearBasicDisplay/components/SetMaxHeight.tsx +0 -73
- package/src/LinearBasicDisplay/configSchema.ts +0 -28
- package/src/LinearBasicDisplay/index.ts +0 -25
- package/src/LinearBasicDisplay/model.ts +0 -215
- package/src/LinearGenomeView/README.md +0 -9
- package/src/LinearGenomeView/components/CenterLine.tsx +0 -65
- package/src/LinearGenomeView/components/Cytobands.tsx +0 -154
- package/src/LinearGenomeView/components/ExportSvgDialog.tsx +0 -149
- package/src/LinearGenomeView/components/GetSequenceDialog.tsx +0 -269
- package/src/LinearGenomeView/components/Gridlines.tsx +0 -119
- package/src/LinearGenomeView/components/Header.tsx +0 -126
- package/src/LinearGenomeView/components/ImportForm.tsx +0 -217
- package/src/LinearGenomeView/components/LinearGenomeView.test.tsx +0 -167
- package/src/LinearGenomeView/components/LinearGenomeView.tsx +0 -75
- package/src/LinearGenomeView/components/MiniControls.tsx +0 -54
- package/src/LinearGenomeView/components/OverviewRubberband.tsx +0 -219
- package/src/LinearGenomeView/components/OverviewScalebar.tsx +0 -351
- package/src/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.tsx +0 -53
- package/src/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.tsx +0 -44
- package/src/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.tsx +0 -69
- package/src/LinearGenomeView/components/RefNameAutocomplete/index.tsx +0 -160
- package/src/LinearGenomeView/components/RefNameAutocomplete/util.ts +0 -65
- package/src/LinearGenomeView/components/Rubberband.tsx +0 -89
- package/src/LinearGenomeView/components/RubberbandSpan.tsx +0 -99
- package/src/LinearGenomeView/components/Scalebar.test.tsx +0 -145
- package/src/LinearGenomeView/components/Scalebar.tsx +0 -199
- package/src/LinearGenomeView/components/SearchBox.tsx +0 -123
- package/src/LinearGenomeView/components/SearchResultsDialog.tsx +0 -57
- package/src/LinearGenomeView/components/SearchResultsTable.tsx +0 -121
- package/src/LinearGenomeView/components/SequenceSearchDialog.tsx +0 -136
- package/src/LinearGenomeView/components/TrackContainer.tsx +0 -92
- package/src/LinearGenomeView/components/TrackLabel.tsx +0 -123
- package/src/LinearGenomeView/components/TrackLabelContainer.tsx +0 -48
- package/src/LinearGenomeView/components/TrackRenderingContainer.tsx +0 -96
- package/src/LinearGenomeView/components/TracksContainer.tsx +0 -114
- package/src/LinearGenomeView/components/VerticalGuide.tsx +0 -37
- package/src/LinearGenomeView/components/ZoomControls.tsx +0 -62
- package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.tsx.snap +0 -1520
- package/src/LinearGenomeView/components/hooks.ts +0 -306
- package/src/LinearGenomeView/components/util.ts +0 -76
- package/src/LinearGenomeView/hg38DisplayedRegions.json +0 -3187
- package/src/LinearGenomeView/index.test.ts +0 -993
- package/src/LinearGenomeView/index.ts +0 -17
- package/src/LinearGenomeView/model.ts +0 -1533
- package/src/LinearGenomeView/svgcomponents/SVGBackground.tsx +0 -21
- package/src/LinearGenomeView/svgcomponents/SVGHeader.tsx +0 -95
- package/src/LinearGenomeView/svgcomponents/SVGLinearGenomeView.tsx +0 -114
- package/src/LinearGenomeView/svgcomponents/SVGRegionSeparators.tsx +0 -31
- package/src/LinearGenomeView/svgcomponents/SVGRuler.tsx +0 -125
- package/src/LinearGenomeView/svgcomponents/SVGScalebar.tsx +0 -57
- package/src/LinearGenomeView/svgcomponents/SVGTrackLabel.tsx +0 -47
- package/src/LinearGenomeView/svgcomponents/SVGTracks.tsx +0 -67
- package/src/LinearGenomeView/util.test.ts +0 -33
- package/src/LinearGenomeView/util.ts +0 -182
- package/src/LinearGenomeView/volvoxDisplayedRegions.json +0 -16
- package/src/index.ts +0 -91
|
@@ -1,1533 +0,0 @@
|
|
|
1
|
-
import React, { lazy } from 'react'
|
|
2
|
-
import { getConf, AnyConfigurationModel } from '@jbrowse/core/configuration'
|
|
3
|
-
import { BaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'
|
|
4
|
-
import { Region } from '@jbrowse/core/util/types'
|
|
5
|
-
import { ElementId, Region as MUIRegion } from '@jbrowse/core/util/types/mst'
|
|
6
|
-
import { MenuItem } from '@jbrowse/core/ui'
|
|
7
|
-
import {
|
|
8
|
-
assembleLocString,
|
|
9
|
-
clamp,
|
|
10
|
-
findLast,
|
|
11
|
-
getContainingView,
|
|
12
|
-
getSession,
|
|
13
|
-
isViewContainer,
|
|
14
|
-
isSessionModelWithWidgets,
|
|
15
|
-
isSessionWithAddTracks,
|
|
16
|
-
localStorageGetItem,
|
|
17
|
-
measureText,
|
|
18
|
-
springAnimate,
|
|
19
|
-
sum,
|
|
20
|
-
ParsedLocString,
|
|
21
|
-
} from '@jbrowse/core/util'
|
|
22
|
-
import BaseResult from '@jbrowse/core/TextSearch/BaseResults'
|
|
23
|
-
import { BlockSet, BaseBlock } from '@jbrowse/core/util/blockTypes'
|
|
24
|
-
import calculateDynamicBlocks from '@jbrowse/core/util/calculateDynamicBlocks'
|
|
25
|
-
import calculateStaticBlocks from '@jbrowse/core/util/calculateStaticBlocks'
|
|
26
|
-
import { getParentRenderProps } from '@jbrowse/core/util/tracks'
|
|
27
|
-
import { when, transaction, autorun } from 'mobx'
|
|
28
|
-
import {
|
|
29
|
-
addDisposer,
|
|
30
|
-
cast,
|
|
31
|
-
getSnapshot,
|
|
32
|
-
getRoot,
|
|
33
|
-
resolveIdentifier,
|
|
34
|
-
types,
|
|
35
|
-
Instance,
|
|
36
|
-
} from 'mobx-state-tree'
|
|
37
|
-
|
|
38
|
-
import Base1DView from '@jbrowse/core/util/Base1DViewModel'
|
|
39
|
-
import { moveTo, pxToBp, bpToPx } from '@jbrowse/core/util/Base1DUtils'
|
|
40
|
-
import { saveAs } from 'file-saver'
|
|
41
|
-
import clone from 'clone'
|
|
42
|
-
import PluginManager from '@jbrowse/core/PluginManager'
|
|
43
|
-
|
|
44
|
-
// icons
|
|
45
|
-
import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons'
|
|
46
|
-
import SyncAltIcon from '@mui/icons-material/SyncAlt'
|
|
47
|
-
import VisibilityIcon from '@mui/icons-material/Visibility'
|
|
48
|
-
import LabelIcon from '@mui/icons-material/Label'
|
|
49
|
-
import FolderOpenIcon from '@mui/icons-material/FolderOpen'
|
|
50
|
-
import PhotoCameraIcon from '@mui/icons-material/PhotoCamera'
|
|
51
|
-
import ZoomInIcon from '@mui/icons-material/ZoomIn'
|
|
52
|
-
import MenuOpenIcon from '@mui/icons-material/MenuOpen'
|
|
53
|
-
|
|
54
|
-
import MiniControls from './components/MiniControls'
|
|
55
|
-
import Header from './components/Header'
|
|
56
|
-
import { generateLocations, parseLocStrings } from './util'
|
|
57
|
-
|
|
58
|
-
// lazies
|
|
59
|
-
const ReturnToImportFormDialog = lazy(
|
|
60
|
-
() => import('@jbrowse/core/ui/ReturnToImportFormDialog'),
|
|
61
|
-
)
|
|
62
|
-
const SequenceSearchDialog = lazy(
|
|
63
|
-
() => import('./components/SequenceSearchDialog'),
|
|
64
|
-
)
|
|
65
|
-
const ExportSvgDialog = lazy(() => import('./components/ExportSvgDialog'))
|
|
66
|
-
const GetSequenceDialog = lazy(() => import('./components/GetSequenceDialog'))
|
|
67
|
-
const SearchResultsDialog = lazy(
|
|
68
|
-
() => import('./components/SearchResultsDialog'),
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
export interface BpOffset {
|
|
72
|
-
refName?: string
|
|
73
|
-
index: number
|
|
74
|
-
offset: number
|
|
75
|
-
start?: number
|
|
76
|
-
end?: number
|
|
77
|
-
coord?: number
|
|
78
|
-
reversed?: boolean
|
|
79
|
-
assemblyName?: string
|
|
80
|
-
oob?: boolean
|
|
81
|
-
}
|
|
82
|
-
export interface ExportSvgOptions {
|
|
83
|
-
rasterizeLayers?: boolean
|
|
84
|
-
filename?: string
|
|
85
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
86
|
-
Wrapper?: React.FC<any>
|
|
87
|
-
fontSize?: number
|
|
88
|
-
rulerHeight?: number
|
|
89
|
-
textHeight?: number
|
|
90
|
-
paddingHeight?: number
|
|
91
|
-
headerHeight?: number
|
|
92
|
-
cytobandHeight?: number
|
|
93
|
-
trackLabels?: string
|
|
94
|
-
themeName?: string
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function calculateVisibleLocStrings(contentBlocks: BaseBlock[]) {
|
|
98
|
-
if (!contentBlocks.length) {
|
|
99
|
-
return ''
|
|
100
|
-
}
|
|
101
|
-
const isSingleAssemblyName = contentBlocks.every(
|
|
102
|
-
b => b.assemblyName === contentBlocks[0].assemblyName,
|
|
103
|
-
)
|
|
104
|
-
const locs = contentBlocks.map(block =>
|
|
105
|
-
assembleLocString({
|
|
106
|
-
...block,
|
|
107
|
-
start: Math.round(block.start),
|
|
108
|
-
end: Math.round(block.end),
|
|
109
|
-
assemblyName: isSingleAssemblyName ? undefined : block.assemblyName,
|
|
110
|
-
}),
|
|
111
|
-
)
|
|
112
|
-
return locs.join(' ')
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export interface NavLocation {
|
|
116
|
-
refName: string
|
|
117
|
-
start?: number
|
|
118
|
-
end?: number
|
|
119
|
-
assemblyName?: string
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export const HEADER_BAR_HEIGHT = 48
|
|
123
|
-
export const HEADER_OVERVIEW_HEIGHT = 20
|
|
124
|
-
export const SCALE_BAR_HEIGHT = 17
|
|
125
|
-
export const RESIZE_HANDLE_HEIGHT = 3
|
|
126
|
-
export const INTER_REGION_PADDING_WIDTH = 2
|
|
127
|
-
export const SPACING = 7
|
|
128
|
-
export const WIDGET_HEIGHT = 32
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* #stateModel LinearGenomeView
|
|
132
|
-
* #category view
|
|
133
|
-
*/
|
|
134
|
-
export function stateModelFactory(pluginManager: PluginManager) {
|
|
135
|
-
return types
|
|
136
|
-
.compose(
|
|
137
|
-
BaseViewModel,
|
|
138
|
-
types.model('LinearGenomeView', {
|
|
139
|
-
/**
|
|
140
|
-
* #property
|
|
141
|
-
*/
|
|
142
|
-
id: ElementId,
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* #property
|
|
146
|
-
* this is a string instead of the const literal 'LinearGenomeView' to
|
|
147
|
-
* reduce some typescripting strictness, but you should pass the string
|
|
148
|
-
* 'LinearGenomeView' to the model explicitly
|
|
149
|
-
*/
|
|
150
|
-
type: types.literal('LinearGenomeView') as unknown as string,
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* #property
|
|
154
|
-
* corresponds roughly to the horizontal scroll of the LGV
|
|
155
|
-
*/
|
|
156
|
-
offsetPx: 0,
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* #property
|
|
160
|
-
* corresponds roughly to the zoom level, base-pairs per pixel
|
|
161
|
-
*/
|
|
162
|
-
bpPerPx: 1,
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* #property
|
|
166
|
-
* currently displayed regions, can be a single chromosome, arbitrary
|
|
167
|
-
* subsections, or the entire set of chromosomes in the genome, but it not
|
|
168
|
-
* advised to use the entire set of chromosomes if your assembly is very
|
|
169
|
-
* fragmented
|
|
170
|
-
*/
|
|
171
|
-
displayedRegions: types.array(MUIRegion),
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* #property
|
|
175
|
-
* array of currently displayed tracks state models instances
|
|
176
|
-
*/
|
|
177
|
-
tracks: types.array(
|
|
178
|
-
pluginManager.pluggableMstType('track', 'stateModel'),
|
|
179
|
-
),
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* #property
|
|
183
|
-
* array of currently displayed tracks state model's
|
|
184
|
-
*/
|
|
185
|
-
hideHeader: false,
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* #property
|
|
189
|
-
*/
|
|
190
|
-
hideHeaderOverview: false,
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* #property
|
|
194
|
-
*/
|
|
195
|
-
hideNoTracksActive: false,
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* #property
|
|
199
|
-
*/
|
|
200
|
-
trackSelectorType: types.optional(
|
|
201
|
-
types.enumeration(['hierarchical']),
|
|
202
|
-
'hierarchical',
|
|
203
|
-
),
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* #property
|
|
207
|
-
* how to display the track labels, can be "overlapping", "offset", or
|
|
208
|
-
* "hidden"
|
|
209
|
-
*/
|
|
210
|
-
trackLabels: types.optional(
|
|
211
|
-
types.string,
|
|
212
|
-
() => localStorageGetItem('lgv-trackLabels') || 'overlapping',
|
|
213
|
-
),
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* #property
|
|
217
|
-
* show the "center line"
|
|
218
|
-
*/
|
|
219
|
-
showCenterLine: types.optional(types.boolean, () =>
|
|
220
|
-
Boolean(
|
|
221
|
-
JSON.parse(localStorageGetItem('lgv-showCenterLine') || 'false'),
|
|
222
|
-
),
|
|
223
|
-
),
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* #property
|
|
227
|
-
* show the "cytobands" in the overview scale bar
|
|
228
|
-
*/
|
|
229
|
-
showCytobandsSetting: types.optional(types.boolean, () =>
|
|
230
|
-
Boolean(
|
|
231
|
-
JSON.parse(localStorageGetItem('lgv-showCytobands') || 'true'),
|
|
232
|
-
),
|
|
233
|
-
),
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* #property
|
|
237
|
-
* show the "gridlines" in the track area
|
|
238
|
-
*/
|
|
239
|
-
showGridlines: true,
|
|
240
|
-
}),
|
|
241
|
-
)
|
|
242
|
-
.volatile(() => ({
|
|
243
|
-
volatileWidth: undefined as number | undefined,
|
|
244
|
-
minimumBlockWidth: 3,
|
|
245
|
-
draggingTrackId: undefined as undefined | string,
|
|
246
|
-
volatileError: undefined as undefined | Error,
|
|
247
|
-
|
|
248
|
-
// array of callbacks to run after the next set of the displayedRegions,
|
|
249
|
-
// which is basically like an onLoad
|
|
250
|
-
afterDisplayedRegionsSetCallbacks: [] as Function[],
|
|
251
|
-
scaleFactor: 1,
|
|
252
|
-
trackRefs: {} as { [key: string]: HTMLDivElement },
|
|
253
|
-
coarseDynamicBlocks: [] as BaseBlock[],
|
|
254
|
-
coarseTotalBp: 0,
|
|
255
|
-
leftOffset: undefined as undefined | BpOffset,
|
|
256
|
-
rightOffset: undefined as undefined | BpOffset,
|
|
257
|
-
}))
|
|
258
|
-
.views(self => ({
|
|
259
|
-
/**
|
|
260
|
-
* #getter
|
|
261
|
-
*/
|
|
262
|
-
get width(): number {
|
|
263
|
-
if (self.volatileWidth === undefined) {
|
|
264
|
-
throw new Error(
|
|
265
|
-
'width undefined, make sure to check for model.initialized',
|
|
266
|
-
)
|
|
267
|
-
}
|
|
268
|
-
return self.volatileWidth
|
|
269
|
-
},
|
|
270
|
-
/**
|
|
271
|
-
* #getter
|
|
272
|
-
*/
|
|
273
|
-
get interRegionPaddingWidth() {
|
|
274
|
-
return INTER_REGION_PADDING_WIDTH
|
|
275
|
-
},
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* #getter
|
|
279
|
-
*/
|
|
280
|
-
get assemblyNames() {
|
|
281
|
-
return [
|
|
282
|
-
...new Set(self.displayedRegions.map(region => region.assemblyName)),
|
|
283
|
-
]
|
|
284
|
-
},
|
|
285
|
-
}))
|
|
286
|
-
.views(self => ({
|
|
287
|
-
/**
|
|
288
|
-
* #method
|
|
289
|
-
*/
|
|
290
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
291
|
-
MiniControlsComponent(): React.FC<any> {
|
|
292
|
-
return MiniControls
|
|
293
|
-
},
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* #method
|
|
297
|
-
*/
|
|
298
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
299
|
-
HeaderComponent(): React.FC<any> {
|
|
300
|
-
return Header
|
|
301
|
-
},
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* #getter
|
|
305
|
-
*/
|
|
306
|
-
get assemblyErrors() {
|
|
307
|
-
const { assemblyManager } = getSession(self)
|
|
308
|
-
const { assemblyNames } = self
|
|
309
|
-
return assemblyNames
|
|
310
|
-
.map(a => assemblyManager.get(a)?.error)
|
|
311
|
-
.filter(f => !!f)
|
|
312
|
-
.join(', ')
|
|
313
|
-
},
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* #getter
|
|
317
|
-
*/
|
|
318
|
-
get assembliesInitialized() {
|
|
319
|
-
const { assemblyManager } = getSession(self)
|
|
320
|
-
const { assemblyNames } = self
|
|
321
|
-
return assemblyNames.every(a => assemblyManager.get(a)?.initialized)
|
|
322
|
-
},
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* #getter
|
|
326
|
-
*/
|
|
327
|
-
get initialized() {
|
|
328
|
-
return self.volatileWidth !== undefined && this.assembliesInitialized
|
|
329
|
-
},
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* #getter
|
|
333
|
-
*/
|
|
334
|
-
get hasDisplayedRegions() {
|
|
335
|
-
return self.displayedRegions.length > 0
|
|
336
|
-
},
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* #getter
|
|
340
|
-
*/
|
|
341
|
-
get scaleBarHeight() {
|
|
342
|
-
return SCALE_BAR_HEIGHT + RESIZE_HANDLE_HEIGHT
|
|
343
|
-
},
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* #getter
|
|
347
|
-
*/
|
|
348
|
-
get headerHeight() {
|
|
349
|
-
if (self.hideHeader) {
|
|
350
|
-
return 0
|
|
351
|
-
}
|
|
352
|
-
if (self.hideHeaderOverview) {
|
|
353
|
-
return HEADER_BAR_HEIGHT
|
|
354
|
-
}
|
|
355
|
-
return HEADER_BAR_HEIGHT + HEADER_OVERVIEW_HEIGHT
|
|
356
|
-
},
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* #getter
|
|
360
|
-
*/
|
|
361
|
-
get trackHeights() {
|
|
362
|
-
return sum(self.tracks.map(t => t.displays[0].height))
|
|
363
|
-
},
|
|
364
|
-
|
|
365
|
-
/**
|
|
366
|
-
* #getter
|
|
367
|
-
*/
|
|
368
|
-
get trackHeightsWithResizeHandles() {
|
|
369
|
-
return this.trackHeights + self.tracks.length * RESIZE_HANDLE_HEIGHT
|
|
370
|
-
},
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* #getter
|
|
374
|
-
*/
|
|
375
|
-
get height() {
|
|
376
|
-
return (
|
|
377
|
-
this.trackHeightsWithResizeHandles +
|
|
378
|
-
this.headerHeight +
|
|
379
|
-
this.scaleBarHeight
|
|
380
|
-
)
|
|
381
|
-
},
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* #getter
|
|
385
|
-
*/
|
|
386
|
-
get totalBp() {
|
|
387
|
-
return self.displayedRegions.reduce((a, b) => a + b.end - b.start, 0)
|
|
388
|
-
},
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* #getter
|
|
392
|
-
*/
|
|
393
|
-
get maxBpPerPx() {
|
|
394
|
-
return this.totalBp / (self.width * 0.9)
|
|
395
|
-
},
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* #getter
|
|
399
|
-
*/
|
|
400
|
-
get minBpPerPx() {
|
|
401
|
-
return 1 / 50
|
|
402
|
-
},
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* #getter
|
|
406
|
-
*/
|
|
407
|
-
get error() {
|
|
408
|
-
return self.volatileError || this.assemblyErrors
|
|
409
|
-
},
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* #getter
|
|
413
|
-
*/
|
|
414
|
-
get maxOffset() {
|
|
415
|
-
// objectively determined to keep the linear genome on the main screen
|
|
416
|
-
const leftPadding = 10
|
|
417
|
-
return this.displayedRegionsTotalPx - leftPadding
|
|
418
|
-
},
|
|
419
|
-
|
|
420
|
-
/**
|
|
421
|
-
* #getter
|
|
422
|
-
*/
|
|
423
|
-
get minOffset() {
|
|
424
|
-
// objectively determined to keep the linear genome on the main screen
|
|
425
|
-
const rightPadding = 30
|
|
426
|
-
return -self.width + rightPadding
|
|
427
|
-
},
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
* #getter
|
|
431
|
-
*/
|
|
432
|
-
get displayedRegionsTotalPx() {
|
|
433
|
-
return this.totalBp / self.bpPerPx
|
|
434
|
-
},
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* #method
|
|
438
|
-
*/
|
|
439
|
-
renderProps() {
|
|
440
|
-
return {
|
|
441
|
-
...getParentRenderProps(self),
|
|
442
|
-
bpPerPx: self.bpPerPx,
|
|
443
|
-
highResolutionScaling: getConf(
|
|
444
|
-
getSession(self),
|
|
445
|
-
'highResolutionScaling',
|
|
446
|
-
),
|
|
447
|
-
}
|
|
448
|
-
},
|
|
449
|
-
|
|
450
|
-
/**
|
|
451
|
-
* #method
|
|
452
|
-
*/
|
|
453
|
-
searchScope(assemblyName: string) {
|
|
454
|
-
return {
|
|
455
|
-
assemblyName,
|
|
456
|
-
includeAggregateIndexes: true,
|
|
457
|
-
tracks: self.tracks,
|
|
458
|
-
}
|
|
459
|
-
},
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* #method
|
|
463
|
-
*/
|
|
464
|
-
getTrack(id: string) {
|
|
465
|
-
return self.tracks.find(t => t.configuration.trackId === id)
|
|
466
|
-
},
|
|
467
|
-
|
|
468
|
-
/**
|
|
469
|
-
* #method
|
|
470
|
-
*/
|
|
471
|
-
rankSearchResults(results: BaseResult[]) {
|
|
472
|
-
// order of rank
|
|
473
|
-
const openTrackIds = new Set(
|
|
474
|
-
self.tracks.map(track => track.configuration.trackId),
|
|
475
|
-
)
|
|
476
|
-
for (const result of results) {
|
|
477
|
-
if (openTrackIds.has(result.trackId)) {
|
|
478
|
-
result.updateScore(result.getScore() + 1)
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
return results
|
|
482
|
-
},
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* #method
|
|
486
|
-
* modifies view menu action onClick to apply to all tracks of same type
|
|
487
|
-
*/
|
|
488
|
-
rewriteOnClicks(trackType: string, viewMenuActions: MenuItem[]) {
|
|
489
|
-
viewMenuActions.forEach(action => {
|
|
490
|
-
// go to lowest level menu
|
|
491
|
-
if ('subMenu' in action) {
|
|
492
|
-
this.rewriteOnClicks(trackType, action.subMenu)
|
|
493
|
-
}
|
|
494
|
-
if ('onClick' in action) {
|
|
495
|
-
const holdOnClick = action.onClick
|
|
496
|
-
action.onClick = (...args: unknown[]) => {
|
|
497
|
-
self.tracks.forEach(track => {
|
|
498
|
-
if (track.type === trackType) {
|
|
499
|
-
holdOnClick.apply(track, [track, ...args])
|
|
500
|
-
}
|
|
501
|
-
})
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
})
|
|
505
|
-
},
|
|
506
|
-
/**
|
|
507
|
-
* #getter
|
|
508
|
-
*/
|
|
509
|
-
get trackTypeActions() {
|
|
510
|
-
const allActions: Map<string, MenuItem[]> = new Map()
|
|
511
|
-
self.tracks.forEach(track => {
|
|
512
|
-
const trackInMap = allActions.get(track.type)
|
|
513
|
-
if (!trackInMap) {
|
|
514
|
-
const viewMenuActions = clone(track.viewMenuActions)
|
|
515
|
-
this.rewriteOnClicks(track.type, viewMenuActions)
|
|
516
|
-
allActions.set(track.type, viewMenuActions)
|
|
517
|
-
}
|
|
518
|
-
})
|
|
519
|
-
|
|
520
|
-
return allActions
|
|
521
|
-
},
|
|
522
|
-
}))
|
|
523
|
-
.actions(self => ({
|
|
524
|
-
/**
|
|
525
|
-
* #action
|
|
526
|
-
*/
|
|
527
|
-
setShowCytobands(flag: boolean) {
|
|
528
|
-
self.showCytobandsSetting = flag
|
|
529
|
-
},
|
|
530
|
-
/**
|
|
531
|
-
* #action
|
|
532
|
-
*/
|
|
533
|
-
setWidth(newWidth: number) {
|
|
534
|
-
self.volatileWidth = newWidth
|
|
535
|
-
},
|
|
536
|
-
/**
|
|
537
|
-
* #action
|
|
538
|
-
*/
|
|
539
|
-
setError(error: Error | undefined) {
|
|
540
|
-
self.volatileError = error
|
|
541
|
-
},
|
|
542
|
-
/**
|
|
543
|
-
* #action
|
|
544
|
-
*/
|
|
545
|
-
toggleHeader() {
|
|
546
|
-
self.hideHeader = !self.hideHeader
|
|
547
|
-
},
|
|
548
|
-
/**
|
|
549
|
-
* #action
|
|
550
|
-
*/
|
|
551
|
-
toggleHeaderOverview() {
|
|
552
|
-
self.hideHeaderOverview = !self.hideHeaderOverview
|
|
553
|
-
},
|
|
554
|
-
/**
|
|
555
|
-
* #action
|
|
556
|
-
*/
|
|
557
|
-
toggleNoTracksActive() {
|
|
558
|
-
self.hideNoTracksActive = !self.hideNoTracksActive
|
|
559
|
-
},
|
|
560
|
-
/**
|
|
561
|
-
* #action
|
|
562
|
-
*/
|
|
563
|
-
toggleShowGridlines() {
|
|
564
|
-
self.showGridlines = !self.showGridlines
|
|
565
|
-
},
|
|
566
|
-
/**
|
|
567
|
-
* #action
|
|
568
|
-
*/
|
|
569
|
-
scrollTo(offsetPx: number) {
|
|
570
|
-
const newOffsetPx = clamp(offsetPx, self.minOffset, self.maxOffset)
|
|
571
|
-
self.offsetPx = newOffsetPx
|
|
572
|
-
return newOffsetPx
|
|
573
|
-
},
|
|
574
|
-
|
|
575
|
-
/**
|
|
576
|
-
* #action
|
|
577
|
-
*/
|
|
578
|
-
zoomTo(bpPerPx: number, offset = self.width / 2, centerAtOffset = false) {
|
|
579
|
-
const newBpPerPx = clamp(bpPerPx, self.minBpPerPx, self.maxBpPerPx)
|
|
580
|
-
if (newBpPerPx === self.bpPerPx) {
|
|
581
|
-
return newBpPerPx
|
|
582
|
-
}
|
|
583
|
-
const oldBpPerPx = self.bpPerPx
|
|
584
|
-
|
|
585
|
-
if (Math.abs(oldBpPerPx - newBpPerPx) < 0.000001) {
|
|
586
|
-
console.warn('zoomTo bpPerPx rounding error')
|
|
587
|
-
return oldBpPerPx
|
|
588
|
-
}
|
|
589
|
-
self.bpPerPx = newBpPerPx
|
|
590
|
-
|
|
591
|
-
// tweak the offset so that the center of the view remains at the same
|
|
592
|
-
// coordinate
|
|
593
|
-
this.scrollTo(
|
|
594
|
-
Math.round(
|
|
595
|
-
((self.offsetPx + offset) * oldBpPerPx) / newBpPerPx -
|
|
596
|
-
(centerAtOffset ? self.width / 2 : offset),
|
|
597
|
-
),
|
|
598
|
-
)
|
|
599
|
-
return newBpPerPx
|
|
600
|
-
},
|
|
601
|
-
|
|
602
|
-
/**
|
|
603
|
-
* #action
|
|
604
|
-
* sets offsets of rubberband, used in the get sequence dialog can call
|
|
605
|
-
* view.getSelectedRegions(view.leftOffset,view.rightOffset) to compute
|
|
606
|
-
* the selected regions from the offsets
|
|
607
|
-
*/
|
|
608
|
-
setOffsets(left?: BpOffset, right?: BpOffset) {
|
|
609
|
-
self.leftOffset = left
|
|
610
|
-
self.rightOffset = right
|
|
611
|
-
},
|
|
612
|
-
|
|
613
|
-
/**
|
|
614
|
-
* #action
|
|
615
|
-
*/
|
|
616
|
-
setSearchResults(
|
|
617
|
-
searchResults: BaseResult[],
|
|
618
|
-
searchQuery: string,
|
|
619
|
-
assemblyName?: string,
|
|
620
|
-
) {
|
|
621
|
-
getSession(self).queueDialog(handleClose => [
|
|
622
|
-
SearchResultsDialog,
|
|
623
|
-
{
|
|
624
|
-
model: self as LinearGenomeViewModel,
|
|
625
|
-
searchResults,
|
|
626
|
-
searchQuery,
|
|
627
|
-
handleClose,
|
|
628
|
-
assemblyName,
|
|
629
|
-
},
|
|
630
|
-
])
|
|
631
|
-
},
|
|
632
|
-
|
|
633
|
-
/**
|
|
634
|
-
* #action
|
|
635
|
-
*/
|
|
636
|
-
setNewView(bpPerPx: number, offsetPx: number) {
|
|
637
|
-
this.zoomTo(bpPerPx)
|
|
638
|
-
this.scrollTo(offsetPx)
|
|
639
|
-
},
|
|
640
|
-
|
|
641
|
-
/**
|
|
642
|
-
* #action
|
|
643
|
-
*/
|
|
644
|
-
horizontallyFlip() {
|
|
645
|
-
self.displayedRegions = cast(
|
|
646
|
-
[...self.displayedRegions]
|
|
647
|
-
.reverse()
|
|
648
|
-
.map(region => ({ ...region, reversed: !region.reversed })),
|
|
649
|
-
)
|
|
650
|
-
this.scrollTo(self.totalBp / self.bpPerPx - self.offsetPx - self.width)
|
|
651
|
-
},
|
|
652
|
-
|
|
653
|
-
/**
|
|
654
|
-
* #action
|
|
655
|
-
*/
|
|
656
|
-
showTrack(
|
|
657
|
-
trackId: string,
|
|
658
|
-
initialSnapshot = {},
|
|
659
|
-
displayInitialSnapshot = {},
|
|
660
|
-
) {
|
|
661
|
-
const schema = pluginManager.pluggableConfigSchemaType('track')
|
|
662
|
-
const conf = resolveIdentifier(schema, getRoot(self), trackId)
|
|
663
|
-
if (!conf) {
|
|
664
|
-
throw new Error(`Could not resolve identifier "${trackId}"`)
|
|
665
|
-
}
|
|
666
|
-
const trackType = pluginManager.getTrackType(conf?.type)
|
|
667
|
-
if (!trackType) {
|
|
668
|
-
throw new Error(`Unknown track type ${conf.type}`)
|
|
669
|
-
}
|
|
670
|
-
const viewType = pluginManager.getViewType(self.type)
|
|
671
|
-
const supportedDisplays = new Set(
|
|
672
|
-
viewType.displayTypes.map(d => d.name),
|
|
673
|
-
)
|
|
674
|
-
const displayConf = conf.displays.find((d: AnyConfigurationModel) =>
|
|
675
|
-
supportedDisplays.has(d.type),
|
|
676
|
-
)
|
|
677
|
-
if (!displayConf) {
|
|
678
|
-
throw new Error(
|
|
679
|
-
`Could not find a compatible display for view type ${self.type}`,
|
|
680
|
-
)
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
const t = self.tracks.filter(t => t.configuration === conf)
|
|
684
|
-
if (t.length === 0) {
|
|
685
|
-
const track = trackType.stateModel.create({
|
|
686
|
-
...initialSnapshot,
|
|
687
|
-
type: conf.type,
|
|
688
|
-
configuration: conf,
|
|
689
|
-
displays: [
|
|
690
|
-
{
|
|
691
|
-
type: displayConf.type,
|
|
692
|
-
configuration: displayConf,
|
|
693
|
-
...displayInitialSnapshot,
|
|
694
|
-
},
|
|
695
|
-
],
|
|
696
|
-
})
|
|
697
|
-
self.tracks.push(track)
|
|
698
|
-
return track
|
|
699
|
-
}
|
|
700
|
-
return t[0]
|
|
701
|
-
},
|
|
702
|
-
/**
|
|
703
|
-
* #action
|
|
704
|
-
*/
|
|
705
|
-
hideTrack(trackId: string) {
|
|
706
|
-
const schema = pluginManager.pluggableConfigSchemaType('track')
|
|
707
|
-
const conf = resolveIdentifier(schema, getRoot(self), trackId)
|
|
708
|
-
const t = self.tracks.filter(t => t.configuration === conf)
|
|
709
|
-
transaction(() => t.forEach(t => self.tracks.remove(t)))
|
|
710
|
-
return t.length
|
|
711
|
-
},
|
|
712
|
-
}))
|
|
713
|
-
.actions(self => ({
|
|
714
|
-
/**
|
|
715
|
-
* #action
|
|
716
|
-
*/
|
|
717
|
-
moveTrack(movingId: string, targetId: string) {
|
|
718
|
-
const oldIndex = self.tracks.findIndex(track => track.id === movingId)
|
|
719
|
-
if (oldIndex === -1) {
|
|
720
|
-
throw new Error(`Track ID ${movingId} not found`)
|
|
721
|
-
}
|
|
722
|
-
const newIndex = self.tracks.findIndex(track => track.id === targetId)
|
|
723
|
-
if (newIndex === -1) {
|
|
724
|
-
throw new Error(`Track ID ${targetId} not found`)
|
|
725
|
-
}
|
|
726
|
-
const track = getSnapshot(self.tracks[oldIndex])
|
|
727
|
-
self.tracks.splice(oldIndex, 1)
|
|
728
|
-
self.tracks.splice(newIndex, 0, track)
|
|
729
|
-
},
|
|
730
|
-
|
|
731
|
-
/**
|
|
732
|
-
* #action
|
|
733
|
-
*/
|
|
734
|
-
closeView() {
|
|
735
|
-
const parent = getContainingView(self)
|
|
736
|
-
if (parent) {
|
|
737
|
-
// I am embedded in a some other view
|
|
738
|
-
if (isViewContainer(parent)) {
|
|
739
|
-
parent.removeView(self)
|
|
740
|
-
}
|
|
741
|
-
} else {
|
|
742
|
-
// I am part of a session
|
|
743
|
-
getSession(self).removeView(self)
|
|
744
|
-
}
|
|
745
|
-
},
|
|
746
|
-
|
|
747
|
-
/**
|
|
748
|
-
* #action
|
|
749
|
-
*/
|
|
750
|
-
toggleTrack(trackId: string) {
|
|
751
|
-
// if we have any tracks with that configuration, turn them off
|
|
752
|
-
const hiddenCount = self.hideTrack(trackId)
|
|
753
|
-
// if none had that configuration, turn one on
|
|
754
|
-
if (!hiddenCount) {
|
|
755
|
-
self.showTrack(trackId)
|
|
756
|
-
}
|
|
757
|
-
},
|
|
758
|
-
|
|
759
|
-
/**
|
|
760
|
-
* #action
|
|
761
|
-
*/
|
|
762
|
-
setTrackLabels(setting: 'overlapping' | 'offset' | 'hidden') {
|
|
763
|
-
self.trackLabels = setting
|
|
764
|
-
},
|
|
765
|
-
|
|
766
|
-
/**
|
|
767
|
-
* #action
|
|
768
|
-
*/
|
|
769
|
-
toggleCenterLine() {
|
|
770
|
-
self.showCenterLine = !self.showCenterLine
|
|
771
|
-
},
|
|
772
|
-
|
|
773
|
-
/**
|
|
774
|
-
* #action
|
|
775
|
-
*/
|
|
776
|
-
setDisplayedRegions(regions: Region[]) {
|
|
777
|
-
self.displayedRegions = cast(regions)
|
|
778
|
-
self.zoomTo(self.bpPerPx)
|
|
779
|
-
},
|
|
780
|
-
|
|
781
|
-
/**
|
|
782
|
-
* #action
|
|
783
|
-
*/
|
|
784
|
-
activateTrackSelector() {
|
|
785
|
-
if (self.trackSelectorType === 'hierarchical') {
|
|
786
|
-
const session = getSession(self)
|
|
787
|
-
if (isSessionModelWithWidgets(session)) {
|
|
788
|
-
const selector = session.addWidget(
|
|
789
|
-
'HierarchicalTrackSelectorWidget',
|
|
790
|
-
'hierarchicalTrackSelector',
|
|
791
|
-
{ view: self },
|
|
792
|
-
)
|
|
793
|
-
session.showWidget(selector)
|
|
794
|
-
return selector
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
throw new Error(`invalid track selector type ${self.trackSelectorType}`)
|
|
798
|
-
},
|
|
799
|
-
|
|
800
|
-
/**
|
|
801
|
-
* #method
|
|
802
|
-
* Helper method for the fetchSequence.
|
|
803
|
-
* Retrieves the corresponding regions that were selected by the
|
|
804
|
-
* rubberband
|
|
805
|
-
*
|
|
806
|
-
* @param leftOffset - `object as {start, end, index, offset}`, offset = start
|
|
807
|
-
* of user drag
|
|
808
|
-
* @param rightOffset - `object as {start, end, index, offset}`,
|
|
809
|
-
* offset = end of user drag
|
|
810
|
-
* @returns array of Region[]
|
|
811
|
-
*/
|
|
812
|
-
getSelectedRegions(leftOffset?: BpOffset, rightOffset?: BpOffset) {
|
|
813
|
-
const snap = getSnapshot(self)
|
|
814
|
-
const simView = Base1DView.create({
|
|
815
|
-
...snap,
|
|
816
|
-
interRegionPaddingWidth: self.interRegionPaddingWidth,
|
|
817
|
-
})
|
|
818
|
-
|
|
819
|
-
simView.setVolatileWidth(self.width)
|
|
820
|
-
simView.moveTo(leftOffset, rightOffset)
|
|
821
|
-
|
|
822
|
-
return simView.dynamicBlocks.contentBlocks.map(region => ({
|
|
823
|
-
...region,
|
|
824
|
-
start: Math.floor(region.start),
|
|
825
|
-
end: Math.ceil(region.end),
|
|
826
|
-
}))
|
|
827
|
-
},
|
|
828
|
-
|
|
829
|
-
/**
|
|
830
|
-
* #action
|
|
831
|
-
* schedule something to be run after the next time displayedRegions is
|
|
832
|
-
* set
|
|
833
|
-
*/
|
|
834
|
-
afterDisplayedRegionsSet(cb: Function) {
|
|
835
|
-
self.afterDisplayedRegionsSetCallbacks.push(cb)
|
|
836
|
-
},
|
|
837
|
-
|
|
838
|
-
/**
|
|
839
|
-
* #action
|
|
840
|
-
*/
|
|
841
|
-
horizontalScroll(distance: number) {
|
|
842
|
-
const oldOffsetPx = self.offsetPx
|
|
843
|
-
// newOffsetPx is the actual offset after the scroll is clamped
|
|
844
|
-
const newOffsetPx = self.scrollTo(self.offsetPx + distance)
|
|
845
|
-
return newOffsetPx - oldOffsetPx
|
|
846
|
-
},
|
|
847
|
-
|
|
848
|
-
/**
|
|
849
|
-
* #action
|
|
850
|
-
*/
|
|
851
|
-
center() {
|
|
852
|
-
const centerBp = self.totalBp / 2
|
|
853
|
-
const centerPx = centerBp / self.bpPerPx
|
|
854
|
-
self.scrollTo(Math.round(centerPx - self.width / 2))
|
|
855
|
-
},
|
|
856
|
-
|
|
857
|
-
/**
|
|
858
|
-
* #action
|
|
859
|
-
*/
|
|
860
|
-
showAllRegions() {
|
|
861
|
-
self.zoomTo(self.maxBpPerPx)
|
|
862
|
-
this.center()
|
|
863
|
-
},
|
|
864
|
-
|
|
865
|
-
/**
|
|
866
|
-
* #action
|
|
867
|
-
*/
|
|
868
|
-
showAllRegionsInAssembly(assemblyName?: string) {
|
|
869
|
-
const session = getSession(self)
|
|
870
|
-
const { assemblyManager } = session
|
|
871
|
-
if (!assemblyName) {
|
|
872
|
-
const names = new Set(self.displayedRegions.map(r => r.assemblyName))
|
|
873
|
-
if (names.size > 1) {
|
|
874
|
-
session.notify(
|
|
875
|
-
`Can't perform operation with multiple assemblies currently`,
|
|
876
|
-
)
|
|
877
|
-
return
|
|
878
|
-
}
|
|
879
|
-
;[assemblyName] = [...names]
|
|
880
|
-
}
|
|
881
|
-
const assembly = assemblyManager.get(assemblyName)
|
|
882
|
-
if (assembly) {
|
|
883
|
-
const { regions } = assembly
|
|
884
|
-
if (regions) {
|
|
885
|
-
this.setDisplayedRegions(regions)
|
|
886
|
-
self.zoomTo(self.maxBpPerPx)
|
|
887
|
-
this.center()
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
},
|
|
891
|
-
|
|
892
|
-
/**
|
|
893
|
-
* #action
|
|
894
|
-
*/
|
|
895
|
-
setDraggingTrackId(idx?: string) {
|
|
896
|
-
self.draggingTrackId = idx
|
|
897
|
-
},
|
|
898
|
-
|
|
899
|
-
/**
|
|
900
|
-
* #action
|
|
901
|
-
*/
|
|
902
|
-
setScaleFactor(factor: number) {
|
|
903
|
-
self.scaleFactor = factor
|
|
904
|
-
},
|
|
905
|
-
|
|
906
|
-
/**
|
|
907
|
-
* #action
|
|
908
|
-
* this "clears the view" and makes the view return to the import form
|
|
909
|
-
*/
|
|
910
|
-
clearView() {
|
|
911
|
-
this.setDisplayedRegions([])
|
|
912
|
-
self.tracks.clear()
|
|
913
|
-
// it is necessary to run these after setting displayed regions empty
|
|
914
|
-
// or else model.offsetPx gets set to Infinity and breaks
|
|
915
|
-
// mobx-state-tree snapshot
|
|
916
|
-
self.scrollTo(0)
|
|
917
|
-
self.zoomTo(10)
|
|
918
|
-
},
|
|
919
|
-
|
|
920
|
-
/**
|
|
921
|
-
* #method
|
|
922
|
-
* creates an svg export and save using FileSaver
|
|
923
|
-
*/
|
|
924
|
-
async exportSvg(opts: ExportSvgOptions = {}) {
|
|
925
|
-
const { renderToSvg } = await import(
|
|
926
|
-
'./svgcomponents/SVGLinearGenomeView'
|
|
927
|
-
)
|
|
928
|
-
const html = await renderToSvg(self as LinearGenomeViewModel, opts)
|
|
929
|
-
const blob = new Blob([html], { type: 'image/svg+xml' })
|
|
930
|
-
saveAs(blob, opts.filename || 'image.svg')
|
|
931
|
-
},
|
|
932
|
-
}))
|
|
933
|
-
.actions(self => {
|
|
934
|
-
let cancelLastAnimation = () => {}
|
|
935
|
-
|
|
936
|
-
/**
|
|
937
|
-
* #action
|
|
938
|
-
* perform animated slide
|
|
939
|
-
*/
|
|
940
|
-
function slide(viewWidths: number) {
|
|
941
|
-
const [animate, cancelAnimation] = springAnimate(
|
|
942
|
-
self.offsetPx,
|
|
943
|
-
self.offsetPx + self.width * viewWidths,
|
|
944
|
-
self.scrollTo,
|
|
945
|
-
)
|
|
946
|
-
cancelLastAnimation()
|
|
947
|
-
cancelLastAnimation = cancelAnimation
|
|
948
|
-
animate()
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
return { slide }
|
|
952
|
-
})
|
|
953
|
-
.actions(self => {
|
|
954
|
-
let cancelLastAnimation = () => {}
|
|
955
|
-
|
|
956
|
-
/**
|
|
957
|
-
* #action
|
|
958
|
-
* perform animated zoom
|
|
959
|
-
*/
|
|
960
|
-
function zoom(targetBpPerPx: number) {
|
|
961
|
-
self.zoomTo(self.bpPerPx)
|
|
962
|
-
if (
|
|
963
|
-
// already zoomed all the way in
|
|
964
|
-
(targetBpPerPx < self.bpPerPx && self.bpPerPx === self.minBpPerPx) ||
|
|
965
|
-
// already zoomed all the way out
|
|
966
|
-
(targetBpPerPx > self.bpPerPx && self.bpPerPx === self.maxBpPerPx)
|
|
967
|
-
) {
|
|
968
|
-
return
|
|
969
|
-
}
|
|
970
|
-
const factor = self.bpPerPx / targetBpPerPx
|
|
971
|
-
const [animate, cancelAnimation] = springAnimate(
|
|
972
|
-
1,
|
|
973
|
-
factor,
|
|
974
|
-
self.setScaleFactor,
|
|
975
|
-
() => {
|
|
976
|
-
self.zoomTo(targetBpPerPx)
|
|
977
|
-
self.setScaleFactor(1)
|
|
978
|
-
},
|
|
979
|
-
)
|
|
980
|
-
cancelLastAnimation()
|
|
981
|
-
cancelLastAnimation = cancelAnimation
|
|
982
|
-
animate()
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
return { zoom }
|
|
986
|
-
})
|
|
987
|
-
.views(self => ({
|
|
988
|
-
/**
|
|
989
|
-
* #getter
|
|
990
|
-
*/
|
|
991
|
-
get canShowCytobands() {
|
|
992
|
-
return self.displayedRegions.length === 1 && this.anyCytobandsExist
|
|
993
|
-
},
|
|
994
|
-
/**
|
|
995
|
-
* #getter
|
|
996
|
-
*/
|
|
997
|
-
get showCytobands() {
|
|
998
|
-
return this.canShowCytobands && self.showCytobandsSetting
|
|
999
|
-
},
|
|
1000
|
-
/**
|
|
1001
|
-
* #getter
|
|
1002
|
-
*/
|
|
1003
|
-
get anyCytobandsExist() {
|
|
1004
|
-
const { assemblyManager } = getSession(self)
|
|
1005
|
-
return self.assemblyNames.some(
|
|
1006
|
-
a => assemblyManager.get(a)?.cytobands?.length,
|
|
1007
|
-
)
|
|
1008
|
-
},
|
|
1009
|
-
/**
|
|
1010
|
-
* #getter
|
|
1011
|
-
* the cytoband is displayed to the right of the chromosome name, and
|
|
1012
|
-
* that offset is calculated manually with this method
|
|
1013
|
-
*/
|
|
1014
|
-
get cytobandOffset() {
|
|
1015
|
-
return this.showCytobands
|
|
1016
|
-
? measureText(self.displayedRegions[0].refName, 12) + 15
|
|
1017
|
-
: 0
|
|
1018
|
-
},
|
|
1019
|
-
}))
|
|
1020
|
-
.views(self => ({
|
|
1021
|
-
/**
|
|
1022
|
-
* #method
|
|
1023
|
-
* return the view menu items
|
|
1024
|
-
*/
|
|
1025
|
-
menuItems(): MenuItem[] {
|
|
1026
|
-
const { canShowCytobands, showCytobands } = self
|
|
1027
|
-
const session = getSession(self)
|
|
1028
|
-
const menuItems: MenuItem[] = [
|
|
1029
|
-
{
|
|
1030
|
-
label: 'Return to import form',
|
|
1031
|
-
onClick: () => {
|
|
1032
|
-
getSession(self).queueDialog(handleClose => [
|
|
1033
|
-
ReturnToImportFormDialog,
|
|
1034
|
-
{ model: self, handleClose },
|
|
1035
|
-
])
|
|
1036
|
-
},
|
|
1037
|
-
icon: FolderOpenIcon,
|
|
1038
|
-
},
|
|
1039
|
-
...(isSessionWithAddTracks(session)
|
|
1040
|
-
? [
|
|
1041
|
-
{
|
|
1042
|
-
label: 'Sequence search',
|
|
1043
|
-
onClick: () => {
|
|
1044
|
-
getSession(self).queueDialog(handleClose => [
|
|
1045
|
-
SequenceSearchDialog,
|
|
1046
|
-
{ model: self, handleClose },
|
|
1047
|
-
])
|
|
1048
|
-
},
|
|
1049
|
-
},
|
|
1050
|
-
]
|
|
1051
|
-
: []),
|
|
1052
|
-
{
|
|
1053
|
-
label: 'Export SVG',
|
|
1054
|
-
icon: PhotoCameraIcon,
|
|
1055
|
-
onClick: () => {
|
|
1056
|
-
getSession(self).queueDialog(handleClose => [
|
|
1057
|
-
ExportSvgDialog,
|
|
1058
|
-
{ model: self, handleClose },
|
|
1059
|
-
])
|
|
1060
|
-
},
|
|
1061
|
-
},
|
|
1062
|
-
{
|
|
1063
|
-
label: 'Open track selector',
|
|
1064
|
-
onClick: self.activateTrackSelector,
|
|
1065
|
-
icon: TrackSelectorIcon,
|
|
1066
|
-
},
|
|
1067
|
-
{
|
|
1068
|
-
label: 'Horizontally flip',
|
|
1069
|
-
icon: SyncAltIcon,
|
|
1070
|
-
onClick: self.horizontallyFlip,
|
|
1071
|
-
},
|
|
1072
|
-
{
|
|
1073
|
-
label: 'Show...',
|
|
1074
|
-
icon: VisibilityIcon,
|
|
1075
|
-
subMenu: [
|
|
1076
|
-
{
|
|
1077
|
-
label: 'Show all regions in assembly',
|
|
1078
|
-
onClick: self.showAllRegionsInAssembly,
|
|
1079
|
-
},
|
|
1080
|
-
{
|
|
1081
|
-
label: 'Show center line',
|
|
1082
|
-
type: 'checkbox',
|
|
1083
|
-
checked: self.showCenterLine,
|
|
1084
|
-
onClick: self.toggleCenterLine,
|
|
1085
|
-
},
|
|
1086
|
-
{
|
|
1087
|
-
label: 'Show header',
|
|
1088
|
-
type: 'checkbox',
|
|
1089
|
-
checked: !self.hideHeader,
|
|
1090
|
-
onClick: self.toggleHeader,
|
|
1091
|
-
},
|
|
1092
|
-
{
|
|
1093
|
-
label: 'Show header overview',
|
|
1094
|
-
type: 'checkbox',
|
|
1095
|
-
checked: !self.hideHeaderOverview,
|
|
1096
|
-
onClick: self.toggleHeaderOverview,
|
|
1097
|
-
disabled: self.hideHeader,
|
|
1098
|
-
},
|
|
1099
|
-
{
|
|
1100
|
-
label: 'Show no tracks active button',
|
|
1101
|
-
type: 'checkbox',
|
|
1102
|
-
checked: !self.hideNoTracksActive,
|
|
1103
|
-
onClick: self.toggleNoTracksActive,
|
|
1104
|
-
},
|
|
1105
|
-
{
|
|
1106
|
-
label: 'Show guidelines',
|
|
1107
|
-
type: 'checkbox',
|
|
1108
|
-
checked: self.showGridlines,
|
|
1109
|
-
onClick: self.toggleShowGridlines,
|
|
1110
|
-
},
|
|
1111
|
-
...(canShowCytobands
|
|
1112
|
-
? [
|
|
1113
|
-
{
|
|
1114
|
-
label: 'Show ideogram',
|
|
1115
|
-
type: 'checkbox' as const,
|
|
1116
|
-
checked: self.showCytobands,
|
|
1117
|
-
onClick: () => self.setShowCytobands(!showCytobands),
|
|
1118
|
-
},
|
|
1119
|
-
]
|
|
1120
|
-
: []),
|
|
1121
|
-
],
|
|
1122
|
-
},
|
|
1123
|
-
{
|
|
1124
|
-
label: 'Track labels',
|
|
1125
|
-
icon: LabelIcon,
|
|
1126
|
-
subMenu: [
|
|
1127
|
-
{
|
|
1128
|
-
label: 'Overlapping',
|
|
1129
|
-
icon: VisibilityIcon,
|
|
1130
|
-
type: 'radio',
|
|
1131
|
-
checked: self.trackLabels === 'overlapping',
|
|
1132
|
-
onClick: () => self.setTrackLabels('overlapping'),
|
|
1133
|
-
},
|
|
1134
|
-
{
|
|
1135
|
-
label: 'Offset',
|
|
1136
|
-
icon: VisibilityIcon,
|
|
1137
|
-
type: 'radio',
|
|
1138
|
-
checked: self.trackLabels === 'offset',
|
|
1139
|
-
onClick: () => self.setTrackLabels('offset'),
|
|
1140
|
-
},
|
|
1141
|
-
{
|
|
1142
|
-
label: 'Hidden',
|
|
1143
|
-
icon: VisibilityIcon,
|
|
1144
|
-
type: 'radio',
|
|
1145
|
-
checked: self.trackLabels === 'hidden',
|
|
1146
|
-
onClick: () => self.setTrackLabels('hidden'),
|
|
1147
|
-
},
|
|
1148
|
-
],
|
|
1149
|
-
},
|
|
1150
|
-
]
|
|
1151
|
-
|
|
1152
|
-
// add track's view level menu options
|
|
1153
|
-
for (const [key, value] of self.trackTypeActions.entries()) {
|
|
1154
|
-
if (value.length) {
|
|
1155
|
-
menuItems.push(
|
|
1156
|
-
{ type: 'divider' },
|
|
1157
|
-
{ type: 'subHeader', label: key },
|
|
1158
|
-
)
|
|
1159
|
-
value.forEach(action => menuItems.push(action))
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
return menuItems
|
|
1164
|
-
},
|
|
1165
|
-
}))
|
|
1166
|
-
.views(self => {
|
|
1167
|
-
let currentlyCalculatedStaticBlocks: BlockSet | undefined
|
|
1168
|
-
let stringifiedCurrentlyCalculatedStaticBlocks = ''
|
|
1169
|
-
return {
|
|
1170
|
-
/**
|
|
1171
|
-
* #getter
|
|
1172
|
-
* static blocks are an important concept jbrowse uses to avoid
|
|
1173
|
-
* re-rendering when you scroll to the side. when you horizontally
|
|
1174
|
-
* scroll to the right, old blocks to the left may be removed, and new
|
|
1175
|
-
* blocks may be instantiated on the right. tracks may use the static
|
|
1176
|
-
* blocks to render their data for the region represented by the block
|
|
1177
|
-
*/
|
|
1178
|
-
get staticBlocks() {
|
|
1179
|
-
const ret = calculateStaticBlocks(self)
|
|
1180
|
-
const sret = JSON.stringify(ret)
|
|
1181
|
-
if (stringifiedCurrentlyCalculatedStaticBlocks !== sret) {
|
|
1182
|
-
currentlyCalculatedStaticBlocks = ret
|
|
1183
|
-
stringifiedCurrentlyCalculatedStaticBlocks = sret
|
|
1184
|
-
}
|
|
1185
|
-
return currentlyCalculatedStaticBlocks as BlockSet
|
|
1186
|
-
},
|
|
1187
|
-
/**
|
|
1188
|
-
* #getter
|
|
1189
|
-
* dynamic blocks represent the exact coordinates of the currently
|
|
1190
|
-
* visible genome regions on the screen. they are similar to static
|
|
1191
|
-
* blocks, but static blocks can go offscreen while dynamic blocks
|
|
1192
|
-
* represent exactly what is on screen
|
|
1193
|
-
*/
|
|
1194
|
-
get dynamicBlocks() {
|
|
1195
|
-
return calculateDynamicBlocks(self)
|
|
1196
|
-
},
|
|
1197
|
-
/**
|
|
1198
|
-
* #getter
|
|
1199
|
-
* rounded dynamic blocks are dynamic blocks without fractions of bp
|
|
1200
|
-
*/
|
|
1201
|
-
get roundedDynamicBlocks() {
|
|
1202
|
-
return this.dynamicBlocks.contentBlocks.map(
|
|
1203
|
-
block =>
|
|
1204
|
-
({
|
|
1205
|
-
...block,
|
|
1206
|
-
start: Math.floor(block.start),
|
|
1207
|
-
end: Math.ceil(block.end),
|
|
1208
|
-
} as BaseBlock),
|
|
1209
|
-
)
|
|
1210
|
-
},
|
|
1211
|
-
|
|
1212
|
-
/**
|
|
1213
|
-
* #getter
|
|
1214
|
-
* a single "combo-locstring" representing all the regions visible on
|
|
1215
|
-
* the screen
|
|
1216
|
-
*/
|
|
1217
|
-
get visibleLocStrings() {
|
|
1218
|
-
return calculateVisibleLocStrings(this.dynamicBlocks.contentBlocks)
|
|
1219
|
-
},
|
|
1220
|
-
|
|
1221
|
-
/**
|
|
1222
|
-
* #getter
|
|
1223
|
-
* same as visibleLocStrings, but only updated every 300ms
|
|
1224
|
-
*/
|
|
1225
|
-
get coarseVisibleLocStrings() {
|
|
1226
|
-
return calculateVisibleLocStrings(self.coarseDynamicBlocks)
|
|
1227
|
-
},
|
|
1228
|
-
}
|
|
1229
|
-
})
|
|
1230
|
-
.actions(self => ({
|
|
1231
|
-
/**
|
|
1232
|
-
* #action
|
|
1233
|
-
*/
|
|
1234
|
-
setCoarseDynamicBlocks(blocks: BlockSet) {
|
|
1235
|
-
self.coarseDynamicBlocks = blocks.contentBlocks
|
|
1236
|
-
self.coarseTotalBp = blocks.totalBp
|
|
1237
|
-
},
|
|
1238
|
-
|
|
1239
|
-
afterAttach() {
|
|
1240
|
-
addDisposer(
|
|
1241
|
-
self,
|
|
1242
|
-
autorun(
|
|
1243
|
-
() => {
|
|
1244
|
-
if (self.initialized) {
|
|
1245
|
-
this.setCoarseDynamicBlocks(self.dynamicBlocks)
|
|
1246
|
-
}
|
|
1247
|
-
},
|
|
1248
|
-
{ delay: 150 },
|
|
1249
|
-
),
|
|
1250
|
-
)
|
|
1251
|
-
|
|
1252
|
-
addDisposer(
|
|
1253
|
-
self,
|
|
1254
|
-
autorun(() => {
|
|
1255
|
-
const s = (s: unknown) => JSON.stringify(s)
|
|
1256
|
-
const { trackLabels, showCytobandsSetting, showCenterLine } = self
|
|
1257
|
-
if (typeof localStorage !== 'undefined') {
|
|
1258
|
-
localStorage.setItem('lgv-trackLabels', trackLabels)
|
|
1259
|
-
localStorage.setItem('lgv-showCytobands', s(showCytobandsSetting))
|
|
1260
|
-
localStorage.setItem('lgv-showCenterLine', s(showCenterLine))
|
|
1261
|
-
}
|
|
1262
|
-
}),
|
|
1263
|
-
)
|
|
1264
|
-
},
|
|
1265
|
-
}))
|
|
1266
|
-
.actions(self => ({
|
|
1267
|
-
/**
|
|
1268
|
-
* #action
|
|
1269
|
-
* offset is the base-pair-offset in the displayed region, index is the
|
|
1270
|
-
* index of the displayed region in the linear genome view
|
|
1271
|
-
*
|
|
1272
|
-
* @param start - object as `{start, end, offset, index}`
|
|
1273
|
-
* @param end - object as `{start, end, offset, index}`
|
|
1274
|
-
*/
|
|
1275
|
-
moveTo(start?: BpOffset, end?: BpOffset) {
|
|
1276
|
-
moveTo(self, start, end)
|
|
1277
|
-
},
|
|
1278
|
-
|
|
1279
|
-
/**
|
|
1280
|
-
* #action
|
|
1281
|
-
* Navigate to the given locstring, will change displayed regions if
|
|
1282
|
-
* needed, and wait for assemblies to be initialized
|
|
1283
|
-
*
|
|
1284
|
-
* @param input - e.g. "chr1:1-100", "chr1:1-100 chr2:1-100", "chr 1 100"
|
|
1285
|
-
* @param optAssemblyName - (optional) the assembly name to use when
|
|
1286
|
-
* navigating to the locstring
|
|
1287
|
-
*/
|
|
1288
|
-
async navToLocString(input: string, optAssemblyName?: string) {
|
|
1289
|
-
const { assemblyNames } = self
|
|
1290
|
-
const { assemblyManager } = getSession(self)
|
|
1291
|
-
const { isValidRefName } = assemblyManager
|
|
1292
|
-
const assemblyName = optAssemblyName || assemblyNames[0]
|
|
1293
|
-
if (assemblyName) {
|
|
1294
|
-
// wait before isValidRefName can be called
|
|
1295
|
-
await assemblyManager.waitForAssembly(assemblyName)
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
return this.navToLocations(
|
|
1299
|
-
parseLocStrings(input, assemblyName, isValidRefName),
|
|
1300
|
-
assemblyName,
|
|
1301
|
-
)
|
|
1302
|
-
},
|
|
1303
|
-
|
|
1304
|
-
/**
|
|
1305
|
-
* #action
|
|
1306
|
-
* Similar to `navToLocString`, but accepts parsed location objects
|
|
1307
|
-
* instead of strings. Will try to perform `setDisplayedRegions` if
|
|
1308
|
-
* changing regions
|
|
1309
|
-
*/
|
|
1310
|
-
async navToLocations(
|
|
1311
|
-
parsedLocStrings: ParsedLocString[],
|
|
1312
|
-
assemblyName?: string,
|
|
1313
|
-
) {
|
|
1314
|
-
const { assemblyManager } = getSession(self)
|
|
1315
|
-
await when(() => self.volatileWidth !== undefined)
|
|
1316
|
-
|
|
1317
|
-
const locations = await generateLocations(
|
|
1318
|
-
parsedLocStrings,
|
|
1319
|
-
assemblyManager,
|
|
1320
|
-
assemblyName,
|
|
1321
|
-
)
|
|
1322
|
-
|
|
1323
|
-
if (locations.length === 1) {
|
|
1324
|
-
const loc = locations[0]
|
|
1325
|
-
const { reversed, parentRegion, start, end } = loc
|
|
1326
|
-
self.setDisplayedRegions([{ reversed, ...parentRegion }])
|
|
1327
|
-
|
|
1328
|
-
this.navTo({
|
|
1329
|
-
...loc,
|
|
1330
|
-
start: clamp(start ?? 0, 0, parentRegion.end),
|
|
1331
|
-
end: clamp(end ?? parentRegion.end, 0, parentRegion.end),
|
|
1332
|
-
})
|
|
1333
|
-
} else {
|
|
1334
|
-
self.setDisplayedRegions(
|
|
1335
|
-
// @ts-expect-error
|
|
1336
|
-
locations.map(r => (r.start === undefined ? r.parentRegion : r)),
|
|
1337
|
-
)
|
|
1338
|
-
self.showAllRegions()
|
|
1339
|
-
}
|
|
1340
|
-
},
|
|
1341
|
-
|
|
1342
|
-
/**
|
|
1343
|
-
* #action
|
|
1344
|
-
* Navigate to a location based on its refName and optionally start, end,
|
|
1345
|
-
* and assemblyName. Will not try to change displayed regions, use
|
|
1346
|
-
* `navToLocations` instead. Only navigates to a location if it is
|
|
1347
|
-
* entirely within a displayedRegion. Navigates to the first matching
|
|
1348
|
-
* location encountered.
|
|
1349
|
-
*
|
|
1350
|
-
* Throws an error if navigation was unsuccessful
|
|
1351
|
-
*
|
|
1352
|
-
* @param query - a proposed location to navigate to
|
|
1353
|
-
*/
|
|
1354
|
-
navTo(query: NavLocation) {
|
|
1355
|
-
this.navToMultiple([query])
|
|
1356
|
-
},
|
|
1357
|
-
|
|
1358
|
-
/**
|
|
1359
|
-
* #action
|
|
1360
|
-
* Navigate to a location based on its refName and optionally start, end,
|
|
1361
|
-
* and assemblyName. Will not try to change displayed regions, use
|
|
1362
|
-
* navToLocations instead. Only navigates to a location if it is entirely
|
|
1363
|
-
* within a displayedRegion. Navigates to the first matching location
|
|
1364
|
-
* encountered.
|
|
1365
|
-
*
|
|
1366
|
-
* Throws an error if navigation was unsuccessful
|
|
1367
|
-
*
|
|
1368
|
-
* @param locations - proposed location to navigate to
|
|
1369
|
-
*/
|
|
1370
|
-
navToMultiple(locations: NavLocation[]) {
|
|
1371
|
-
if (
|
|
1372
|
-
locations.some(
|
|
1373
|
-
l =>
|
|
1374
|
-
l.start !== undefined && l.end !== undefined && l.start > l.end,
|
|
1375
|
-
)
|
|
1376
|
-
) {
|
|
1377
|
-
throw new Error('found start greater than end')
|
|
1378
|
-
}
|
|
1379
|
-
const f1 = locations.at(0)
|
|
1380
|
-
const f2 = locations.at(-1)
|
|
1381
|
-
if (!f1 || !f2) {
|
|
1382
|
-
return
|
|
1383
|
-
}
|
|
1384
|
-
const a = self.assemblyNames[0]
|
|
1385
|
-
const { assemblyManager } = getSession(self)
|
|
1386
|
-
const assembly1 = assemblyManager.get(f1.assemblyName || a)
|
|
1387
|
-
const assembly2 = assemblyManager.get(f2.assemblyName || a)
|
|
1388
|
-
const ref1 = assembly1?.getCanonicalRefName(f1.refName) || f1.refName
|
|
1389
|
-
const ref2 = assembly2?.getCanonicalRefName(f2.refName) || f2.refName
|
|
1390
|
-
const r1 = self.displayedRegions.find(r => r.refName === ref1)
|
|
1391
|
-
const r2 = findLast(self.displayedRegions, r => r.refName === ref2)
|
|
1392
|
-
if (!r1) {
|
|
1393
|
-
throw new Error(`could not find a region with refName "${ref1}"`)
|
|
1394
|
-
}
|
|
1395
|
-
if (!r2) {
|
|
1396
|
-
throw new Error(`could not find a region with refName "${ref2}"`)
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
const s1 = f1.start === undefined ? r1.start : f1.start
|
|
1400
|
-
const e1 = f1.end === undefined ? r1.end : f1.end
|
|
1401
|
-
const s2 = f2.start === undefined ? r2.start : f2.start
|
|
1402
|
-
const e2 = f2.end === undefined ? r2.end : f2.end
|
|
1403
|
-
|
|
1404
|
-
const index = self.displayedRegions.findIndex(
|
|
1405
|
-
r =>
|
|
1406
|
-
ref1 === r.refName &&
|
|
1407
|
-
s1 >= r.start &&
|
|
1408
|
-
s1 <= r.end &&
|
|
1409
|
-
e1 <= r.end &&
|
|
1410
|
-
e1 >= r.start,
|
|
1411
|
-
)
|
|
1412
|
-
|
|
1413
|
-
const index2 = self.displayedRegions.findIndex(
|
|
1414
|
-
r =>
|
|
1415
|
-
ref2 === r.refName &&
|
|
1416
|
-
s2 >= r.start &&
|
|
1417
|
-
s2 <= r.end &&
|
|
1418
|
-
e2 <= r.end &&
|
|
1419
|
-
e2 >= r.start,
|
|
1420
|
-
)
|
|
1421
|
-
|
|
1422
|
-
if (index === -1 || index2 === -1) {
|
|
1423
|
-
throw new Error(
|
|
1424
|
-
`could not find a region that contained "${locations.map(l =>
|
|
1425
|
-
assembleLocString(l),
|
|
1426
|
-
)}"`,
|
|
1427
|
-
)
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
const sd = self.displayedRegions[index]
|
|
1431
|
-
const ed = self.displayedRegions[index2]
|
|
1432
|
-
|
|
1433
|
-
this.moveTo(
|
|
1434
|
-
{
|
|
1435
|
-
index,
|
|
1436
|
-
offset: sd.reversed ? sd.end - e1 : s1 - sd.start,
|
|
1437
|
-
},
|
|
1438
|
-
{
|
|
1439
|
-
index: index2,
|
|
1440
|
-
offset: ed.reversed ? ed.end - s2 : e2 - ed.start,
|
|
1441
|
-
},
|
|
1442
|
-
)
|
|
1443
|
-
},
|
|
1444
|
-
}))
|
|
1445
|
-
.views(self => ({
|
|
1446
|
-
/**
|
|
1447
|
-
* #method
|
|
1448
|
-
*/
|
|
1449
|
-
rubberBandMenuItems(): MenuItem[] {
|
|
1450
|
-
return [
|
|
1451
|
-
{
|
|
1452
|
-
label: 'Zoom to region',
|
|
1453
|
-
icon: ZoomInIcon,
|
|
1454
|
-
onClick: () => self.moveTo(self.leftOffset, self.rightOffset),
|
|
1455
|
-
},
|
|
1456
|
-
{
|
|
1457
|
-
label: 'Get sequence',
|
|
1458
|
-
icon: MenuOpenIcon,
|
|
1459
|
-
onClick: () =>
|
|
1460
|
-
getSession(self).queueDialog(handleClose => [
|
|
1461
|
-
GetSequenceDialog,
|
|
1462
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1463
|
-
{ model: self as any, handleClose },
|
|
1464
|
-
]),
|
|
1465
|
-
},
|
|
1466
|
-
]
|
|
1467
|
-
},
|
|
1468
|
-
|
|
1469
|
-
/**
|
|
1470
|
-
* #method
|
|
1471
|
-
*/
|
|
1472
|
-
bpToPx({
|
|
1473
|
-
refName,
|
|
1474
|
-
coord,
|
|
1475
|
-
regionNumber,
|
|
1476
|
-
}: {
|
|
1477
|
-
refName: string
|
|
1478
|
-
coord: number
|
|
1479
|
-
regionNumber?: number
|
|
1480
|
-
}) {
|
|
1481
|
-
return bpToPx({ refName, coord, regionNumber, self })
|
|
1482
|
-
},
|
|
1483
|
-
|
|
1484
|
-
/**
|
|
1485
|
-
* #method
|
|
1486
|
-
* scrolls the view to center on the given bp. if that is not in any
|
|
1487
|
-
* of the displayed regions, does nothing
|
|
1488
|
-
* @param coord - basepair at which you want to center the view
|
|
1489
|
-
* @param refName - refName of the displayedRegion you are centering at
|
|
1490
|
-
* @param regionNumber - index of the displayedRegion
|
|
1491
|
-
*/
|
|
1492
|
-
centerAt(coord: number, refName: string, regionNumber: number) {
|
|
1493
|
-
const centerPx = this.bpToPx({
|
|
1494
|
-
refName,
|
|
1495
|
-
coord,
|
|
1496
|
-
regionNumber,
|
|
1497
|
-
})
|
|
1498
|
-
if (centerPx !== undefined) {
|
|
1499
|
-
self.scrollTo(Math.round(centerPx.offsetPx - self.width / 2))
|
|
1500
|
-
}
|
|
1501
|
-
},
|
|
1502
|
-
|
|
1503
|
-
/**
|
|
1504
|
-
* #method
|
|
1505
|
-
*/
|
|
1506
|
-
pxToBp(px: number) {
|
|
1507
|
-
return pxToBp(self, px)
|
|
1508
|
-
},
|
|
1509
|
-
|
|
1510
|
-
/**
|
|
1511
|
-
* #getter
|
|
1512
|
-
*/
|
|
1513
|
-
get centerLineInfo() {
|
|
1514
|
-
return self.displayedRegions.length > 0
|
|
1515
|
-
? this.pxToBp(self.width / 2)
|
|
1516
|
-
: undefined
|
|
1517
|
-
},
|
|
1518
|
-
}))
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
|
-
export type LinearGenomeViewStateModel = ReturnType<typeof stateModelFactory>
|
|
1522
|
-
export type LinearGenomeViewModel = Instance<LinearGenomeViewStateModel>
|
|
1523
|
-
|
|
1524
|
-
export {
|
|
1525
|
-
default as ReactComponent,
|
|
1526
|
-
default as LinearGenomeView,
|
|
1527
|
-
} from './components/LinearGenomeView'
|
|
1528
|
-
|
|
1529
|
-
export { default as RefNameAutocomplete } from './components/RefNameAutocomplete'
|
|
1530
|
-
export { default as SearchBox } from './components/SearchBox'
|
|
1531
|
-
export { default as ZoomControls } from './components/ZoomControls'
|
|
1532
|
-
|
|
1533
|
-
export { renderToSvg } from './svgcomponents/SVGLinearGenomeView'
|