@jbrowse/plugin-linear-genome-view 1.7.7 → 1.7.10
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 +1 -5
- package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js +32 -120
- package/dist/BaseLinearDisplay/components/Tooltip.d.ts +8 -0
- package/dist/BaseLinearDisplay/components/Tooltip.js +125 -0
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +3 -3
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +3 -4
- package/dist/LinearGenomeView/components/ExportSvgDialog.js +35 -25
- package/dist/LinearGenomeView/components/Header.js +5 -2
- package/dist/LinearGenomeView/components/HelpDialog.js +2 -3
- package/dist/LinearGenomeView/components/ImportForm.js +47 -47
- package/dist/LinearGenomeView/components/LinearGenomeView.js +6 -2
- package/dist/LinearGenomeView/components/LinearGenomeView.test.js +2 -2
- package/dist/LinearGenomeView/components/OverviewScaleBar.js +2 -2
- package/dist/LinearGenomeView/components/RefNameAutocomplete.d.ts +3 -2
- package/dist/LinearGenomeView/components/RefNameAutocomplete.js +7 -5
- package/dist/LinearGenomeView/components/ScaleBar.d.ts +8 -4
- package/dist/LinearGenomeView/components/ScaleBar.js +8 -3
- package/dist/LinearGenomeView/components/SearchBox.js +31 -22
- package/dist/LinearGenomeView/components/TrackLabel.js +25 -41
- package/dist/LinearGenomeView/index.d.ts +7 -11
- package/dist/LinearGenomeView/index.js +60 -33
- package/dist/LinearGenomeView/index.test.js +22 -5
- package/dist/index.js +22 -11
- package/package.json +3 -2
- package/src/BaseLinearDisplay/components/BaseLinearDisplay.tsx +4 -89
- package/src/BaseLinearDisplay/components/Tooltip.tsx +97 -0
- package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +11 -4
- package/src/LinearGenomeView/components/ExportSvgDialog.tsx +24 -11
- package/src/LinearGenomeView/components/Header.tsx +3 -2
- package/src/LinearGenomeView/components/HelpDialog.tsx +5 -4
- package/src/LinearGenomeView/components/ImportForm.tsx +37 -32
- package/src/LinearGenomeView/components/LinearGenomeView.test.js +2 -2
- package/src/LinearGenomeView/components/LinearGenomeView.tsx +16 -10
- package/src/LinearGenomeView/components/OverviewScaleBar.tsx +3 -4
- package/src/LinearGenomeView/components/RefNameAutocomplete.tsx +10 -5
- package/src/LinearGenomeView/components/ScaleBar.tsx +6 -9
- package/src/LinearGenomeView/components/SearchBox.tsx +20 -4
- package/src/LinearGenomeView/components/TrackLabel.tsx +25 -28
- package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.js.snap +4 -21
- package/src/LinearGenomeView/index.test.ts +20 -5
- package/src/LinearGenomeView/index.tsx +56 -27
- package/src/index.ts +35 -30
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { getConf, readConfObject } from '@jbrowse/core/configuration'
|
|
3
|
-
import
|
|
3
|
+
import CascadingMenu from '@jbrowse/core/ui/CascadingMenu'
|
|
4
4
|
import { getSession, getContainingView } from '@jbrowse/core/util'
|
|
5
5
|
import { BaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models'
|
|
6
6
|
import {
|
|
@@ -11,14 +11,21 @@ import {
|
|
|
11
11
|
makeStyles,
|
|
12
12
|
} from '@material-ui/core'
|
|
13
13
|
|
|
14
|
+
import {
|
|
15
|
+
bindTrigger,
|
|
16
|
+
bindPopover,
|
|
17
|
+
usePopupState,
|
|
18
|
+
} from 'material-ui-popup-state/hooks'
|
|
19
|
+
|
|
20
|
+
import clsx from 'clsx'
|
|
21
|
+
import { observer } from 'mobx-react'
|
|
22
|
+
import { Instance } from 'mobx-state-tree'
|
|
23
|
+
|
|
14
24
|
// icons
|
|
15
25
|
import MoreVertIcon from '@material-ui/icons/MoreVert'
|
|
16
26
|
import DragIcon from '@material-ui/icons/DragIndicator'
|
|
17
27
|
import CloseIcon from '@material-ui/icons/Close'
|
|
18
28
|
|
|
19
|
-
import clsx from 'clsx'
|
|
20
|
-
import { observer } from 'mobx-react'
|
|
21
|
-
import { Instance } from 'mobx-state-tree'
|
|
22
29
|
import { LinearGenomeViewStateModel } from '..'
|
|
23
30
|
|
|
24
31
|
const useStyles = makeStyles(theme => ({
|
|
@@ -54,22 +61,20 @@ const useStyles = makeStyles(theme => ({
|
|
|
54
61
|
type LGV = Instance<LinearGenomeViewStateModel>
|
|
55
62
|
|
|
56
63
|
const TrackLabel = React.forwardRef(
|
|
57
|
-
(
|
|
64
|
+
(
|
|
65
|
+
{ track, className }: { track: BaseTrackModel; className?: string },
|
|
66
|
+
ref,
|
|
67
|
+
) => {
|
|
58
68
|
const classes = useStyles()
|
|
59
|
-
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null)
|
|
60
|
-
const { track, className } = props
|
|
61
69
|
const view = getContainingView(track) as LGV
|
|
62
70
|
const session = getSession(track)
|
|
63
71
|
const trackConf = track.configuration
|
|
64
72
|
const trackId = getConf(track, 'trackId')
|
|
65
73
|
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const handleClose = () => {
|
|
71
|
-
setAnchorEl(null)
|
|
72
|
-
}
|
|
74
|
+
const popupState = usePopupState({
|
|
75
|
+
popupId: 'trackLabelMenu',
|
|
76
|
+
variant: 'popover',
|
|
77
|
+
})
|
|
73
78
|
|
|
74
79
|
const onDragStart = (event: React.DragEvent<HTMLSpanElement>) => {
|
|
75
80
|
const target = event.target as HTMLElement
|
|
@@ -91,17 +96,12 @@ const TrackLabel = React.forwardRef(
|
|
|
91
96
|
if (getConf(track, 'type') === 'ReferenceSequenceTrack') {
|
|
92
97
|
const r = session.assemblies.find(a => a.sequence === trackConf)
|
|
93
98
|
trackName =
|
|
94
|
-
|
|
99
|
+
trackName ||
|
|
95
100
|
(r
|
|
96
101
|
? `Reference Sequence (${readConfObject(r, 'name')})`
|
|
97
102
|
: 'Reference Sequence')
|
|
98
103
|
}
|
|
99
104
|
|
|
100
|
-
function handleMenuItemClick(_: unknown, callback: Function) {
|
|
101
|
-
callback()
|
|
102
|
-
handleClose()
|
|
103
|
-
}
|
|
104
|
-
|
|
105
105
|
const items = [
|
|
106
106
|
...(session.getTrackActionMenuItems?.(trackConf) || []),
|
|
107
107
|
...track.trackMenuItems(),
|
|
@@ -135,9 +135,7 @@ const TrackLabel = React.forwardRef(
|
|
|
135
135
|
{trackName}
|
|
136
136
|
</Typography>
|
|
137
137
|
<IconButton
|
|
138
|
-
|
|
139
|
-
aria-haspopup="true"
|
|
140
|
-
onClick={handleClick}
|
|
138
|
+
{...bindTrigger(popupState)}
|
|
141
139
|
className={classes.iconButton}
|
|
142
140
|
color="secondary"
|
|
143
141
|
data-testid="track_menu_icon"
|
|
@@ -146,12 +144,11 @@ const TrackLabel = React.forwardRef(
|
|
|
146
144
|
<MoreVertIcon />
|
|
147
145
|
</IconButton>
|
|
148
146
|
</Paper>
|
|
149
|
-
<
|
|
150
|
-
|
|
151
|
-
onMenuItemClick={
|
|
152
|
-
open={Boolean(anchorEl)}
|
|
153
|
-
onClose={handleClose}
|
|
147
|
+
<CascadingMenu
|
|
148
|
+
{...bindPopover(popupState)}
|
|
149
|
+
onMenuItemClick={(_: unknown, callback: Function) => callback()}
|
|
154
150
|
menuItems={items}
|
|
151
|
+
popupState={popupState}
|
|
155
152
|
/>
|
|
156
153
|
</>
|
|
157
154
|
)
|
|
@@ -255,8 +255,7 @@ exports[`<LinearGenomeView /> renders one track, one region 1`] = `
|
|
|
255
255
|
<p
|
|
256
256
|
class="MuiTypography-root makeStyles-bp MuiTypography-body2 MuiTypography-colorTextSecondary"
|
|
257
257
|
>
|
|
258
|
-
|
|
259
|
-
bp
|
|
258
|
+
100bp
|
|
260
259
|
</p>
|
|
261
260
|
<div
|
|
262
261
|
class="makeStyles-container"
|
|
@@ -425,13 +424,7 @@ exports[`<LinearGenomeView /> renders one track, one region 1`] = `
|
|
|
425
424
|
<div
|
|
426
425
|
class="makeStyles-tick"
|
|
427
426
|
style="left: -1px;"
|
|
428
|
-
|
|
429
|
-
<p
|
|
430
|
-
class="MuiTypography-root makeStyles-majorTickLabel MuiTypography-body1"
|
|
431
|
-
>
|
|
432
|
-
0
|
|
433
|
-
</p>
|
|
434
|
-
</div>
|
|
427
|
+
/>
|
|
435
428
|
</div>
|
|
436
429
|
<div
|
|
437
430
|
class="makeStyles-boundaryPaddingBlock"
|
|
@@ -500,7 +493,6 @@ exports[`<LinearGenomeView /> renders one track, one region 1`] = `
|
|
|
500
493
|
Foo Track
|
|
501
494
|
</span>
|
|
502
495
|
<button
|
|
503
|
-
aria-controls="simple-menu"
|
|
504
496
|
aria-haspopup="true"
|
|
505
497
|
class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary"
|
|
506
498
|
data-testid="track_menu_icon"
|
|
@@ -850,8 +842,7 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
850
842
|
<p
|
|
851
843
|
class="MuiTypography-root makeStyles-bp MuiTypography-body2 MuiTypography-colorTextSecondary"
|
|
852
844
|
>
|
|
853
|
-
|
|
854
|
-
bp
|
|
845
|
+
798bp
|
|
855
846
|
</p>
|
|
856
847
|
<div
|
|
857
848
|
class="makeStyles-container"
|
|
@@ -1239,13 +1230,7 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
1239
1230
|
<div
|
|
1240
1231
|
class="makeStyles-tick"
|
|
1241
1232
|
style="left: -1px;"
|
|
1242
|
-
|
|
1243
|
-
<p
|
|
1244
|
-
class="MuiTypography-root makeStyles-majorTickLabel MuiTypography-body1"
|
|
1245
|
-
>
|
|
1246
|
-
0
|
|
1247
|
-
</p>
|
|
1248
|
-
</div>
|
|
1233
|
+
/>
|
|
1249
1234
|
</div>
|
|
1250
1235
|
<div
|
|
1251
1236
|
class="makeStyles-interRegionPaddingBlock"
|
|
@@ -1390,7 +1375,6 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
1390
1375
|
Foo Track
|
|
1391
1376
|
</span>
|
|
1392
1377
|
<button
|
|
1393
|
-
aria-controls="simple-menu"
|
|
1394
1378
|
aria-haspopup="true"
|
|
1395
1379
|
class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary"
|
|
1396
1380
|
data-testid="track_menu_icon"
|
|
@@ -1533,7 +1517,6 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
1533
1517
|
Bar Track
|
|
1534
1518
|
</span>
|
|
1535
1519
|
<button
|
|
1536
|
-
aria-controls="simple-menu"
|
|
1537
1520
|
aria-haspopup="true"
|
|
1538
1521
|
class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary"
|
|
1539
1522
|
data-testid="track_menu_icon"
|
|
@@ -72,7 +72,7 @@ function initialize() {
|
|
|
72
72
|
})
|
|
73
73
|
.actions(self => ({
|
|
74
74
|
isValidRefName(str: string) {
|
|
75
|
-
return
|
|
75
|
+
return str === 'ctgA' || str === 'ctgB'
|
|
76
76
|
},
|
|
77
77
|
get(str: string) {
|
|
78
78
|
return self.assemblies.get(str)
|
|
@@ -989,8 +989,23 @@ test('multi region', () => {
|
|
|
989
989
|
model.navToLocString('ctgA ctgB')
|
|
990
990
|
expect(model.displayedRegions[0].refName).toBe('ctgA')
|
|
991
991
|
expect(model.displayedRegions[1].refName).toBe('ctgB')
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
992
|
+
})
|
|
993
|
+
|
|
994
|
+
test('space separated locstring', () => {
|
|
995
|
+
const { Session, LinearGenomeModel } = initialize()
|
|
996
|
+
const model = Session.create({
|
|
997
|
+
configuration: {},
|
|
998
|
+
}).setView(
|
|
999
|
+
LinearGenomeModel.create({
|
|
1000
|
+
type: 'LinearGenomeView',
|
|
1001
|
+
tracks: [{ name: 'foo track', type: 'BasicTrack' }],
|
|
1002
|
+
}),
|
|
1003
|
+
)
|
|
1004
|
+
model.setWidth(800)
|
|
1005
|
+
model.setDisplayedRegions(volvoxDisplayedRegions.slice(0, 1))
|
|
1006
|
+
|
|
1007
|
+
model.navToLocString('ctgA 0 100')
|
|
1008
|
+
|
|
1009
|
+
expect(model.offsetPx).toBe(0)
|
|
1010
|
+
expect(model.bpPerPx).toBe(0.125)
|
|
996
1011
|
})
|
|
@@ -67,6 +67,7 @@ export interface BpOffset {
|
|
|
67
67
|
|
|
68
68
|
export interface ExportSvgOptions {
|
|
69
69
|
rasterizeLayers?: boolean
|
|
70
|
+
filename?: string
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
function calculateVisibleLocStrings(contentBlocks: BaseBlock[]) {
|
|
@@ -126,6 +127,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
126
127
|
),
|
|
127
128
|
hideHeader: false,
|
|
128
129
|
hideHeaderOverview: false,
|
|
130
|
+
hideNoTracksActive: false,
|
|
129
131
|
trackSelectorType: types.optional(
|
|
130
132
|
types.enumeration(['hierarchical']),
|
|
131
133
|
'hierarchical',
|
|
@@ -176,11 +178,18 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
176
178
|
get interRegionPaddingWidth() {
|
|
177
179
|
return INTER_REGION_PADDING_WIDTH
|
|
178
180
|
},
|
|
181
|
+
|
|
182
|
+
get assemblyNames() {
|
|
183
|
+
return [
|
|
184
|
+
...new Set(self.displayedRegions.map(region => region.assemblyName)),
|
|
185
|
+
]
|
|
186
|
+
},
|
|
179
187
|
}))
|
|
180
188
|
.views(self => ({
|
|
181
189
|
get assemblyErrors() {
|
|
182
190
|
const { assemblyManager } = getSession(self)
|
|
183
|
-
|
|
191
|
+
const { assemblyNames } = self
|
|
192
|
+
return assemblyNames
|
|
184
193
|
.map(a => assemblyManager.get(a)?.error)
|
|
185
194
|
.filter(f => !!f)
|
|
186
195
|
.join(', ')
|
|
@@ -188,9 +197,8 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
188
197
|
|
|
189
198
|
get assembliesInitialized() {
|
|
190
199
|
const { assemblyManager } = getSession(self)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
)
|
|
200
|
+
const { assemblyNames } = self
|
|
201
|
+
return assemblyNames.every(a => assemblyManager.get(a)?.initialized)
|
|
194
202
|
},
|
|
195
203
|
get initialized() {
|
|
196
204
|
return self.volatileWidth !== undefined && this.assembliesInitialized
|
|
@@ -272,11 +280,6 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
272
280
|
}
|
|
273
281
|
},
|
|
274
282
|
|
|
275
|
-
get assemblyNames() {
|
|
276
|
-
return [
|
|
277
|
-
...new Set(self.displayedRegions.map(region => region.assemblyName)),
|
|
278
|
-
]
|
|
279
|
-
},
|
|
280
283
|
searchScope(assemblyName: string) {
|
|
281
284
|
return {
|
|
282
285
|
assemblyName,
|
|
@@ -285,13 +288,6 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
285
288
|
}
|
|
286
289
|
},
|
|
287
290
|
|
|
288
|
-
/**
|
|
289
|
-
* @param refName - refName of the displayedRegion
|
|
290
|
-
* @param coord - coordinate at the displayed Region
|
|
291
|
-
* @param regionNumber - optional param used as identifier when
|
|
292
|
-
* there are multiple displayedRegions with the same refName
|
|
293
|
-
* @returns offsetPx of the displayed region that it lands in
|
|
294
|
-
*/
|
|
295
291
|
bpToPx({
|
|
296
292
|
refName,
|
|
297
293
|
coord,
|
|
@@ -395,10 +391,8 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
395
391
|
track => track.configuration.trackId,
|
|
396
392
|
)
|
|
397
393
|
results.forEach(result => {
|
|
398
|
-
if (openTrackIds
|
|
399
|
-
|
|
400
|
-
result.updateScore(result.getScore() + 1)
|
|
401
|
-
}
|
|
394
|
+
if (openTrackIds.includes(result.trackId)) {
|
|
395
|
+
result.updateScore(result.getScore() + 1)
|
|
402
396
|
}
|
|
403
397
|
})
|
|
404
398
|
return results
|
|
@@ -406,7 +400,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
406
400
|
|
|
407
401
|
// modifies view menu action onClick to apply to all tracks of same type
|
|
408
402
|
rewriteOnClicks(trackType: string, viewMenuActions: MenuItem[]) {
|
|
409
|
-
viewMenuActions.forEach(
|
|
403
|
+
viewMenuActions.forEach(action => {
|
|
410
404
|
// go to lowest level menu
|
|
411
405
|
if ('subMenu' in action) {
|
|
412
406
|
this.rewriteOnClicks(trackType, action.subMenu)
|
|
@@ -463,6 +457,9 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
463
457
|
toggleHeaderOverview() {
|
|
464
458
|
self.hideHeaderOverview = !self.hideHeaderOverview
|
|
465
459
|
},
|
|
460
|
+
toggleNoTracksActive() {
|
|
461
|
+
self.hideNoTracksActive = !self.hideNoTracksActive
|
|
462
|
+
},
|
|
466
463
|
|
|
467
464
|
scrollTo(offsetPx: number) {
|
|
468
465
|
const newOffsetPx = clamp(offsetPx, self.minOffset, self.maxOffset)
|
|
@@ -674,13 +671,38 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
674
671
|
const { assemblyManager } = getSession(self)
|
|
675
672
|
const { isValidRefName } = assemblyManager
|
|
676
673
|
const assemblyName = optAssemblyName || assemblyNames[0]
|
|
674
|
+
let parsedLocStrings
|
|
675
|
+
const inputs = locString
|
|
676
|
+
.split(/(\s+)/)
|
|
677
|
+
.map(f => f.trim())
|
|
678
|
+
.filter(f => !!f)
|
|
677
679
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
.map(l =>
|
|
680
|
+
// first try interpreting as a whitespace-separated sequence of
|
|
681
|
+
// multiple locstrings
|
|
682
|
+
try {
|
|
683
|
+
parsedLocStrings = inputs.map(l =>
|
|
684
|
+
parseLocString(l, ref => isValidRefName(ref, assemblyName)),
|
|
685
|
+
)
|
|
686
|
+
} catch (e) {
|
|
687
|
+
// if this fails, try interpreting as a whitespace-separated refname,
|
|
688
|
+
// start, end if start and end are integer inputs
|
|
689
|
+
const [refName, start, end] = inputs
|
|
690
|
+
if (
|
|
691
|
+
`${e}`.match(/Unknown reference sequence/) &&
|
|
692
|
+
Number.isInteger(+start) &&
|
|
693
|
+
Number.isInteger(+end)
|
|
694
|
+
) {
|
|
695
|
+
parsedLocStrings = [
|
|
696
|
+
parseLocString(refName + ':' + start + '..' + end, ref =>
|
|
697
|
+
isValidRefName(ref, assemblyName),
|
|
698
|
+
),
|
|
699
|
+
]
|
|
700
|
+
} else {
|
|
701
|
+
throw e
|
|
702
|
+
}
|
|
703
|
+
}
|
|
682
704
|
|
|
683
|
-
const locations = parsedLocStrings
|
|
705
|
+
const locations = parsedLocStrings?.map(region => {
|
|
684
706
|
const asmName = region.assemblyName || assemblyName
|
|
685
707
|
const asm = assemblyManager.get(asmName)
|
|
686
708
|
const { refName } = region
|
|
@@ -1206,6 +1228,13 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
1206
1228
|
onClick: self.toggleHeaderOverview,
|
|
1207
1229
|
disabled: self.hideHeader,
|
|
1208
1230
|
},
|
|
1231
|
+
{
|
|
1232
|
+
label: 'Show no tracks active button',
|
|
1233
|
+
icon: VisibilityIcon,
|
|
1234
|
+
type: 'checkbox',
|
|
1235
|
+
checked: !self.hideNoTracksActive,
|
|
1236
|
+
onClick: self.toggleNoTracksActive,
|
|
1237
|
+
},
|
|
1209
1238
|
{
|
|
1210
1239
|
label: 'Track labels',
|
|
1211
1240
|
icon: LabelIcon,
|
|
@@ -1330,7 +1359,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
1330
1359
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1331
1360
|
const html = await renderToSvg(self as any, opts)
|
|
1332
1361
|
const blob = new Blob([html], { type: 'image/svg+xml' })
|
|
1333
|
-
saveAs(blob, 'image.svg')
|
|
1362
|
+
saveAs(blob, opts.filename || 'image.svg')
|
|
1334
1363
|
},
|
|
1335
1364
|
}))
|
|
1336
1365
|
.views(self => ({
|
package/src/index.ts
CHANGED
|
@@ -137,42 +137,47 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
137
137
|
loc: string
|
|
138
138
|
tracks?: string[]
|
|
139
139
|
}) => {
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
try {
|
|
141
|
+
const { assemblyManager } = session
|
|
142
|
+
const view = session.addView('LinearGenomeView', {}) as LGV
|
|
142
143
|
|
|
143
|
-
|
|
144
|
+
await when(() => !!view.volatileWidth)
|
|
144
145
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
146
|
+
if (!assembly) {
|
|
147
|
+
throw new Error(
|
|
148
|
+
'No assembly provided when launching linear genome view',
|
|
149
|
+
)
|
|
150
|
+
}
|
|
150
151
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
152
|
+
const asm = await assemblyManager.waitForAssembly(assembly)
|
|
153
|
+
if (!asm) {
|
|
154
|
+
throw new Error(
|
|
155
|
+
`Assembly "${assembly}" not found when launching linear genome view`,
|
|
156
|
+
)
|
|
157
|
+
}
|
|
157
158
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
159
|
+
view.navToLocString(loc, assembly)
|
|
160
|
+
|
|
161
|
+
const idsNotFound = [] as string[]
|
|
162
|
+
tracks.forEach(track => {
|
|
163
|
+
try {
|
|
164
|
+
view.showTrack(track)
|
|
165
|
+
} catch (e) {
|
|
166
|
+
if (`${e}`.match('Could not resolve identifier')) {
|
|
167
|
+
idsNotFound.push(track)
|
|
168
|
+
} else {
|
|
169
|
+
throw e
|
|
170
|
+
}
|
|
169
171
|
}
|
|
172
|
+
})
|
|
173
|
+
if (idsNotFound.length) {
|
|
174
|
+
throw new Error(
|
|
175
|
+
`Could not resolve identifiers: ${idsNotFound.join(',')}`,
|
|
176
|
+
)
|
|
170
177
|
}
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
throw
|
|
174
|
-
`Could not resolve identifiers: ${idsNotFound.join(',')}`,
|
|
175
|
-
)
|
|
178
|
+
} catch (e) {
|
|
179
|
+
session.notify(`${e}`, 'error')
|
|
180
|
+
throw e
|
|
176
181
|
}
|
|
177
182
|
},
|
|
178
183
|
)
|