@jbrowse/plugin-linear-genome-view 2.4.0 → 2.4.1
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.d.ts +2 -3
- package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js +4 -4
- package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js.map +1 -1
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +11 -6
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +5 -9
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +4 -5
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
- package/dist/BaseLinearDisplay/models/util.js +2 -2
- package/dist/BaseLinearDisplay/models/util.js.map +1 -1
- package/dist/LaunchLinearGenomeView/index.js +1 -1
- package/dist/LaunchLinearGenomeView/index.js.map +1 -1
- package/dist/LinearBareDisplay/index.d.ts +2 -3
- package/dist/LinearBareDisplay/index.js +4 -2
- package/dist/LinearBareDisplay/index.js.map +1 -1
- package/dist/LinearBareDisplay/model.d.ts +2 -2
- package/dist/LinearBasicDisplay/index.d.ts +2 -3
- package/dist/LinearBasicDisplay/index.js +4 -2
- package/dist/LinearBasicDisplay/index.js.map +1 -1
- package/dist/LinearBasicDisplay/model.d.ts +14 -4
- package/dist/LinearGenomeView/components/ExportSvgDialog.js +1 -1
- package/dist/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
- package/dist/LinearGenomeView/components/ImportForm.d.ts +2 -2
- package/dist/LinearGenomeView/components/ImportForm.js +15 -19
- package/dist/LinearGenomeView/components/ImportForm.js.map +1 -1
- package/dist/LinearGenomeView/components/OverviewRubberband.d.ts +3 -4
- package/dist/LinearGenomeView/components/OverviewRubberband.js +8 -11
- package/dist/LinearGenomeView/components/OverviewRubberband.js.map +1 -1
- package/dist/LinearGenomeView/components/OverviewScalebar.d.ts +4 -5
- package/dist/LinearGenomeView/components/OverviewScalebar.js +5 -5
- package/dist/LinearGenomeView/components/OverviewScalebar.js.map +1 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete.d.ts +2 -1
- package/dist/LinearGenomeView/components/RefNameAutocomplete.js +35 -31
- package/dist/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
- package/dist/LinearGenomeView/components/RubberbandSpan.d.ts +2 -2
- package/dist/LinearGenomeView/components/RubberbandSpan.js +2 -16
- package/dist/LinearGenomeView/components/RubberbandSpan.js.map +1 -1
- package/dist/LinearGenomeView/components/SearchBox.js +3 -3
- package/dist/LinearGenomeView/components/SearchBox.js.map +1 -1
- package/dist/LinearGenomeView/components/TrackLabel.js +3 -3
- package/dist/LinearGenomeView/components/TrackLabel.js.map +1 -1
- package/dist/LinearGenomeView/components/TracksContainer.d.ts +2 -3
- package/dist/LinearGenomeView/components/TracksContainer.js +9 -8
- package/dist/LinearGenomeView/components/TracksContainer.js.map +1 -1
- package/dist/LinearGenomeView/components/hooks.d.ts +6 -1
- package/dist/LinearGenomeView/components/hooks.js +1 -1
- package/dist/LinearGenomeView/components/hooks.js.map +1 -1
- package/dist/LinearGenomeView/index.js +8 -6
- package/dist/LinearGenomeView/index.js.map +1 -1
- package/dist/LinearGenomeView/model.d.ts +9 -11
- package/dist/LinearGenomeView/model.js +28 -31
- package/dist/LinearGenomeView/model.js.map +1 -1
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +2 -3
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +6 -5
- package/dist/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js.map +1 -1
- package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.js +2 -1
- package/dist/LinearGenomeView/svgcomponents/SVGTrackLabel.js.map +1 -1
- package/dist/LinearGenomeView/util.js +1 -1
- package/dist/LinearGenomeView/util.js.map +1 -1
- package/dist/index.d.ts +36 -38
- package/dist/index.js +21 -17
- package/dist/index.js.map +1 -1
- package/esm/BaseLinearDisplay/components/BaseLinearDisplay.d.ts +2 -3
- package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js +2 -3
- package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js.map +1 -1
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +11 -6
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +5 -9
- package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +4 -5
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
- package/esm/BaseLinearDisplay/models/util.js +2 -2
- package/esm/BaseLinearDisplay/models/util.js.map +1 -1
- package/esm/LaunchLinearGenomeView/index.js +1 -1
- package/esm/LaunchLinearGenomeView/index.js.map +1 -1
- package/esm/LinearBareDisplay/index.d.ts +2 -3
- package/esm/LinearBareDisplay/index.js +2 -1
- package/esm/LinearBareDisplay/index.js.map +1 -1
- package/esm/LinearBareDisplay/model.d.ts +2 -2
- package/esm/LinearBasicDisplay/index.d.ts +2 -3
- package/esm/LinearBasicDisplay/index.js +2 -1
- package/esm/LinearBasicDisplay/index.js.map +1 -1
- package/esm/LinearBasicDisplay/model.d.ts +14 -4
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +1 -1
- package/esm/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
- package/esm/LinearGenomeView/components/ImportForm.d.ts +2 -2
- package/esm/LinearGenomeView/components/ImportForm.js +16 -20
- package/esm/LinearGenomeView/components/ImportForm.js.map +1 -1
- package/esm/LinearGenomeView/components/OverviewRubberband.d.ts +3 -4
- package/esm/LinearGenomeView/components/OverviewRubberband.js +8 -11
- package/esm/LinearGenomeView/components/OverviewRubberband.js.map +1 -1
- package/esm/LinearGenomeView/components/OverviewScalebar.d.ts +4 -5
- package/esm/LinearGenomeView/components/OverviewScalebar.js +4 -4
- package/esm/LinearGenomeView/components/OverviewScalebar.js.map +1 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete.d.ts +2 -1
- package/esm/LinearGenomeView/components/RefNameAutocomplete.js +36 -32
- package/esm/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
- package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +2 -2
- package/esm/LinearGenomeView/components/RubberbandSpan.js +3 -18
- package/esm/LinearGenomeView/components/RubberbandSpan.js.map +1 -1
- package/esm/LinearGenomeView/components/SearchBox.js +3 -3
- package/esm/LinearGenomeView/components/SearchBox.js.map +1 -1
- package/esm/LinearGenomeView/components/TrackLabel.js +3 -3
- package/esm/LinearGenomeView/components/TrackLabel.js.map +1 -1
- package/esm/LinearGenomeView/components/TracksContainer.d.ts +2 -3
- package/esm/LinearGenomeView/components/TracksContainer.js +9 -8
- package/esm/LinearGenomeView/components/TracksContainer.js.map +1 -1
- package/esm/LinearGenomeView/components/hooks.d.ts +6 -1
- package/esm/LinearGenomeView/components/hooks.js +1 -1
- package/esm/LinearGenomeView/components/hooks.js.map +1 -1
- package/esm/LinearGenomeView/index.js +8 -6
- package/esm/LinearGenomeView/index.js.map +1 -1
- package/esm/LinearGenomeView/model.d.ts +9 -11
- package/esm/LinearGenomeView/model.js +22 -26
- package/esm/LinearGenomeView/model.js.map +1 -1
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +2 -3
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +3 -3
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js.map +1 -1
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +2 -1
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js.map +1 -1
- package/esm/LinearGenomeView/util.js +1 -1
- package/esm/LinearGenomeView/util.js.map +1 -1
- package/esm/index.d.ts +36 -38
- package/esm/index.js +9 -6
- package/esm/index.js.map +1 -1
- package/package.json +2 -2
- package/src/BaseLinearDisplay/components/BaseLinearDisplay.tsx +4 -3
- package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +6 -9
- package/src/BaseLinearDisplay/models/serverSideRenderedBlock.ts +6 -5
- package/src/BaseLinearDisplay/models/util.ts +2 -2
- package/src/LaunchLinearGenomeView/index.ts +1 -1
- package/src/LinearBareDisplay/index.ts +2 -1
- package/src/LinearBasicDisplay/index.ts +2 -1
- package/src/LinearGenomeView/components/ExportSvgDialog.tsx +1 -1
- package/src/LinearGenomeView/components/ImportForm.tsx +17 -26
- package/src/LinearGenomeView/components/OverviewRubberband.tsx +40 -49
- package/src/LinearGenomeView/components/OverviewScalebar.tsx +4 -4
- package/src/LinearGenomeView/components/RefNameAutocomplete.tsx +50 -48
- package/src/LinearGenomeView/components/RubberbandSpan.tsx +6 -23
- package/src/LinearGenomeView/components/SearchBox.tsx +3 -2
- package/src/LinearGenomeView/components/TrackLabel.tsx +74 -71
- package/src/LinearGenomeView/components/TracksContainer.tsx +8 -8
- package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.tsx.snap +7 -11
- package/src/LinearGenomeView/components/hooks.ts +7 -1
- package/src/LinearGenomeView/index.test.ts +3 -8
- package/src/LinearGenomeView/index.ts +8 -9
- package/src/LinearGenomeView/model.ts +31 -33
- package/src/LinearGenomeView/svgcomponents/SVGLinearGenomeView.tsx +5 -5
- package/src/LinearGenomeView/svgcomponents/SVGTrackLabel.tsx +2 -0
- package/src/LinearGenomeView/util.ts +1 -1
- package/src/index.ts +21 -31
|
@@ -14,9 +14,9 @@ export interface ErrorProps {
|
|
|
14
14
|
export function getDisplayStr(totalBytes: number) {
|
|
15
15
|
let displayBp
|
|
16
16
|
if (Math.floor(totalBytes / 1000000) > 0) {
|
|
17
|
-
displayBp = `${parseFloat((totalBytes / 1000000).toPrecision(3))} Mb`
|
|
17
|
+
displayBp = `${Number.parseFloat((totalBytes / 1000000).toPrecision(3))} Mb`
|
|
18
18
|
} else if (Math.floor(totalBytes / 1000) > 0) {
|
|
19
|
-
displayBp = `${parseFloat((totalBytes / 1000).toPrecision(3))} Kb`
|
|
19
|
+
displayBp = `${Number.parseFloat((totalBytes / 1000).toPrecision(3))} Kb`
|
|
20
20
|
} else {
|
|
21
21
|
displayBp = `${Math.floor(totalBytes)} bytes`
|
|
22
22
|
}
|
|
@@ -4,10 +4,10 @@ import { observer } from 'mobx-react'
|
|
|
4
4
|
import { getSession } from '@jbrowse/core/util'
|
|
5
5
|
import {
|
|
6
6
|
Button,
|
|
7
|
-
CircularProgress,
|
|
8
7
|
FormControl,
|
|
9
8
|
Container,
|
|
10
9
|
Grid,
|
|
10
|
+
CircularProgress,
|
|
11
11
|
} from '@mui/material'
|
|
12
12
|
import { ErrorMessage, AssemblySelector } from '@jbrowse/core/ui'
|
|
13
13
|
import BaseResult from '@jbrowse/core/TextSearch/BaseResults'
|
|
@@ -19,6 +19,8 @@ import CloseIcon from '@mui/icons-material/Close'
|
|
|
19
19
|
import RefNameAutocomplete from './RefNameAutocomplete'
|
|
20
20
|
import { fetchResults, splitLast } from './util'
|
|
21
21
|
import { LinearGenomeViewModel } from '..'
|
|
22
|
+
|
|
23
|
+
// lazies
|
|
22
24
|
const SearchResultsDialog = lazy(() => import('./SearchResultsDialog'))
|
|
23
25
|
|
|
24
26
|
const useStyles = makeStyles()(theme => ({
|
|
@@ -35,29 +37,29 @@ const useStyles = makeStyles()(theme => ({
|
|
|
35
37
|
|
|
36
38
|
type LGV = LinearGenomeViewModel
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
export default observer(function ({ model }: { model: LGV }) {
|
|
39
41
|
const { classes } = useStyles()
|
|
40
42
|
const session = getSession(model)
|
|
41
43
|
const { assemblyNames, assemblyManager, textSearchManager } = session
|
|
42
44
|
const { rankSearchResults, isSearchDialogDisplayed, error } = model
|
|
43
45
|
const [selectedAsm, setSelectedAsm] = useState(assemblyNames[0])
|
|
44
46
|
const [option, setOption] = useState<BaseResult>()
|
|
45
|
-
|
|
46
47
|
const searchScope = model.searchScope(selectedAsm)
|
|
47
|
-
|
|
48
48
|
const assembly = assemblyManager.get(selectedAsm)
|
|
49
49
|
const assemblyError = assemblyNames.length
|
|
50
50
|
? assembly?.error
|
|
51
51
|
: 'No configured assemblies'
|
|
52
|
-
const regions = assembly?.regions || []
|
|
53
52
|
const displayError = assemblyError || error
|
|
54
53
|
const [value, setValue] = useState('')
|
|
55
|
-
const
|
|
54
|
+
const regions = assembly?.regions
|
|
55
|
+
const assemblyLoaded = !!regions
|
|
56
|
+
const r0 = regions ? regions[0]?.refName : ''
|
|
56
57
|
|
|
57
|
-
// useEffect resets to an "initial state" of displaying first region from
|
|
58
|
-
// after assembly change. needs to react to selectedAsm as well as
|
|
59
|
-
// assembly will run setValue('') and then r0 may not
|
|
60
|
-
// same across assemblies, but it still
|
|
58
|
+
// useEffect resets to an "initial state" of displaying first region from
|
|
59
|
+
// assembly after assembly change. needs to react to selectedAsm as well as
|
|
60
|
+
// r0 because changing assembly will run setValue('') and then r0 may not
|
|
61
|
+
// change if assembly names are the same across assemblies, but it still
|
|
62
|
+
// needs to be reset
|
|
61
63
|
useEffect(() => {
|
|
62
64
|
setValue(r0)
|
|
63
65
|
}, [r0, selectedAsm])
|
|
@@ -89,7 +91,7 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
89
91
|
const allRefs = assembly?.allRefNamesWithLowerCase || []
|
|
90
92
|
if (
|
|
91
93
|
allRefs.includes(input) ||
|
|
92
|
-
(allRefs.includes(ref) && !Number.isNaN(parseInt(rest, 10)))
|
|
94
|
+
(allRefs.includes(ref) && !Number.isNaN(Number.parseInt(rest, 10)))
|
|
93
95
|
) {
|
|
94
96
|
await model.navToLocString(input, selectedAsm)
|
|
95
97
|
} else {
|
|
@@ -142,10 +144,7 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
142
144
|
<Grid item>
|
|
143
145
|
<FormControl>
|
|
144
146
|
<AssemblySelector
|
|
145
|
-
onChange={val =>
|
|
146
|
-
setSelectedAsm(val)
|
|
147
|
-
setValue('')
|
|
148
|
-
}}
|
|
147
|
+
onChange={val => setSelectedAsm(val)}
|
|
149
148
|
localStorageKey="lgv"
|
|
150
149
|
session={session}
|
|
151
150
|
selected={selectedAsm}
|
|
@@ -156,7 +155,7 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
156
155
|
{selectedAsm ? (
|
|
157
156
|
assemblyError ? (
|
|
158
157
|
<CloseIcon style={{ color: 'red' }} />
|
|
159
|
-
) :
|
|
158
|
+
) : assemblyLoaded ? (
|
|
160
159
|
<FormControl>
|
|
161
160
|
<RefNameAutocomplete
|
|
162
161
|
fetchResults={queryString =>
|
|
@@ -169,9 +168,8 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
169
168
|
})
|
|
170
169
|
}
|
|
171
170
|
model={model}
|
|
172
|
-
assemblyName={
|
|
171
|
+
assemblyName={selectedAsm}
|
|
173
172
|
value={value}
|
|
174
|
-
// note: minWidth 270 accommodates full width of helperText
|
|
175
173
|
minWidth={270}
|
|
176
174
|
onChange={str => setValue(str)}
|
|
177
175
|
onSelect={val => setOption(val)}
|
|
@@ -179,16 +177,11 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
179
177
|
variant: 'outlined',
|
|
180
178
|
helperText:
|
|
181
179
|
'Enter sequence name, feature name, or location',
|
|
182
|
-
style: { minWidth: '175px' },
|
|
183
180
|
}}
|
|
184
181
|
/>
|
|
185
182
|
</FormControl>
|
|
186
183
|
) : (
|
|
187
|
-
<CircularProgress
|
|
188
|
-
role="progressbar"
|
|
189
|
-
size={20}
|
|
190
|
-
disableShrink
|
|
191
|
-
/>
|
|
184
|
+
<CircularProgress size={20} disableShrink />
|
|
192
185
|
)
|
|
193
186
|
) : null}
|
|
194
187
|
</Grid>
|
|
@@ -232,5 +225,3 @@ const ImportForm = observer(({ model }: { model: LGV }) => {
|
|
|
232
225
|
</div>
|
|
233
226
|
)
|
|
234
227
|
})
|
|
235
|
-
|
|
236
|
-
export default ImportForm
|
|
@@ -4,6 +4,8 @@ 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
|
+
|
|
8
|
+
// locals
|
|
7
9
|
import { LinearGenomeViewModel } from '..'
|
|
8
10
|
import RubberbandSpan from './RubberbandSpan'
|
|
9
11
|
import { getRelativeX } from './util'
|
|
@@ -25,50 +27,43 @@ const useStyles = makeStyles()({
|
|
|
25
27
|
},
|
|
26
28
|
})
|
|
27
29
|
|
|
28
|
-
const HoverTooltip = observer(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
f
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
30
|
+
const HoverTooltip = observer(function ({
|
|
31
|
+
model,
|
|
32
|
+
open,
|
|
33
|
+
guideX,
|
|
34
|
+
overview,
|
|
35
|
+
}: {
|
|
36
|
+
model: LGV
|
|
37
|
+
open: boolean
|
|
38
|
+
guideX: number
|
|
39
|
+
overview: Base1DViewModel
|
|
40
|
+
}) {
|
|
41
|
+
const { classes } = useStyles()
|
|
42
|
+
const { cytobandOffset } = model
|
|
43
|
+
const { assemblyManager } = getSession(model)
|
|
44
|
+
|
|
45
|
+
const px = overview.pxToBp(guideX - cytobandOffset)
|
|
46
|
+
const assembly = assemblyManager.get(px.assemblyName)
|
|
47
|
+
const cytoband = assembly?.cytobands?.find(
|
|
48
|
+
f =>
|
|
49
|
+
px.coord > f.get('start') &&
|
|
50
|
+
px.coord < f.get('end') &&
|
|
51
|
+
px.refName === assembly.getCanonicalRefName(f.get('refName')),
|
|
52
|
+
)
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}}
|
|
65
|
-
/>
|
|
66
|
-
</Tooltip>
|
|
67
|
-
)
|
|
68
|
-
},
|
|
69
|
-
)
|
|
54
|
+
return (
|
|
55
|
+
<Tooltip
|
|
56
|
+
open={open}
|
|
57
|
+
placement="top"
|
|
58
|
+
title={[stringify(px), cytoband?.get('name')].join(' ')}
|
|
59
|
+
arrow
|
|
60
|
+
>
|
|
61
|
+
<div className={classes.guide} style={{ left: guideX }} />
|
|
62
|
+
</Tooltip>
|
|
63
|
+
)
|
|
64
|
+
})
|
|
70
65
|
|
|
71
|
-
function OverviewRubberband({
|
|
66
|
+
export default observer(function OverviewRubberband({
|
|
72
67
|
model,
|
|
73
68
|
overview,
|
|
74
69
|
ControlComponent = <div />,
|
|
@@ -171,7 +166,6 @@ function OverviewRubberband({
|
|
|
171
166
|
) : null}
|
|
172
167
|
<div
|
|
173
168
|
className={classes.rubberbandControl}
|
|
174
|
-
role="presentation"
|
|
175
169
|
ref={controlsRef}
|
|
176
170
|
onMouseDown={mouseDown}
|
|
177
171
|
onMouseOut={mouseOut}
|
|
@@ -195,7 +189,7 @@ function OverviewRubberband({
|
|
|
195
189
|
if (startX) {
|
|
196
190
|
leftBpOffset = overview.pxToBp(startX - cytobandOffset)
|
|
197
191
|
rightBpOffset = overview.pxToBp(startX + width - cytobandOffset)
|
|
198
|
-
if (currentX && currentX < startX) {
|
|
192
|
+
if (currentX !== undefined && currentX < startX) {
|
|
199
193
|
;[leftBpOffset, rightBpOffset] = [rightBpOffset, leftBpOffset]
|
|
200
194
|
}
|
|
201
195
|
}
|
|
@@ -206,14 +200,13 @@ function OverviewRubberband({
|
|
|
206
200
|
<RubberbandSpan
|
|
207
201
|
leftBpOffset={leftBpOffset}
|
|
208
202
|
rightBpOffset={rightBpOffset}
|
|
209
|
-
width={width}
|
|
203
|
+
width={Math.abs(width)}
|
|
210
204
|
left={left}
|
|
211
205
|
/>
|
|
212
206
|
) : null}
|
|
213
207
|
<div
|
|
214
208
|
data-testid="rubberband_controls"
|
|
215
209
|
className={classes.rubberbandControl}
|
|
216
|
-
role="presentation"
|
|
217
210
|
ref={controlsRef}
|
|
218
211
|
onMouseDown={mouseDown}
|
|
219
212
|
onMouseOut={mouseOut}
|
|
@@ -223,6 +216,4 @@ function OverviewRubberband({
|
|
|
223
216
|
</div>
|
|
224
217
|
</div>
|
|
225
218
|
)
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export default observer(OverviewRubberband)
|
|
219
|
+
})
|
|
@@ -297,7 +297,7 @@ const Scalebar = observer(function ({
|
|
|
297
297
|
)
|
|
298
298
|
})
|
|
299
299
|
|
|
300
|
-
function OverviewScalebar({
|
|
300
|
+
export default observer(function OverviewScalebar({
|
|
301
301
|
model,
|
|
302
302
|
children,
|
|
303
303
|
}: {
|
|
@@ -337,8 +337,8 @@ function OverviewScalebar({
|
|
|
337
337
|
</div>
|
|
338
338
|
</div>
|
|
339
339
|
)
|
|
340
|
-
}
|
|
340
|
+
})
|
|
341
341
|
|
|
342
|
-
export
|
|
342
|
+
export { Polygon }
|
|
343
343
|
|
|
344
|
-
export { Cytobands
|
|
344
|
+
export { default as Cytobands } from './Cytobands'
|
|
@@ -6,7 +6,6 @@ import BaseResult, {
|
|
|
6
6
|
} from '@jbrowse/core/TextSearch/BaseResults'
|
|
7
7
|
import {
|
|
8
8
|
Autocomplete,
|
|
9
|
-
CircularProgress,
|
|
10
9
|
IconButton,
|
|
11
10
|
InputAdornment,
|
|
12
11
|
TextField,
|
|
@@ -28,6 +27,38 @@ export interface Option {
|
|
|
28
27
|
result: BaseResult
|
|
29
28
|
}
|
|
30
29
|
|
|
30
|
+
function aggregateResults(results: BaseResult[]) {
|
|
31
|
+
const m: { [key: string]: BaseResult[] } = {}
|
|
32
|
+
|
|
33
|
+
for (let i = 0; i < results.length; i++) {
|
|
34
|
+
const r = results[i]
|
|
35
|
+
const d = r.getDisplayString()
|
|
36
|
+
if (!m[d]) {
|
|
37
|
+
m[d] = []
|
|
38
|
+
}
|
|
39
|
+
m[d].push(r)
|
|
40
|
+
}
|
|
41
|
+
return m
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getDeduplicatedResult(results: BaseResult[]) {
|
|
45
|
+
return Object.entries(aggregateResults(results)).map(
|
|
46
|
+
([displayString, results]) =>
|
|
47
|
+
results.length === 1
|
|
48
|
+
? {
|
|
49
|
+
result: results[0],
|
|
50
|
+
}
|
|
51
|
+
: {
|
|
52
|
+
// deduplicate a "multi-result"
|
|
53
|
+
result: new BaseResult({
|
|
54
|
+
displayString,
|
|
55
|
+
results,
|
|
56
|
+
label: displayString,
|
|
57
|
+
}),
|
|
58
|
+
},
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
31
62
|
// the logic of this method is to only apply a filter to RefSequenceResults
|
|
32
63
|
// because they do not have a matchedObject. the trix search results already
|
|
33
64
|
// filter so don't need re-filtering
|
|
@@ -51,6 +82,7 @@ function RefNameAutocomplete({
|
|
|
51
82
|
value,
|
|
52
83
|
showHelp = true,
|
|
53
84
|
minWidth = 200,
|
|
85
|
+
maxWidth = 550,
|
|
54
86
|
TextFieldProps = {},
|
|
55
87
|
}: {
|
|
56
88
|
model: LinearGenomeViewModel
|
|
@@ -61,6 +93,7 @@ function RefNameAutocomplete({
|
|
|
61
93
|
fetchResults: (query: string) => Promise<BaseResult[]>
|
|
62
94
|
style?: React.CSSProperties
|
|
63
95
|
minWidth?: number
|
|
96
|
+
maxWidth?: number
|
|
64
97
|
showHelp?: boolean
|
|
65
98
|
TextFieldProps?: TFP
|
|
66
99
|
}) {
|
|
@@ -104,32 +137,8 @@ function RefNameAutocomplete({
|
|
|
104
137
|
setLoaded(false)
|
|
105
138
|
const results = await fetchResults(debouncedSearch)
|
|
106
139
|
if (active) {
|
|
107
|
-
const m: { [key: string]: BaseResult[] } = {}
|
|
108
|
-
|
|
109
|
-
for (let i = 0; i < results.length; i++) {
|
|
110
|
-
const r = results[i]
|
|
111
|
-
const d = r.getDisplayString()
|
|
112
|
-
if (!m[d]) {
|
|
113
|
-
m[d] = []
|
|
114
|
-
}
|
|
115
|
-
m[d].push(r)
|
|
116
|
-
}
|
|
117
|
-
const display = Object.entries(m).map(([displayString, results]) => {
|
|
118
|
-
if (results.length === 1) {
|
|
119
|
-
return { result: results[0] }
|
|
120
|
-
} else {
|
|
121
|
-
return {
|
|
122
|
-
result: new BaseResult({
|
|
123
|
-
displayString,
|
|
124
|
-
results,
|
|
125
|
-
label: displayString,
|
|
126
|
-
}),
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
setSearchOptions(display)
|
|
132
140
|
setLoaded(true)
|
|
141
|
+
setSearchOptions(getDeduplicatedResult(results))
|
|
133
142
|
}
|
|
134
143
|
} catch (e) {
|
|
135
144
|
console.error(e)
|
|
@@ -146,19 +155,16 @@ function RefNameAutocomplete({
|
|
|
146
155
|
|
|
147
156
|
const inputBoxVal = coarseVisibleLocStrings || value || ''
|
|
148
157
|
|
|
149
|
-
// heuristic, text width + icon width
|
|
150
|
-
//
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
550,
|
|
154
|
-
)
|
|
158
|
+
// heuristic, text width + icon width + 50 accommodates help icon and search
|
|
159
|
+
// icon
|
|
160
|
+
const w = measureText(inputBoxVal, 16) + 50
|
|
161
|
+
const width = Math.min(Math.max(w, minWidth), maxWidth)
|
|
155
162
|
|
|
156
163
|
// notes on implementation:
|
|
157
164
|
// The selectOnFocus setting helps highlight the field when clicked
|
|
158
165
|
return (
|
|
159
166
|
<>
|
|
160
167
|
<Autocomplete
|
|
161
|
-
id={`refNameAutocomplete-${model.id}`}
|
|
162
168
|
data-testid="autocomplete"
|
|
163
169
|
disableListWrap
|
|
164
170
|
disableClearable
|
|
@@ -237,21 +243,17 @@ function RefNameAutocomplete({
|
|
|
237
243
|
|
|
238
244
|
endAdornment: (
|
|
239
245
|
<>
|
|
240
|
-
{
|
|
241
|
-
<
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
</IconButton>
|
|
252
|
-
) : null}
|
|
253
|
-
</InputAdornment>
|
|
254
|
-
)}
|
|
246
|
+
<InputAdornment position="end" style={{ marginRight: 7 }}>
|
|
247
|
+
<SearchIcon fontSize="small" />
|
|
248
|
+
{showHelp ? (
|
|
249
|
+
<IconButton
|
|
250
|
+
onClick={() => setHelpDialogDisplayed(true)}
|
|
251
|
+
size="small"
|
|
252
|
+
>
|
|
253
|
+
<HelpIcon fontSize="small" />
|
|
254
|
+
</IconButton>
|
|
255
|
+
) : null}
|
|
256
|
+
</InputAdornment>
|
|
255
257
|
{params.InputProps.endAdornment}
|
|
256
258
|
</>
|
|
257
259
|
),
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useRef } from 'react'
|
|
2
2
|
import { makeStyles } from 'tss-react/mui'
|
|
3
|
-
|
|
4
3
|
import { Popover, Typography, alpha } from '@mui/material'
|
|
5
4
|
import { stringify, toLocale } from '@jbrowse/core/util'
|
|
6
5
|
|
|
@@ -43,7 +42,7 @@ interface Offset {
|
|
|
43
42
|
oob?: boolean
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
function RubberbandSpan({
|
|
45
|
+
export default function RubberbandSpan({
|
|
47
46
|
leftBpOffset,
|
|
48
47
|
rightBpOffset,
|
|
49
48
|
numOfBpSelected,
|
|
@@ -67,14 +66,8 @@ function RubberbandSpan({
|
|
|
67
66
|
classes={{ paper: classes.paper }}
|
|
68
67
|
open
|
|
69
68
|
anchorEl={ref.current}
|
|
70
|
-
anchorOrigin={{
|
|
71
|
-
|
|
72
|
-
horizontal: 'left',
|
|
73
|
-
}}
|
|
74
|
-
transformOrigin={{
|
|
75
|
-
vertical: 'bottom',
|
|
76
|
-
horizontal: 'right',
|
|
77
|
-
}}
|
|
69
|
+
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
|
|
70
|
+
transformOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
|
78
71
|
keepMounted
|
|
79
72
|
disableRestoreFocus
|
|
80
73
|
>
|
|
@@ -82,19 +75,11 @@ function RubberbandSpan({
|
|
|
82
75
|
</Popover>
|
|
83
76
|
<Popover
|
|
84
77
|
className={classes.popover}
|
|
85
|
-
classes={{
|
|
86
|
-
paper: classes.paper,
|
|
87
|
-
}}
|
|
78
|
+
classes={{ paper: classes.paper }}
|
|
88
79
|
open
|
|
89
80
|
anchorEl={ref.current}
|
|
90
|
-
anchorOrigin={{
|
|
91
|
-
|
|
92
|
-
horizontal: 'right',
|
|
93
|
-
}}
|
|
94
|
-
transformOrigin={{
|
|
95
|
-
vertical: 'bottom',
|
|
96
|
-
horizontal: 'left',
|
|
97
|
-
}}
|
|
81
|
+
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
|
|
82
|
+
transformOrigin={{ vertical: 'bottom', horizontal: 'left' }}
|
|
98
83
|
keepMounted
|
|
99
84
|
disableRestoreFocus
|
|
100
85
|
>
|
|
@@ -112,5 +97,3 @@ function RubberbandSpan({
|
|
|
112
97
|
</>
|
|
113
98
|
)
|
|
114
99
|
}
|
|
115
|
-
|
|
116
|
-
export default RubberbandSpan
|
|
@@ -61,7 +61,7 @@ function SearchBox({
|
|
|
61
61
|
const allRefs = assembly?.allRefNamesWithLowerCase || []
|
|
62
62
|
if (
|
|
63
63
|
allRefs.includes(input) ||
|
|
64
|
-
(allRefs.includes(ref) && !Number.isNaN(parseInt(rest, 10)))
|
|
64
|
+
(allRefs.includes(ref) && !Number.isNaN(Number.parseInt(rest, 10)))
|
|
65
65
|
) {
|
|
66
66
|
await model.navToLocString(input, assemblyName)
|
|
67
67
|
} else {
|
|
@@ -103,10 +103,11 @@ function SearchBox({
|
|
|
103
103
|
})
|
|
104
104
|
}
|
|
105
105
|
model={model}
|
|
106
|
+
minWidth={175}
|
|
106
107
|
TextFieldProps={{
|
|
107
108
|
variant: 'outlined',
|
|
108
109
|
className: classes.headerRefName,
|
|
109
|
-
style: { margin: SPACING
|
|
110
|
+
style: { margin: SPACING },
|
|
110
111
|
InputProps: {
|
|
111
112
|
style: {
|
|
112
113
|
padding: 0,
|