@jbrowse/plugin-linear-genome-view 2.2.1 → 2.2.2
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/models/serverSideRenderedBlock.js +1 -1
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
- package/dist/LaunchLinearGenomeView/index.d.ts +3 -0
- package/dist/LaunchLinearGenomeView/index.js +44 -0
- package/dist/LaunchLinearGenomeView/index.js.map +1 -0
- package/dist/LinearBareDisplay/index.d.ts +6 -2
- package/dist/LinearBareDisplay/index.js +17 -2
- package/dist/LinearBareDisplay/index.js.map +1 -1
- package/dist/LinearBasicDisplay/components/SetMaxHeight.js +2 -15
- package/dist/LinearBasicDisplay/components/SetMaxHeight.js.map +1 -1
- package/dist/LinearBasicDisplay/index.d.ts +6 -2
- package/dist/LinearBasicDisplay/index.js +20 -4
- package/dist/LinearBasicDisplay/index.js.map +1 -1
- package/dist/LinearBasicDisplay/model.d.ts +19 -12
- package/dist/LinearBasicDisplay/model.js +2 -1
- package/dist/LinearBasicDisplay/model.js.map +1 -1
- package/dist/LinearGenomeView/components/ExportSvgDialog.js +1 -19
- package/dist/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
- package/dist/LinearGenomeView/components/GetSequenceDialog.js +7 -18
- package/dist/LinearGenomeView/components/GetSequenceDialog.js.map +1 -1
- package/dist/LinearGenomeView/components/Header.js +2 -2
- package/dist/LinearGenomeView/components/HelpDialog.js +2 -17
- package/dist/LinearGenomeView/components/HelpDialog.js.map +1 -1
- package/dist/LinearGenomeView/components/ImportForm.js +10 -9
- package/dist/LinearGenomeView/components/ImportForm.js.map +1 -1
- package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js +5 -5
- package/dist/LinearGenomeView/components/{OverviewRubberBand.d.ts → OverviewRubberband.d.ts} +2 -2
- package/dist/LinearGenomeView/components/{OverviewRubberBand.js → OverviewRubberband.js} +27 -79
- package/dist/LinearGenomeView/components/OverviewRubberband.js.map +1 -0
- package/{esm/LinearGenomeView/components/OverviewScaleBar.d.ts → dist/LinearGenomeView/components/OverviewScalebar.d.ts} +2 -2
- package/dist/LinearGenomeView/components/{OverviewScaleBar.js → OverviewScalebar.js} +25 -24
- package/dist/LinearGenomeView/components/OverviewScalebar.js.map +1 -0
- package/dist/LinearGenomeView/components/RefNameAutocomplete.js +1 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
- package/dist/LinearGenomeView/components/{RubberBand.d.ts → Rubberband.d.ts} +2 -2
- package/dist/LinearGenomeView/components/Rubberband.js +57 -0
- package/dist/LinearGenomeView/components/Rubberband.js.map +1 -0
- package/dist/LinearGenomeView/components/RubberbandSpan.d.ts +14 -0
- package/dist/LinearGenomeView/components/RubberbandSpan.js +90 -0
- package/dist/LinearGenomeView/components/RubberbandSpan.js.map +1 -0
- package/dist/LinearGenomeView/components/{ScaleBar.d.ts → Scalebar.d.ts} +2 -2
- package/dist/LinearGenomeView/components/{ScaleBar.js → Scalebar.js} +11 -11
- package/dist/LinearGenomeView/components/{ScaleBar.js.map → Scalebar.js.map} +1 -1
- package/dist/LinearGenomeView/components/SearchBox.js +6 -6
- package/dist/LinearGenomeView/components/SearchBox.js.map +1 -1
- package/dist/LinearGenomeView/components/SearchResultsDialog.js +17 -31
- package/dist/LinearGenomeView/components/SearchResultsDialog.js.map +1 -1
- package/dist/LinearGenomeView/components/SequenceSearchDialog.js +4 -19
- package/dist/LinearGenomeView/components/SequenceSearchDialog.js.map +1 -1
- package/dist/LinearGenomeView/components/TrackContainer.js +2 -2
- package/dist/LinearGenomeView/components/TrackContainer.js.map +1 -1
- package/dist/LinearGenomeView/components/TracksContainer.js +21 -118
- package/dist/LinearGenomeView/components/TracksContainer.js.map +1 -1
- package/dist/LinearGenomeView/components/VerticalGuide.d.ts +9 -0
- package/dist/LinearGenomeView/components/VerticalGuide.js +29 -0
- package/dist/LinearGenomeView/components/VerticalGuide.js.map +1 -0
- package/dist/LinearGenomeView/components/hooks.d.ts +65 -0
- package/dist/LinearGenomeView/components/hooks.js +264 -0
- package/dist/LinearGenomeView/components/hooks.js.map +1 -0
- package/dist/LinearGenomeView/components/util.d.ts +5 -2
- package/dist/LinearGenomeView/components/util.js +7 -6
- package/dist/LinearGenomeView/components/util.js.map +1 -1
- package/dist/LinearGenomeView/index.d.ts +3 -534
- package/dist/LinearGenomeView/index.js +11 -1327
- package/dist/LinearGenomeView/index.js.map +1 -1
- package/dist/LinearGenomeView/model.d.ts +535 -0
- package/dist/LinearGenomeView/model.js +1357 -0
- package/dist/LinearGenomeView/model.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -72
- package/dist/index.js.map +1 -1
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +1 -1
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
- package/esm/LaunchLinearGenomeView/index.d.ts +3 -0
- package/esm/LaunchLinearGenomeView/index.js +42 -0
- package/esm/LaunchLinearGenomeView/index.js.map +1 -0
- package/esm/LinearBareDisplay/index.d.ts +6 -2
- package/esm/LinearBareDisplay/index.js +18 -2
- package/esm/LinearBareDisplay/index.js.map +1 -1
- package/esm/LinearBasicDisplay/components/SetMaxHeight.js +3 -13
- package/esm/LinearBasicDisplay/components/SetMaxHeight.js.map +1 -1
- package/esm/LinearBasicDisplay/index.d.ts +6 -2
- package/esm/LinearBasicDisplay/index.js +19 -2
- package/esm/LinearBasicDisplay/index.js.map +1 -1
- package/esm/LinearBasicDisplay/model.d.ts +19 -12
- package/esm/LinearBasicDisplay/model.js +2 -1
- package/esm/LinearBasicDisplay/model.js.map +1 -1
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +3 -18
- package/esm/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
- package/esm/LinearGenomeView/components/GetSequenceDialog.js +8 -19
- package/esm/LinearGenomeView/components/GetSequenceDialog.js.map +1 -1
- package/esm/LinearGenomeView/components/Header.js +2 -2
- package/esm/LinearGenomeView/components/HelpDialog.js +3 -18
- package/esm/LinearGenomeView/components/HelpDialog.js.map +1 -1
- package/esm/LinearGenomeView/components/ImportForm.js +10 -9
- package/esm/LinearGenomeView/components/ImportForm.js.map +1 -1
- package/esm/LinearGenomeView/components/LinearGenomeViewSvg.js +3 -3
- package/esm/LinearGenomeView/components/{OverviewRubberBand.d.ts → OverviewRubberband.d.ts} +2 -2
- package/esm/LinearGenomeView/components/{OverviewRubberBand.js → OverviewRubberband.js} +25 -80
- package/esm/LinearGenomeView/components/OverviewRubberband.js.map +1 -0
- package/{dist/LinearGenomeView/components/OverviewScaleBar.d.ts → esm/LinearGenomeView/components/OverviewScalebar.d.ts} +2 -2
- package/esm/LinearGenomeView/components/{OverviewScaleBar.js → OverviewScalebar.js} +25 -24
- package/esm/LinearGenomeView/components/OverviewScalebar.js.map +1 -0
- package/esm/LinearGenomeView/components/RefNameAutocomplete.js +1 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
- package/esm/LinearGenomeView/components/{RubberBand.d.ts → Rubberband.d.ts} +2 -2
- package/esm/LinearGenomeView/components/Rubberband.js +29 -0
- package/esm/LinearGenomeView/components/Rubberband.js.map +1 -0
- package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +14 -0
- package/esm/LinearGenomeView/components/RubberbandSpan.js +65 -0
- package/esm/LinearGenomeView/components/RubberbandSpan.js.map +1 -0
- package/esm/LinearGenomeView/components/{ScaleBar.d.ts → Scalebar.d.ts} +2 -2
- package/esm/LinearGenomeView/components/{ScaleBar.js → Scalebar.js} +11 -11
- package/esm/LinearGenomeView/components/{ScaleBar.js.map → Scalebar.js.map} +1 -1
- package/esm/LinearGenomeView/components/SearchBox.js +6 -6
- package/esm/LinearGenomeView/components/SearchBox.js.map +1 -1
- package/esm/LinearGenomeView/components/SearchResultsDialog.js +18 -32
- package/esm/LinearGenomeView/components/SearchResultsDialog.js.map +1 -1
- package/esm/LinearGenomeView/components/SequenceSearchDialog.js +5 -17
- package/esm/LinearGenomeView/components/SequenceSearchDialog.js.map +1 -1
- package/esm/LinearGenomeView/components/TrackContainer.js +2 -2
- package/esm/LinearGenomeView/components/TrackContainer.js.map +1 -1
- package/esm/LinearGenomeView/components/TracksContainer.js +22 -119
- package/esm/LinearGenomeView/components/TracksContainer.js.map +1 -1
- package/esm/LinearGenomeView/components/VerticalGuide.d.ts +9 -0
- package/esm/LinearGenomeView/components/VerticalGuide.js +24 -0
- package/esm/LinearGenomeView/components/VerticalGuide.js.map +1 -0
- package/esm/LinearGenomeView/components/hooks.d.ts +65 -0
- package/esm/LinearGenomeView/components/hooks.js +255 -0
- package/esm/LinearGenomeView/components/hooks.js.map +1 -0
- package/esm/LinearGenomeView/components/util.d.ts +5 -2
- package/esm/LinearGenomeView/components/util.js +4 -3
- package/esm/LinearGenomeView/components/util.js.map +1 -1
- package/esm/LinearGenomeView/index.d.ts +3 -534
- package/esm/LinearGenomeView/index.js +9 -1318
- package/esm/LinearGenomeView/index.js.map +1 -1
- package/esm/LinearGenomeView/model.d.ts +535 -0
- package/esm/LinearGenomeView/model.js +1322 -0
- package/esm/LinearGenomeView/model.js.map +1 -0
- package/esm/index.d.ts +2 -2
- package/esm/index.js +9 -72
- package/esm/index.js.map +1 -1
- package/package.json +3 -3
- package/src/BaseLinearDisplay/models/serverSideRenderedBlock.ts +1 -1
- package/src/LaunchLinearGenomeView/index.ts +66 -0
- package/src/LinearBareDisplay/index.ts +21 -2
- package/src/LinearBasicDisplay/components/SetMaxHeight.tsx +3 -28
- package/src/LinearBasicDisplay/index.ts +23 -2
- package/src/LinearBasicDisplay/model.ts +2 -1
- package/src/LinearGenomeView/components/ExportSvgDialog.tsx +2 -23
- package/src/LinearGenomeView/components/GetSequenceDialog.tsx +13 -31
- package/src/LinearGenomeView/components/Header.tsx +3 -3
- package/src/LinearGenomeView/components/HelpDialog.tsx +8 -34
- package/src/LinearGenomeView/components/ImportForm.tsx +10 -9
- package/src/LinearGenomeView/components/LinearGenomeViewSvg.tsx +3 -3
- package/src/LinearGenomeView/components/{OverviewRubberBand.tsx → OverviewRubberband.tsx} +32 -114
- package/src/LinearGenomeView/components/{OverviewScaleBar.tsx → OverviewScalebar.tsx} +26 -25
- package/src/LinearGenomeView/components/RefNameAutocomplete.tsx +2 -1
- package/src/LinearGenomeView/components/Rubberband.tsx +89 -0
- package/src/LinearGenomeView/components/RubberbandSpan.tsx +116 -0
- package/src/LinearGenomeView/components/{ScaleBar.test.tsx → Scalebar.test.tsx} +5 -5
- package/src/LinearGenomeView/components/{ScaleBar.tsx → Scalebar.tsx} +11 -11
- package/src/LinearGenomeView/components/SearchBox.tsx +6 -6
- package/src/LinearGenomeView/components/SearchResultsDialog.tsx +17 -44
- package/src/LinearGenomeView/components/SequenceSearchDialog.tsx +4 -30
- package/src/LinearGenomeView/components/TrackContainer.tsx +4 -2
- package/src/LinearGenomeView/components/TracksContainer.tsx +59 -136
- package/src/LinearGenomeView/components/VerticalGuide.tsx +37 -0
- package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.tsx.snap +37 -39
- package/src/LinearGenomeView/components/hooks.ts +300 -0
- package/src/LinearGenomeView/components/util.ts +8 -11
- package/src/LinearGenomeView/index.test.ts +6 -7
- package/src/LinearGenomeView/index.ts +17 -0
- package/src/LinearGenomeView/{index.tsx → model.ts} +7 -4
- package/src/index.ts +13 -108
- package/dist/LinearGenomeView/components/OverviewRubberBand.js.map +0 -1
- package/dist/LinearGenomeView/components/OverviewScaleBar.js.map +0 -1
- package/dist/LinearGenomeView/components/RubberBand.js +0 -221
- package/dist/LinearGenomeView/components/RubberBand.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/RubberBand.js +0 -196
- package/esm/LinearGenomeView/components/RubberBand.js.map +0 -1
- package/src/LinearGenomeView/components/RubberBand.tsx +0 -308
|
@@ -62,11 +62,11 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
62
62
|
setValue(r0)
|
|
63
63
|
}, [r0, selectedAsm])
|
|
64
64
|
|
|
65
|
-
function navToOption(option: BaseResult) {
|
|
65
|
+
async function navToOption(option: BaseResult) {
|
|
66
66
|
const location = option.getLocation()
|
|
67
67
|
const trackId = option.getTrackId()
|
|
68
68
|
if (location) {
|
|
69
|
-
model.navToLocString(location, selectedAsm)
|
|
69
|
+
await model.navToLocString(location, selectedAsm)
|
|
70
70
|
if (trackId) {
|
|
71
71
|
model.showTrack(trackId)
|
|
72
72
|
}
|
|
@@ -81,7 +81,7 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
81
81
|
async function handleSelectedRegion(input: string) {
|
|
82
82
|
try {
|
|
83
83
|
if (option?.getDisplayString() === input && option.hasLocation()) {
|
|
84
|
-
navToOption(option)
|
|
84
|
+
await navToOption(option)
|
|
85
85
|
} else {
|
|
86
86
|
const [ref, rest] = splitLast(input, ':')
|
|
87
87
|
const allRefs = assembly?.allRefNamesWithLowerCase || []
|
|
@@ -89,7 +89,7 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
89
89
|
allRefs.includes(input) ||
|
|
90
90
|
(allRefs.includes(ref) && !Number.isNaN(parseInt(rest, 10)))
|
|
91
91
|
) {
|
|
92
|
-
model.navToLocString(input, selectedAsm)
|
|
92
|
+
await model.navToLocString(input, selectedAsm)
|
|
93
93
|
} else {
|
|
94
94
|
const results = await fetchResults({
|
|
95
95
|
queryString: input,
|
|
@@ -103,9 +103,9 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
103
103
|
if (results.length > 1) {
|
|
104
104
|
model.setSearchResults(results, input.toLowerCase())
|
|
105
105
|
} else if (results.length === 1) {
|
|
106
|
-
navToOption(results[0])
|
|
106
|
+
await navToOption(results[0])
|
|
107
107
|
} else {
|
|
108
|
-
model.navToLocString(input, selectedAsm)
|
|
108
|
+
await model.navToLocString(input, selectedAsm)
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
}
|
|
@@ -122,11 +122,12 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
122
122
|
{displayError ? <ErrorMessage error={displayError} /> : null}
|
|
123
123
|
<Container className={classes.importFormContainer}>
|
|
124
124
|
<form
|
|
125
|
-
onSubmit={event => {
|
|
125
|
+
onSubmit={async event => {
|
|
126
126
|
event.preventDefault()
|
|
127
127
|
model.setError(undefined)
|
|
128
128
|
if (value) {
|
|
129
|
-
|
|
129
|
+
// has it's own error handling
|
|
130
|
+
await handleSelectedRegion(value)
|
|
130
131
|
}
|
|
131
132
|
}}
|
|
132
133
|
>
|
|
@@ -167,7 +168,7 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
167
168
|
model={model}
|
|
168
169
|
assemblyName={assemblyError ? undefined : selectedAsm}
|
|
169
170
|
value={value}
|
|
170
|
-
// note: minWidth 270
|
|
171
|
+
// note: minWidth 270 accommodates full width of helperText
|
|
171
172
|
minWidth={270}
|
|
172
173
|
onChange={str => setValue(str)}
|
|
173
174
|
onSelect={val => setOption(val)}
|
|
@@ -14,11 +14,11 @@ import {
|
|
|
14
14
|
ExportSvgOptions,
|
|
15
15
|
HEADER_OVERVIEW_HEIGHT,
|
|
16
16
|
} from '..'
|
|
17
|
-
import { Polygon, Cytobands } from './
|
|
17
|
+
import { Polygon, Cytobands } from './OverviewScalebar'
|
|
18
18
|
|
|
19
19
|
type LGV = LinearGenomeViewModel
|
|
20
20
|
|
|
21
|
-
function
|
|
21
|
+
function Scalebar({ model, fontSize }: { model: LGV; fontSize: number }) {
|
|
22
22
|
const {
|
|
23
23
|
offsetPx,
|
|
24
24
|
dynamicBlocks: { totalWidthPxWithoutBorders: totalWidthPx, totalBp },
|
|
@@ -178,7 +178,7 @@ const SVGHeader = ({ model }: { model: LGV }) => {
|
|
|
178
178
|
) : null}
|
|
179
179
|
|
|
180
180
|
<g transform={`translate(0 ${fontSize + cytobandHeight})`}>
|
|
181
|
-
<
|
|
181
|
+
<Scalebar model={model} fontSize={fontSize} />
|
|
182
182
|
</g>
|
|
183
183
|
<g transform={`translate(0 ${rulerHeight + cytobandHeight})`}>
|
|
184
184
|
<SVGRuler model={model} fontSize={fontSize} width={width} />
|
|
@@ -1,51 +1,28 @@
|
|
|
1
1
|
import React, { useRef, useEffect, useState } from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import { Tooltip } from '@mui/material'
|
|
3
3
|
import { makeStyles } from 'tss-react/mui'
|
|
4
4
|
import { getSession, stringify } from '@jbrowse/core/util'
|
|
5
5
|
import { observer } from 'mobx-react'
|
|
6
6
|
import { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel'
|
|
7
|
-
import { LinearGenomeViewModel
|
|
7
|
+
import { LinearGenomeViewModel } from '..'
|
|
8
|
+
import RubberbandSpan from './RubberbandSpan'
|
|
9
|
+
import { getRelativeX } from './util'
|
|
8
10
|
|
|
9
11
|
type LGV = LinearGenomeViewModel
|
|
10
12
|
|
|
11
|
-
const useStyles = makeStyles()(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
},
|
|
25
|
-
rubberBandControl: {
|
|
26
|
-
cursor: 'crosshair',
|
|
27
|
-
width: '100%',
|
|
28
|
-
minHeight: 8,
|
|
29
|
-
},
|
|
30
|
-
rubberBandText: {
|
|
31
|
-
color: tertiary ? tertiary.contrastText : primary.contrastText,
|
|
32
|
-
},
|
|
33
|
-
popover: {
|
|
34
|
-
mouseEvents: 'none',
|
|
35
|
-
cursor: 'crosshair',
|
|
36
|
-
},
|
|
37
|
-
paper: {
|
|
38
|
-
paddingLeft: theme.spacing(1),
|
|
39
|
-
paddingRight: theme.spacing(1),
|
|
40
|
-
},
|
|
41
|
-
guide: {
|
|
42
|
-
pointerEvents: 'none',
|
|
43
|
-
height: '100%',
|
|
44
|
-
width: 1,
|
|
45
|
-
position: 'absolute',
|
|
46
|
-
zIndex: 10,
|
|
47
|
-
},
|
|
48
|
-
}
|
|
13
|
+
const useStyles = makeStyles()({
|
|
14
|
+
rubberbandControl: {
|
|
15
|
+
cursor: 'crosshair',
|
|
16
|
+
width: '100%',
|
|
17
|
+
minHeight: 8,
|
|
18
|
+
},
|
|
19
|
+
guide: {
|
|
20
|
+
pointerEvents: 'none',
|
|
21
|
+
height: '100%',
|
|
22
|
+
width: 1,
|
|
23
|
+
position: 'absolute',
|
|
24
|
+
zIndex: 10,
|
|
25
|
+
},
|
|
49
26
|
})
|
|
50
27
|
|
|
51
28
|
const HoverTooltip = observer(
|
|
@@ -91,7 +68,7 @@ const HoverTooltip = observer(
|
|
|
91
68
|
},
|
|
92
69
|
)
|
|
93
70
|
|
|
94
|
-
function
|
|
71
|
+
function OverviewRubberband({
|
|
95
72
|
model,
|
|
96
73
|
overview,
|
|
97
74
|
ControlComponent = <div />,
|
|
@@ -105,7 +82,6 @@ function OverviewRubberBand({
|
|
|
105
82
|
const [currentX, setCurrentX] = useState<number>()
|
|
106
83
|
const [guideX, setGuideX] = useState<number>()
|
|
107
84
|
const controlsRef = useRef<HTMLDivElement>(null)
|
|
108
|
-
const rubberBandRef = useRef<HTMLDivElement>(null)
|
|
109
85
|
const { classes } = useStyles()
|
|
110
86
|
const mouseDragging = startX !== undefined
|
|
111
87
|
|
|
@@ -113,8 +89,7 @@ function OverviewRubberBand({
|
|
|
113
89
|
function globalMouseMove(event: MouseEvent) {
|
|
114
90
|
const ref = controlsRef.current
|
|
115
91
|
if (ref && mouseDragging) {
|
|
116
|
-
|
|
117
|
-
setCurrentX(relativeX)
|
|
92
|
+
setCurrentX(getRelativeX(event, ref))
|
|
118
93
|
}
|
|
119
94
|
}
|
|
120
95
|
|
|
@@ -172,19 +147,11 @@ function OverviewRubberBand({
|
|
|
172
147
|
function mouseDown(event: React.MouseEvent<HTMLDivElement>) {
|
|
173
148
|
event.preventDefault()
|
|
174
149
|
event.stopPropagation()
|
|
175
|
-
|
|
176
|
-
setStartX(
|
|
177
|
-
event.clientX - controlsRef.current.getBoundingClientRect().left,
|
|
178
|
-
)
|
|
179
|
-
}
|
|
150
|
+
setStartX(getRelativeX(event, controlsRef.current))
|
|
180
151
|
}
|
|
181
152
|
|
|
182
153
|
function mouseMove(event: React.MouseEvent<HTMLDivElement>) {
|
|
183
|
-
|
|
184
|
-
setGuideX(
|
|
185
|
-
event.clientX - controlsRef.current.getBoundingClientRect().left,
|
|
186
|
-
)
|
|
187
|
-
}
|
|
154
|
+
setGuideX(getRelativeX(event, controlsRef.current))
|
|
188
155
|
}
|
|
189
156
|
|
|
190
157
|
function mouseOut() {
|
|
@@ -203,7 +170,7 @@ function OverviewRubberBand({
|
|
|
203
170
|
/>
|
|
204
171
|
) : null}
|
|
205
172
|
<div
|
|
206
|
-
className={classes.
|
|
173
|
+
className={classes.rubberbandControl}
|
|
207
174
|
role="presentation"
|
|
208
175
|
ref={controlsRef}
|
|
209
176
|
onMouseDown={mouseDown}
|
|
@@ -235,66 +202,17 @@ function OverviewRubberBand({
|
|
|
235
202
|
|
|
236
203
|
return (
|
|
237
204
|
<div style={{ position: 'relative' }}>
|
|
238
|
-
{
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
open
|
|
246
|
-
anchorEl={rubberBandRef.current}
|
|
247
|
-
anchorOrigin={{
|
|
248
|
-
vertical: 'top',
|
|
249
|
-
horizontal: 'left',
|
|
250
|
-
}}
|
|
251
|
-
transformOrigin={{
|
|
252
|
-
vertical: 'bottom',
|
|
253
|
-
horizontal: 'right',
|
|
254
|
-
}}
|
|
255
|
-
keepMounted
|
|
256
|
-
disableRestoreFocus
|
|
257
|
-
>
|
|
258
|
-
<Typography>
|
|
259
|
-
{leftBpOffset ? stringify(leftBpOffset) : ''}
|
|
260
|
-
</Typography>
|
|
261
|
-
</Popover>
|
|
262
|
-
<Popover
|
|
263
|
-
className={classes.popover}
|
|
264
|
-
classes={{
|
|
265
|
-
paper: classes.paper,
|
|
266
|
-
}}
|
|
267
|
-
open
|
|
268
|
-
anchorEl={rubberBandRef.current}
|
|
269
|
-
anchorOrigin={{
|
|
270
|
-
vertical: 'top',
|
|
271
|
-
horizontal: 'right',
|
|
272
|
-
}}
|
|
273
|
-
transformOrigin={{
|
|
274
|
-
vertical: 'bottom',
|
|
275
|
-
horizontal: 'left',
|
|
276
|
-
}}
|
|
277
|
-
keepMounted
|
|
278
|
-
disableRestoreFocus
|
|
279
|
-
>
|
|
280
|
-
<Typography>
|
|
281
|
-
{rightBpOffset ? stringify(rightBpOffset) : ''}
|
|
282
|
-
</Typography>
|
|
283
|
-
</Popover>
|
|
284
|
-
</>
|
|
205
|
+
{leftBpOffset && rightBpOffset ? (
|
|
206
|
+
<RubberbandSpan
|
|
207
|
+
leftBpOffset={leftBpOffset}
|
|
208
|
+
rightBpOffset={rightBpOffset}
|
|
209
|
+
width={width}
|
|
210
|
+
left={left}
|
|
211
|
+
/>
|
|
285
212
|
) : null}
|
|
286
213
|
<div
|
|
287
|
-
|
|
288
|
-
className={classes.
|
|
289
|
-
style={{
|
|
290
|
-
left,
|
|
291
|
-
width: Math.abs(width),
|
|
292
|
-
height: HEADER_OVERVIEW_HEIGHT,
|
|
293
|
-
}}
|
|
294
|
-
/>
|
|
295
|
-
<div
|
|
296
|
-
data-testid="rubberBand_controls"
|
|
297
|
-
className={classes.rubberBandControl}
|
|
214
|
+
data-testid="rubberband_controls"
|
|
215
|
+
className={classes.rubberbandControl}
|
|
298
216
|
role="presentation"
|
|
299
217
|
ref={controlsRef}
|
|
300
218
|
onMouseDown={mouseDown}
|
|
@@ -307,4 +225,4 @@ function OverviewRubberBand({
|
|
|
307
225
|
)
|
|
308
226
|
}
|
|
309
227
|
|
|
310
|
-
export default observer(
|
|
228
|
+
export default observer(OverviewRubberband)
|
|
@@ -3,6 +3,7 @@ import { Typography, useTheme, alpha } from '@mui/material'
|
|
|
3
3
|
import { makeStyles } from 'tss-react/mui'
|
|
4
4
|
import { observer } from 'mobx-react'
|
|
5
5
|
|
|
6
|
+
// core
|
|
6
7
|
import Base1DView, { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel'
|
|
7
8
|
import { getSession, getTickDisplayStr } from '@jbrowse/core/util'
|
|
8
9
|
import { ContentBlock } from '@jbrowse/core/util/blockTypes'
|
|
@@ -15,46 +16,46 @@ import {
|
|
|
15
16
|
HEADER_OVERVIEW_HEIGHT,
|
|
16
17
|
} from '..'
|
|
17
18
|
import { chooseGridPitch } from '../util'
|
|
18
|
-
import
|
|
19
|
+
import OverviewRubberband from './OverviewRubberband'
|
|
19
20
|
|
|
20
21
|
const wholeSeqSpacer = 2
|
|
21
22
|
|
|
22
23
|
const useStyles = makeStyles()(theme => ({
|
|
23
|
-
|
|
24
|
+
scalebar: {
|
|
24
25
|
height: HEADER_OVERVIEW_HEIGHT,
|
|
25
26
|
},
|
|
26
|
-
|
|
27
|
+
scalebarBorder: {
|
|
27
28
|
border: '1px solid',
|
|
28
29
|
},
|
|
29
|
-
|
|
30
|
+
scalebarContig: {
|
|
30
31
|
backgroundColor: theme.palette.background.default,
|
|
31
32
|
position: 'absolute',
|
|
32
33
|
top: 0,
|
|
33
34
|
height: HEADER_OVERVIEW_HEIGHT,
|
|
34
35
|
},
|
|
35
|
-
|
|
36
|
+
scalebarContigForward: {
|
|
36
37
|
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 9'%3E%3Cpath d='M-.1 0L6 4.5L-.1 9' fill='none' stroke='%23ddd'/%3E%3C/svg%3E")`,
|
|
37
38
|
backgroundRepeat: 'repeat',
|
|
38
39
|
},
|
|
39
|
-
|
|
40
|
+
scalebarContigReverse: {
|
|
40
41
|
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 9'%3E%3Cpath d='M6 0L0 4.5L6 9' fill='none' stroke='%23ddd'/%3E%3C/svg%3E")`,
|
|
41
42
|
backgroundRepeat: 'repeat',
|
|
42
43
|
},
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
scalebarRefName: {
|
|
45
46
|
position: 'absolute',
|
|
46
47
|
fontWeight: 'bold',
|
|
47
48
|
pointerEvents: 'none',
|
|
48
49
|
zIndex: 100,
|
|
49
50
|
},
|
|
50
|
-
|
|
51
|
+
scalebarLabel: {
|
|
51
52
|
height: HEADER_OVERVIEW_HEIGHT,
|
|
52
53
|
position: 'absolute',
|
|
53
54
|
display: 'flex',
|
|
54
55
|
justifyContent: 'center',
|
|
55
56
|
pointerEvents: 'none',
|
|
56
57
|
},
|
|
57
|
-
|
|
58
|
+
scalebarVisibleRegion: {
|
|
58
59
|
position: 'absolute',
|
|
59
60
|
height: HEADER_OVERVIEW_HEIGHT,
|
|
60
61
|
pointerEvents: 'none',
|
|
@@ -328,19 +329,19 @@ const OverviewBox = observer(
|
|
|
328
329
|
left: block.offsetPx + 3,
|
|
329
330
|
color: canDisplayCytobands ? 'black' : refNameColor,
|
|
330
331
|
}}
|
|
331
|
-
className={classes.
|
|
332
|
+
className={classes.scalebarRefName}
|
|
332
333
|
>
|
|
333
334
|
{refName}
|
|
334
335
|
</Typography>
|
|
335
336
|
<div
|
|
336
337
|
className={cx(
|
|
337
|
-
classes.
|
|
338
|
+
classes.scalebarContig,
|
|
338
339
|
canDisplayCytobands
|
|
339
340
|
? undefined
|
|
340
341
|
: reversed
|
|
341
|
-
? classes.
|
|
342
|
-
: classes.
|
|
343
|
-
!canDisplayCytobands ? classes.
|
|
342
|
+
? classes.scalebarContigReverse
|
|
343
|
+
: classes.scalebarContigForward,
|
|
344
|
+
!canDisplayCytobands ? classes.scalebarBorder : undefined,
|
|
344
345
|
)}
|
|
345
346
|
style={{
|
|
346
347
|
left: block.offsetPx + cytobandOffset,
|
|
@@ -352,7 +353,7 @@ const OverviewBox = observer(
|
|
|
352
353
|
? tickLabels.map((tickLabel, labelIdx) => (
|
|
353
354
|
<Typography
|
|
354
355
|
key={`${JSON.stringify(block)}-${tickLabel}-${labelIdx}`}
|
|
355
|
-
className={classes.
|
|
356
|
+
className={classes.scalebarLabel}
|
|
356
357
|
variant="body2"
|
|
357
358
|
style={{
|
|
358
359
|
left: ((labelIdx + 1) * majorPitch) / scale,
|
|
@@ -380,7 +381,7 @@ const OverviewBox = observer(
|
|
|
380
381
|
},
|
|
381
382
|
)
|
|
382
383
|
|
|
383
|
-
const
|
|
384
|
+
const Scalebar = observer(
|
|
384
385
|
({
|
|
385
386
|
model,
|
|
386
387
|
scale,
|
|
@@ -397,7 +398,7 @@ const ScaleBar = observer(
|
|
|
397
398
|
const overviewVisibleRegions = overview.dynamicBlocks
|
|
398
399
|
|
|
399
400
|
const { tertiary, primary } = theme.palette
|
|
400
|
-
const
|
|
401
|
+
const scalebarColor = tertiary ? tertiary.light : primary.light
|
|
401
402
|
|
|
402
403
|
if (!visibleRegions.length) {
|
|
403
404
|
return null
|
|
@@ -416,13 +417,13 @@ const ScaleBar = observer(
|
|
|
416
417
|
coord: last.reversed ? last.start : last.end,
|
|
417
418
|
}) || 0
|
|
418
419
|
|
|
419
|
-
const color = showCytobands ? '#f00' :
|
|
420
|
+
const color = showCytobands ? '#f00' : scalebarColor
|
|
420
421
|
const transparency = showCytobands ? 0.1 : 0.3
|
|
421
422
|
|
|
422
423
|
return (
|
|
423
|
-
<div className={classes.
|
|
424
|
+
<div className={classes.scalebar}>
|
|
424
425
|
<div
|
|
425
|
-
className={classes.
|
|
426
|
+
className={classes.scalebarVisibleRegion}
|
|
426
427
|
style={{
|
|
427
428
|
width: lastOverviewPx - firstOverviewPx,
|
|
428
429
|
left: firstOverviewPx + cytobandOffset,
|
|
@@ -435,7 +436,7 @@ const ScaleBar = observer(
|
|
|
435
436
|
return !(block instanceof ContentBlock) ? (
|
|
436
437
|
<div
|
|
437
438
|
key={`${JSON.stringify(block)}-${idx}`}
|
|
438
|
-
className={classes.
|
|
439
|
+
className={classes.scalebarContig}
|
|
439
440
|
style={{
|
|
440
441
|
width: block.widthPx,
|
|
441
442
|
left: block.offsetPx,
|
|
@@ -459,7 +460,7 @@ const ScaleBar = observer(
|
|
|
459
460
|
},
|
|
460
461
|
)
|
|
461
462
|
|
|
462
|
-
function
|
|
463
|
+
function OverviewScalebar({
|
|
463
464
|
model,
|
|
464
465
|
children,
|
|
465
466
|
}: {
|
|
@@ -484,11 +485,11 @@ function OverviewScaleBar({
|
|
|
484
485
|
|
|
485
486
|
return (
|
|
486
487
|
<div>
|
|
487
|
-
<
|
|
488
|
+
<OverviewRubberband
|
|
488
489
|
model={model}
|
|
489
490
|
overview={overview}
|
|
490
491
|
ControlComponent={
|
|
491
|
-
<
|
|
492
|
+
<Scalebar model={model} overview={overview} scale={scale} />
|
|
492
493
|
}
|
|
493
494
|
/>
|
|
494
495
|
<div className={classes.overview}>
|
|
@@ -501,6 +502,6 @@ function OverviewScaleBar({
|
|
|
501
502
|
)
|
|
502
503
|
}
|
|
503
504
|
|
|
504
|
-
export default observer(
|
|
505
|
+
export default observer(OverviewScalebar)
|
|
505
506
|
|
|
506
507
|
export { Cytobands, Polygon }
|
|
@@ -94,6 +94,7 @@ function RefNameAutocomplete({
|
|
|
94
94
|
useEffect(() => {
|
|
95
95
|
let active = true
|
|
96
96
|
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
97
98
|
;(async () => {
|
|
98
99
|
try {
|
|
99
100
|
if (debouncedSearch === '' || !assemblyName) {
|
|
@@ -146,7 +147,7 @@ function RefNameAutocomplete({
|
|
|
146
147
|
const inputBoxVal = coarseVisibleLocStrings || value || ''
|
|
147
148
|
|
|
148
149
|
// heuristic, text width + icon width
|
|
149
|
-
// + 45
|
|
150
|
+
// + 45 accommodates help icon and search icon
|
|
150
151
|
const width = Math.min(
|
|
151
152
|
Math.max(measureText(inputBoxVal, 16) + 45, minWidth),
|
|
152
153
|
550,
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React, { useRef } from 'react'
|
|
2
|
+
import { observer } from 'mobx-react'
|
|
3
|
+
import { makeStyles } from 'tss-react/mui'
|
|
4
|
+
import { Menu } from '@jbrowse/core/ui'
|
|
5
|
+
|
|
6
|
+
// locals
|
|
7
|
+
import VerticalGuide from './VerticalGuide'
|
|
8
|
+
import RubberbandSpan from './RubberbandSpan'
|
|
9
|
+
import { useRangeSelect } from './hooks'
|
|
10
|
+
import { LinearGenomeViewModel } from '..'
|
|
11
|
+
|
|
12
|
+
type LGV = LinearGenomeViewModel
|
|
13
|
+
|
|
14
|
+
const useStyles = makeStyles()({
|
|
15
|
+
rubberbandControl: {
|
|
16
|
+
cursor: 'crosshair',
|
|
17
|
+
width: '100%',
|
|
18
|
+
minHeight: 8,
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
function Rubberband({
|
|
23
|
+
model,
|
|
24
|
+
ControlComponent = <div />,
|
|
25
|
+
}: {
|
|
26
|
+
model: LGV
|
|
27
|
+
ControlComponent?: React.ReactElement
|
|
28
|
+
}) {
|
|
29
|
+
const ref = useRef<HTMLDivElement>(null)
|
|
30
|
+
const { classes } = useStyles()
|
|
31
|
+
|
|
32
|
+
const {
|
|
33
|
+
guideX,
|
|
34
|
+
rubberbandOn,
|
|
35
|
+
leftBpOffset,
|
|
36
|
+
rightBpOffset,
|
|
37
|
+
numOfBpSelected,
|
|
38
|
+
width,
|
|
39
|
+
left,
|
|
40
|
+
anchorPosition,
|
|
41
|
+
handleMenuItemClick,
|
|
42
|
+
open,
|
|
43
|
+
handleClose,
|
|
44
|
+
mouseMove,
|
|
45
|
+
mouseDown,
|
|
46
|
+
mouseOut,
|
|
47
|
+
} = useRangeSelect(ref, model)
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<>
|
|
51
|
+
{guideX !== undefined ? (
|
|
52
|
+
<VerticalGuide model={model} coordX={guideX} />
|
|
53
|
+
) : rubberbandOn ? (
|
|
54
|
+
<RubberbandSpan
|
|
55
|
+
leftBpOffset={leftBpOffset}
|
|
56
|
+
rightBpOffset={rightBpOffset}
|
|
57
|
+
numOfBpSelected={numOfBpSelected}
|
|
58
|
+
width={width}
|
|
59
|
+
left={left}
|
|
60
|
+
/>
|
|
61
|
+
) : null}
|
|
62
|
+
{anchorPosition ? (
|
|
63
|
+
<Menu
|
|
64
|
+
anchorReference="anchorPosition"
|
|
65
|
+
anchorPosition={{
|
|
66
|
+
left: anchorPosition.clientX,
|
|
67
|
+
top: anchorPosition.clientY,
|
|
68
|
+
}}
|
|
69
|
+
onMenuItemClick={handleMenuItemClick}
|
|
70
|
+
open={open}
|
|
71
|
+
onClose={handleClose}
|
|
72
|
+
menuItems={model.rubberBandMenuItems()}
|
|
73
|
+
/>
|
|
74
|
+
) : null}
|
|
75
|
+
<div
|
|
76
|
+
data-testid="rubberband_controls"
|
|
77
|
+
className={classes.rubberbandControl}
|
|
78
|
+
ref={ref}
|
|
79
|
+
onMouseDown={mouseDown}
|
|
80
|
+
onMouseMove={mouseMove}
|
|
81
|
+
onMouseOut={mouseOut}
|
|
82
|
+
>
|
|
83
|
+
{ControlComponent}
|
|
84
|
+
</div>
|
|
85
|
+
</>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default observer(Rubberband)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import React, { useRef } from 'react'
|
|
2
|
+
import { makeStyles } from 'tss-react/mui'
|
|
3
|
+
|
|
4
|
+
import { Popover, Typography, alpha } from '@mui/material'
|
|
5
|
+
import { stringify, toLocale } from '@jbrowse/core/util'
|
|
6
|
+
|
|
7
|
+
const useStyles = makeStyles()(theme => {
|
|
8
|
+
const { primary, tertiary } = theme.palette
|
|
9
|
+
const background = tertiary
|
|
10
|
+
? alpha(tertiary.main, 0.7)
|
|
11
|
+
: alpha(primary.main, 0.7)
|
|
12
|
+
return {
|
|
13
|
+
rubberband: {
|
|
14
|
+
height: '100%',
|
|
15
|
+
background,
|
|
16
|
+
position: 'absolute',
|
|
17
|
+
zIndex: 10,
|
|
18
|
+
textAlign: 'center',
|
|
19
|
+
overflow: 'hidden',
|
|
20
|
+
},
|
|
21
|
+
rubberbandControl: {
|
|
22
|
+
cursor: 'crosshair',
|
|
23
|
+
width: '100%',
|
|
24
|
+
minHeight: 8,
|
|
25
|
+
},
|
|
26
|
+
rubberbandText: {
|
|
27
|
+
color: tertiary ? tertiary.contrastText : primary.contrastText,
|
|
28
|
+
},
|
|
29
|
+
popover: {
|
|
30
|
+
mouseEvents: 'none',
|
|
31
|
+
cursor: 'crosshair',
|
|
32
|
+
},
|
|
33
|
+
paper: {
|
|
34
|
+
paddingLeft: theme.spacing(1),
|
|
35
|
+
paddingRight: theme.spacing(1),
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
interface Offset {
|
|
41
|
+
coord: number
|
|
42
|
+
refName?: string
|
|
43
|
+
oob?: boolean
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function RubberbandSpan({
|
|
47
|
+
leftBpOffset,
|
|
48
|
+
rightBpOffset,
|
|
49
|
+
numOfBpSelected,
|
|
50
|
+
left,
|
|
51
|
+
width,
|
|
52
|
+
}: {
|
|
53
|
+
leftBpOffset: Offset
|
|
54
|
+
rightBpOffset: Offset
|
|
55
|
+
numOfBpSelected?: number
|
|
56
|
+
left: number
|
|
57
|
+
width: number
|
|
58
|
+
}) {
|
|
59
|
+
const ref = useRef(null)
|
|
60
|
+
const { classes } = useStyles()
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
{ref.current ? (
|
|
64
|
+
<>
|
|
65
|
+
<Popover
|
|
66
|
+
className={classes.popover}
|
|
67
|
+
classes={{ paper: classes.paper }}
|
|
68
|
+
open
|
|
69
|
+
anchorEl={ref.current}
|
|
70
|
+
anchorOrigin={{
|
|
71
|
+
vertical: 'top',
|
|
72
|
+
horizontal: 'left',
|
|
73
|
+
}}
|
|
74
|
+
transformOrigin={{
|
|
75
|
+
vertical: 'bottom',
|
|
76
|
+
horizontal: 'right',
|
|
77
|
+
}}
|
|
78
|
+
keepMounted
|
|
79
|
+
disableRestoreFocus
|
|
80
|
+
>
|
|
81
|
+
<Typography>{stringify(leftBpOffset)}</Typography>
|
|
82
|
+
</Popover>
|
|
83
|
+
<Popover
|
|
84
|
+
className={classes.popover}
|
|
85
|
+
classes={{
|
|
86
|
+
paper: classes.paper,
|
|
87
|
+
}}
|
|
88
|
+
open
|
|
89
|
+
anchorEl={ref.current}
|
|
90
|
+
anchorOrigin={{
|
|
91
|
+
vertical: 'top',
|
|
92
|
+
horizontal: 'right',
|
|
93
|
+
}}
|
|
94
|
+
transformOrigin={{
|
|
95
|
+
vertical: 'bottom',
|
|
96
|
+
horizontal: 'left',
|
|
97
|
+
}}
|
|
98
|
+
keepMounted
|
|
99
|
+
disableRestoreFocus
|
|
100
|
+
>
|
|
101
|
+
<Typography>{stringify(rightBpOffset)}</Typography>
|
|
102
|
+
</Popover>
|
|
103
|
+
</>
|
|
104
|
+
) : null}
|
|
105
|
+
<div ref={ref} className={classes.rubberband} style={{ left, width }}>
|
|
106
|
+
{numOfBpSelected ? (
|
|
107
|
+
<Typography variant="h6" className={classes.rubberbandText}>
|
|
108
|
+
{toLocale(numOfBpSelected)} bp
|
|
109
|
+
</Typography>
|
|
110
|
+
) : null}
|
|
111
|
+
</div>
|
|
112
|
+
</>
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export default RubberbandSpan
|