@jbrowse/plugin-linear-genome-view 1.6.4 → 1.6.7
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/LinearBlocks.d.ts +0 -5
- package/dist/BaseLinearDisplay/models/baseLinearDisplayConfigSchema.d.ts +1 -1
- package/dist/LinearBareDisplay/configSchema.d.ts +1 -1
- package/dist/LinearBasicDisplay/configSchema.d.ts +1 -1
- package/dist/LinearGenomeView/components/ScaleBar.d.ts +2 -0
- package/dist/LinearGenomeView/components/TrackContainer.d.ts +1 -1
- package/dist/LinearGenomeView/index.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/plugin-linear-genome-view.cjs.development.js +147 -249
- package/dist/plugin-linear-genome-view.cjs.development.js.map +1 -1
- package/dist/plugin-linear-genome-view.cjs.production.min.js +1 -1
- package/dist/plugin-linear-genome-view.cjs.production.min.js.map +1 -1
- package/dist/plugin-linear-genome-view.esm.js +149 -251
- package/dist/plugin-linear-genome-view.esm.js.map +1 -1
- package/package.json +2 -2
- package/src/BaseLinearDisplay/components/BaseLinearDisplay.tsx +2 -4
- package/src/BaseLinearDisplay/components/LinearBlocks.tsx +4 -8
- package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +11 -3
- package/src/LinearBasicDisplay/model.ts +1 -1
- package/src/LinearGenomeView/components/HelpDialog.tsx +14 -1
- package/src/LinearGenomeView/components/LinearGenomeViewSvg.tsx +1 -13
- package/src/LinearGenomeView/components/OverviewScaleBar.tsx +7 -3
- package/src/LinearGenomeView/components/TrackContainer.tsx +35 -38
- package/src/LinearGenomeView/components/TrackLabel.tsx +5 -5
- package/src/LinearGenomeView/components/TracksContainer.tsx +0 -1
- package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.js.snap +23 -26
- package/src/LinearGenomeView/index.test.ts +44 -42
- package/src/LinearGenomeView/index.tsx +167 -242
- package/src/LinearGenomeView/volvoxDisplayedRegions.json +16 -0
- package/dist/LinearGenomeView/components/ReturnToImportFormDialog.d.ts +0 -9
- package/src/LinearGenomeView/components/ReturnToImportFormDialog.tsx +0 -83
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-linear-genome-view",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.7",
|
|
4
4
|
"description": "JBrowse 2 linear genome view",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"publishConfig": {
|
|
62
62
|
"access": "public"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "02012ec299c36647f755316571775d36b0fee5ec"
|
|
65
65
|
}
|
|
@@ -31,7 +31,7 @@ const useStyles = makeStyles(theme => ({
|
|
|
31
31
|
color: theme.palette.common.white,
|
|
32
32
|
fontFamily: theme.typography.fontFamily,
|
|
33
33
|
padding: '4px 8px',
|
|
34
|
-
fontSize: theme.typography.pxToRem(
|
|
34
|
+
fontSize: theme.typography.pxToRem(12),
|
|
35
35
|
lineHeight: `${round(14 / 10)}em`,
|
|
36
36
|
maxWidth: 300,
|
|
37
37
|
wordWrap: 'break-word',
|
|
@@ -96,9 +96,7 @@ const Tooltip = observer(
|
|
|
96
96
|
{...attributes.popper}
|
|
97
97
|
>
|
|
98
98
|
<TooltipContents
|
|
99
|
-
ref={(elt
|
|
100
|
-
setWidth(elt?.getBoundingClientRect().width || 0)
|
|
101
|
-
}
|
|
99
|
+
ref={elt => setWidth(elt?.getBoundingClientRect().width || 0)}
|
|
102
100
|
message={contents}
|
|
103
101
|
/>
|
|
104
102
|
</div>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import React from 'react'
|
|
1
2
|
import { makeStyles } from '@material-ui/core/styles'
|
|
2
3
|
import { getContainingView } from '@jbrowse/core/util'
|
|
3
|
-
import { observer
|
|
4
|
-
import React from 'react'
|
|
4
|
+
import { observer } from 'mobx-react'
|
|
5
5
|
import {
|
|
6
6
|
ContentBlock,
|
|
7
7
|
ElidedBlock,
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
ElidedBlock as ElidedBlockComponent,
|
|
15
15
|
InterRegionPaddingBlock as InterRegionPaddingBlockComponent,
|
|
16
16
|
} from './Block'
|
|
17
|
+
import { LinearGenomeViewModel } from '../../LinearGenomeView'
|
|
17
18
|
|
|
18
19
|
const useStyles = makeStyles({
|
|
19
20
|
linearBlocks: {
|
|
@@ -96,8 +97,7 @@ const RenderedBlocks = observer(
|
|
|
96
97
|
function LinearBlocks({ model }: { model: BaseLinearDisplayModel }) {
|
|
97
98
|
const classes = useStyles()
|
|
98
99
|
const { blockDefinitions } = model
|
|
99
|
-
|
|
100
|
-
const viewModel = getContainingView(model) as any
|
|
100
|
+
const viewModel = getContainingView(model) as LinearGenomeViewModel
|
|
101
101
|
return (
|
|
102
102
|
<div
|
|
103
103
|
data-testid="Blockset"
|
|
@@ -111,9 +111,5 @@ function LinearBlocks({ model }: { model: BaseLinearDisplayModel }) {
|
|
|
111
111
|
)
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
LinearBlocks.propTypes = {
|
|
115
|
-
model: PropTypes.observableObject.isRequired,
|
|
116
|
-
}
|
|
117
|
-
|
|
118
114
|
export { RenderedBlocks, useStyles }
|
|
119
115
|
export default observer(LinearBlocks)
|
|
@@ -387,7 +387,10 @@ export const BaseLinearDisplay = types
|
|
|
387
387
|
self.setError()
|
|
388
388
|
const aborter = new AbortController()
|
|
389
389
|
const view = getContainingView(self) as LGV
|
|
390
|
-
|
|
390
|
+
|
|
391
|
+
// extra check for contentBlocks.length
|
|
392
|
+
// https://github.com/GMOD/jbrowse-components/issues/2694
|
|
393
|
+
if (!view.initialized || !view.staticBlocks.contentBlocks.length) {
|
|
391
394
|
return
|
|
392
395
|
}
|
|
393
396
|
|
|
@@ -411,7 +414,7 @@ export const BaseLinearDisplay = types
|
|
|
411
414
|
afterAttach() {
|
|
412
415
|
// this autorun performs stats estimation
|
|
413
416
|
//
|
|
414
|
-
// the chain of events calls
|
|
417
|
+
// the chain of events calls estimateRegionsStats against the data
|
|
415
418
|
// adapter which by default uses featureDensity, but can also respond
|
|
416
419
|
// with a byte size estimate and fetch size limit (data adapter can
|
|
417
420
|
// define what is too much data)
|
|
@@ -423,7 +426,12 @@ export const BaseLinearDisplay = types
|
|
|
423
426
|
const aborter = new AbortController()
|
|
424
427
|
const view = getContainingView(self) as LGV
|
|
425
428
|
|
|
426
|
-
|
|
429
|
+
// extra check for contentBlocks.length
|
|
430
|
+
// https://github.com/GMOD/jbrowse-components/issues/2694
|
|
431
|
+
if (
|
|
432
|
+
!view.initialized ||
|
|
433
|
+
!view.staticBlocks.contentBlocks.length
|
|
434
|
+
) {
|
|
427
435
|
return
|
|
428
436
|
}
|
|
429
437
|
|
|
@@ -139,7 +139,7 @@ const stateModelFactory = (configSchema: AnyConfigurationSchemaType) =>
|
|
|
139
139
|
{
|
|
140
140
|
label: 'Set max height',
|
|
141
141
|
onClick: () => {
|
|
142
|
-
getSession(self).queueDialog(
|
|
142
|
+
getSession(self).queueDialog(doneCallback => [
|
|
143
143
|
SetMaxHeightDlg,
|
|
144
144
|
{ model: self, handleClose: doneCallback },
|
|
145
145
|
])
|
|
@@ -53,7 +53,9 @@ export default function HelpDialog({
|
|
|
53
53
|
<li>
|
|
54
54
|
Jump to a specific region by typing the region into the location box
|
|
55
55
|
as: <code>ref:start..end</code> or <code>ref:start-end</code>.
|
|
56
|
-
Commas are allowed in the start and end coordinates.
|
|
56
|
+
Commas are allowed in the start and end coordinates. A
|
|
57
|
+
space-separated list of locstrings can be used to open up multiple
|
|
58
|
+
chromosomes at a time
|
|
57
59
|
</li>
|
|
58
60
|
</ul>
|
|
59
61
|
<h3>Example Searches</h3>
|
|
@@ -68,6 +70,17 @@ export default function HelpDialog({
|
|
|
68
70
|
<code>chr4:79,500,000..80,000,000</code> - jumps the region on
|
|
69
71
|
chromosome 4 between 79.5Mb and 80Mb.
|
|
70
72
|
</li>
|
|
73
|
+
<li>
|
|
74
|
+
<code>chr1:1-100 chr2:1-100</code> - create a split view of
|
|
75
|
+
chr1:1-100 and chr2:1-100
|
|
76
|
+
</li>
|
|
77
|
+
<li>
|
|
78
|
+
<code>chr1 chr2 chr3</code> - open up multiple chromosomes at once
|
|
79
|
+
</li>
|
|
80
|
+
<li>
|
|
81
|
+
<code>chr1:1-100[rev] chr2:1-100</code> - open up the first region
|
|
82
|
+
in the horizontally flipped orientation
|
|
83
|
+
</li>
|
|
71
84
|
</ul>
|
|
72
85
|
</DialogContent>
|
|
73
86
|
<Divider />
|
|
@@ -3,7 +3,7 @@ import { renderToStaticMarkup } from 'react-dom/server'
|
|
|
3
3
|
import { when } from 'mobx'
|
|
4
4
|
import { getParent } from 'mobx-state-tree'
|
|
5
5
|
import { getConf, readConfObject } from '@jbrowse/core/configuration'
|
|
6
|
-
import { getSession } from '@jbrowse/core/util'
|
|
6
|
+
import { getSession, getBpDisplayStr } from '@jbrowse/core/util'
|
|
7
7
|
import { AnyConfigurationModel } from '@jbrowse/core/configuration/configurationSchema'
|
|
8
8
|
import Base1DView from '@jbrowse/core/util/Base1DViewModel'
|
|
9
9
|
|
|
@@ -18,18 +18,6 @@ import { Polygon, Cytobands } from './OverviewScaleBar'
|
|
|
18
18
|
|
|
19
19
|
type LGV = LinearGenomeViewModel
|
|
20
20
|
|
|
21
|
-
function getBpDisplayStr(totalBp: number) {
|
|
22
|
-
let displayBp
|
|
23
|
-
if (Math.floor(totalBp / 1000000) > 0) {
|
|
24
|
-
displayBp = `${parseFloat((totalBp / 1000000).toPrecision(3))}Mbp`
|
|
25
|
-
} else if (Math.floor(totalBp / 1000) > 0) {
|
|
26
|
-
displayBp = `${parseFloat((totalBp / 1000).toPrecision(3))}Kbp`
|
|
27
|
-
} else {
|
|
28
|
-
displayBp = `${Math.floor(totalBp)}bp`
|
|
29
|
-
}
|
|
30
|
-
return displayBp
|
|
31
|
-
}
|
|
32
|
-
|
|
33
21
|
function ScaleBar({ model, fontSize }: { model: LGV; fontSize: number }) {
|
|
34
22
|
const {
|
|
35
23
|
offsetPx,
|
|
@@ -181,7 +181,7 @@ const Cytobands = observer(
|
|
|
181
181
|
assembly?: Assembly
|
|
182
182
|
block: ContentBlock
|
|
183
183
|
}) => {
|
|
184
|
-
const { offsetPx } = block
|
|
184
|
+
const { offsetPx, reversed } = block
|
|
185
185
|
const cytobands = assembly?.cytobands
|
|
186
186
|
?.map(f => ({
|
|
187
187
|
refName: assembly.getCanonicalRefName(f.get('refName')),
|
|
@@ -205,6 +205,10 @@ const Cytobands = observer(
|
|
|
205
205
|
]
|
|
206
206
|
})
|
|
207
207
|
|
|
208
|
+
const arr = cytobands || []
|
|
209
|
+
const lcap = reversed ? arr.length - 1 : 0
|
|
210
|
+
const rcap = reversed ? 0 : arr.length - 1
|
|
211
|
+
|
|
208
212
|
let firstCent = true
|
|
209
213
|
return cytobands ? (
|
|
210
214
|
<g transform={`translate(-${offsetPx})`}>
|
|
@@ -238,7 +242,7 @@ const Cytobands = observer(
|
|
|
238
242
|
)
|
|
239
243
|
}
|
|
240
244
|
|
|
241
|
-
if (
|
|
245
|
+
if (lcap === index) {
|
|
242
246
|
return (
|
|
243
247
|
<path
|
|
244
248
|
key={key}
|
|
@@ -252,7 +256,7 @@ const Cytobands = observer(
|
|
|
252
256
|
fill={colorMap[type]}
|
|
253
257
|
/>
|
|
254
258
|
)
|
|
255
|
-
} else if (
|
|
259
|
+
} else if (rcap === index) {
|
|
256
260
|
return (
|
|
257
261
|
<path
|
|
258
262
|
key={key}
|
|
@@ -4,7 +4,7 @@ import { isAlive } from 'mobx-state-tree'
|
|
|
4
4
|
import { BaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models'
|
|
5
5
|
import { getConf } from '@jbrowse/core/configuration'
|
|
6
6
|
import { ResizeHandle } from '@jbrowse/core/ui'
|
|
7
|
-
import { useDebouncedCallback
|
|
7
|
+
import { useDebouncedCallback } from '@jbrowse/core/util'
|
|
8
8
|
import clsx from 'clsx'
|
|
9
9
|
import Paper from '@material-ui/core/Paper'
|
|
10
10
|
import { makeStyles } from '@material-ui/core/styles'
|
|
@@ -13,7 +13,9 @@ import { LinearGenomeViewModel, RESIZE_HANDLE_HEIGHT } from '..'
|
|
|
13
13
|
import TrackLabel from './TrackLabel'
|
|
14
14
|
|
|
15
15
|
const useStyles = makeStyles(theme => ({
|
|
16
|
-
root: {
|
|
16
|
+
root: {
|
|
17
|
+
margin: 2,
|
|
18
|
+
},
|
|
17
19
|
resizeHandle: {
|
|
18
20
|
height: RESIZE_HANDLE_HEIGHT,
|
|
19
21
|
boxSizing: 'border-box',
|
|
@@ -29,16 +31,8 @@ const useStyles = makeStyles(theme => ({
|
|
|
29
31
|
zIndex: 3,
|
|
30
32
|
borderRadius: theme.shape.borderRadius,
|
|
31
33
|
},
|
|
32
|
-
renderingComponentContainer: {
|
|
33
|
-
position: 'absolute',
|
|
34
|
-
// -1 offset because of the 1px border of the Paper
|
|
35
|
-
left: -1,
|
|
36
|
-
height: '100%',
|
|
37
|
-
width: '100%',
|
|
38
|
-
},
|
|
39
34
|
trackLabel: {
|
|
40
35
|
zIndex: 3,
|
|
41
|
-
margin: theme.spacing(1),
|
|
42
36
|
},
|
|
43
37
|
trackLabelInline: {
|
|
44
38
|
position: 'relative',
|
|
@@ -60,16 +54,37 @@ const useStyles = makeStyles(theme => ({
|
|
|
60
54
|
|
|
61
55
|
type LGV = LinearGenomeViewModel
|
|
62
56
|
|
|
63
|
-
function
|
|
57
|
+
function TrackContainerLabel({
|
|
58
|
+
model,
|
|
59
|
+
view,
|
|
60
|
+
}: {
|
|
61
|
+
model: BaseTrackModel
|
|
62
|
+
view: LGV
|
|
63
|
+
}) {
|
|
64
|
+
const classes = useStyles()
|
|
65
|
+
const labelStyle =
|
|
66
|
+
view.trackLabels === 'overlapping'
|
|
67
|
+
? classes.trackLabelOverlap
|
|
68
|
+
: classes.trackLabelInline
|
|
69
|
+
return view.trackLabels !== 'hidden' ? (
|
|
70
|
+
<TrackLabel
|
|
71
|
+
track={model}
|
|
72
|
+
className={clsx(classes.trackLabel, labelStyle)}
|
|
73
|
+
/>
|
|
74
|
+
) : null
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function TrackContainer({
|
|
78
|
+
model,
|
|
79
|
+
track,
|
|
80
|
+
}: {
|
|
64
81
|
model: LinearGenomeViewModel
|
|
65
82
|
track: BaseTrackModel
|
|
66
83
|
}) {
|
|
67
84
|
const classes = useStyles()
|
|
68
|
-
const { model, track } = props
|
|
69
85
|
const display = track.displays[0]
|
|
70
86
|
const { horizontalScroll, draggingTrackId, moveTrack } = model
|
|
71
87
|
const { height } = display
|
|
72
|
-
const view = getContainingView(display) as LGV
|
|
73
88
|
const trackId = getConf(track, 'trackId')
|
|
74
89
|
const ref = useRef(null)
|
|
75
90
|
|
|
@@ -95,21 +110,9 @@ function TrackContainer(props: {
|
|
|
95
110
|
const dimmed = draggingTrackId !== undefined && draggingTrackId !== display.id
|
|
96
111
|
|
|
97
112
|
return (
|
|
98
|
-
<
|
|
99
|
-
{view
|
|
100
|
-
|
|
101
|
-
track={track}
|
|
102
|
-
className={clsx(
|
|
103
|
-
classes.trackLabel,
|
|
104
|
-
view.trackLabels === 'overlapping'
|
|
105
|
-
? classes.trackLabelOverlap
|
|
106
|
-
: classes.trackLabelInline,
|
|
107
|
-
)}
|
|
108
|
-
/>
|
|
109
|
-
) : null}
|
|
110
|
-
|
|
111
|
-
<Paper
|
|
112
|
-
variant="outlined"
|
|
113
|
+
<Paper className={classes.root} variant="outlined">
|
|
114
|
+
<TrackContainerLabel model={track} view={model} />
|
|
115
|
+
<div
|
|
113
116
|
className={classes.trackRenderingContainer}
|
|
114
117
|
style={{ height }}
|
|
115
118
|
onScroll={event => {
|
|
@@ -117,17 +120,12 @@ function TrackContainer(props: {
|
|
|
117
120
|
display.setScrollTop(target.scrollTop)
|
|
118
121
|
}}
|
|
119
122
|
onDragEnter={debouncedOnDragEnter}
|
|
120
|
-
data-testid={`trackRenderingContainer-${
|
|
123
|
+
data-testid={`trackRenderingContainer-${model.id}-${trackId}`}
|
|
121
124
|
role="presentation"
|
|
122
125
|
>
|
|
123
|
-
<div
|
|
124
|
-
ref={ref}
|
|
125
|
-
className={classes.renderingComponentContainer}
|
|
126
|
-
style={{ transform: `scaleX(${model.scaleFactor})` }}
|
|
127
|
-
>
|
|
126
|
+
<div ref={ref} style={{ transform: `scaleX(${model.scaleFactor})` }}>
|
|
128
127
|
<RenderingComponent
|
|
129
128
|
model={display}
|
|
130
|
-
blockState={{}}
|
|
131
129
|
onHorizontalScroll={horizontalScroll}
|
|
132
130
|
/>
|
|
133
131
|
</div>
|
|
@@ -140,11 +138,10 @@ function TrackContainer(props: {
|
|
|
140
138
|
top: display.height - 20,
|
|
141
139
|
}}
|
|
142
140
|
>
|
|
143
|
-
{' '}
|
|
144
141
|
<DisplayBlurb model={display} />
|
|
145
142
|
</div>
|
|
146
143
|
) : null}
|
|
147
|
-
</
|
|
144
|
+
</div>
|
|
148
145
|
<div
|
|
149
146
|
className={classes.overlay}
|
|
150
147
|
style={{
|
|
@@ -157,7 +154,7 @@ function TrackContainer(props: {
|
|
|
157
154
|
onDrag={display.resizeHeight}
|
|
158
155
|
className={classes.resizeHandle}
|
|
159
156
|
/>
|
|
160
|
-
</
|
|
157
|
+
</Paper>
|
|
161
158
|
)
|
|
162
159
|
}
|
|
163
160
|
|
|
@@ -102,7 +102,10 @@ const TrackLabel = React.forwardRef(
|
|
|
102
102
|
handleClose()
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
const items =
|
|
105
|
+
const items = [
|
|
106
|
+
...session.getTrackActionMenuItems?.(trackConf),
|
|
107
|
+
...track.trackMenuItems(),
|
|
108
|
+
].sort((a, b) => (b.priority || 0) - (a.priority || 0))
|
|
106
109
|
|
|
107
110
|
return (
|
|
108
111
|
<>
|
|
@@ -148,10 +151,7 @@ const TrackLabel = React.forwardRef(
|
|
|
148
151
|
onMenuItemClick={handleMenuItemClick}
|
|
149
152
|
open={Boolean(anchorEl)}
|
|
150
153
|
onClose={handleClose}
|
|
151
|
-
menuItems={
|
|
152
|
-
...session.getTrackActionMenuItems?.(trackConf),
|
|
153
|
-
...items,
|
|
154
|
-
].sort((a, b) => (b.priority || 0) - (a.priority || 0))}
|
|
154
|
+
menuItems={items}
|
|
155
155
|
/>
|
|
156
156
|
</>
|
|
157
157
|
)
|
|
@@ -449,10 +449,7 @@ exports[`<LinearGenomeView /> renders one track, one region 1`] = `
|
|
|
449
449
|
</div>
|
|
450
450
|
</div>
|
|
451
451
|
<div
|
|
452
|
-
class="makeStyles-
|
|
453
|
-
/>
|
|
454
|
-
<div
|
|
455
|
-
class="makeStyles-root"
|
|
452
|
+
class="MuiPaper-root makeStyles-root MuiPaper-outlined MuiPaper-rounded"
|
|
456
453
|
>
|
|
457
454
|
<div
|
|
458
455
|
class="MuiPaper-root makeStyles-trackLabel makeStyles-trackLabelOverlap makeStyles-root MuiPaper-elevation1 MuiPaper-rounded"
|
|
@@ -505,10 +502,9 @@ exports[`<LinearGenomeView /> renders one track, one region 1`] = `
|
|
|
505
502
|
<button
|
|
506
503
|
aria-controls="simple-menu"
|
|
507
504
|
aria-haspopup="true"
|
|
508
|
-
class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary
|
|
505
|
+
class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary"
|
|
509
506
|
data-testid="track_menu_icon"
|
|
510
|
-
|
|
511
|
-
tabindex="-1"
|
|
507
|
+
tabindex="0"
|
|
512
508
|
type="button"
|
|
513
509
|
>
|
|
514
510
|
<span
|
|
@@ -525,16 +521,18 @@ exports[`<LinearGenomeView /> renders one track, one region 1`] = `
|
|
|
525
521
|
/>
|
|
526
522
|
</svg>
|
|
527
523
|
</span>
|
|
524
|
+
<span
|
|
525
|
+
class="MuiTouchRipple-root"
|
|
526
|
+
/>
|
|
528
527
|
</button>
|
|
529
528
|
</div>
|
|
530
529
|
<div
|
|
531
|
-
class="
|
|
530
|
+
class="makeStyles-trackRenderingContainer"
|
|
532
531
|
data-testid="trackRenderingContainer-lgv-testConfig"
|
|
533
532
|
role="presentation"
|
|
534
533
|
style="height: 100px;"
|
|
535
534
|
>
|
|
536
535
|
<div
|
|
537
|
-
class="makeStyles-renderingComponentContainer"
|
|
538
536
|
style="transform: scaleX(1);"
|
|
539
537
|
>
|
|
540
538
|
<div
|
|
@@ -768,7 +766,7 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
768
766
|
class="MuiAutocomplete-root"
|
|
769
767
|
data-testid="autocomplete"
|
|
770
768
|
role="combobox"
|
|
771
|
-
style="width: 255.
|
|
769
|
+
style="width: 255.27500000000003px;"
|
|
772
770
|
>
|
|
773
771
|
<div
|
|
774
772
|
class="MuiFormControl-root MuiTextField-root makeStyles-headerRefName MuiFormControl-fullWidth"
|
|
@@ -788,7 +786,7 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
788
786
|
placeholder="Search for location"
|
|
789
787
|
spellcheck="false"
|
|
790
788
|
type="text"
|
|
791
|
-
value="ctgA:1..100
|
|
789
|
+
value="ctgA:1..100 ctgB:1,001..1,698"
|
|
792
790
|
/>
|
|
793
791
|
<div
|
|
794
792
|
class="MuiInputAdornment-root MuiInputAdornment-positionEnd"
|
|
@@ -1341,10 +1339,7 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
1341
1339
|
</div>
|
|
1342
1340
|
</div>
|
|
1343
1341
|
<div
|
|
1344
|
-
class="makeStyles-
|
|
1345
|
-
/>
|
|
1346
|
-
<div
|
|
1347
|
-
class="makeStyles-root"
|
|
1342
|
+
class="MuiPaper-root makeStyles-root MuiPaper-outlined MuiPaper-rounded"
|
|
1348
1343
|
>
|
|
1349
1344
|
<div
|
|
1350
1345
|
class="MuiPaper-root makeStyles-trackLabel makeStyles-trackLabelOverlap makeStyles-root MuiPaper-elevation1 MuiPaper-rounded"
|
|
@@ -1397,10 +1392,9 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
1397
1392
|
<button
|
|
1398
1393
|
aria-controls="simple-menu"
|
|
1399
1394
|
aria-haspopup="true"
|
|
1400
|
-
class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary
|
|
1395
|
+
class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary"
|
|
1401
1396
|
data-testid="track_menu_icon"
|
|
1402
|
-
|
|
1403
|
-
tabindex="-1"
|
|
1397
|
+
tabindex="0"
|
|
1404
1398
|
type="button"
|
|
1405
1399
|
>
|
|
1406
1400
|
<span
|
|
@@ -1417,16 +1411,18 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
1417
1411
|
/>
|
|
1418
1412
|
</svg>
|
|
1419
1413
|
</span>
|
|
1414
|
+
<span
|
|
1415
|
+
class="MuiTouchRipple-root"
|
|
1416
|
+
/>
|
|
1420
1417
|
</button>
|
|
1421
1418
|
</div>
|
|
1422
1419
|
<div
|
|
1423
|
-
class="
|
|
1420
|
+
class="makeStyles-trackRenderingContainer"
|
|
1424
1421
|
data-testid="trackRenderingContainer-lgv-testConfig"
|
|
1425
1422
|
role="presentation"
|
|
1426
1423
|
style="height: 100px;"
|
|
1427
1424
|
>
|
|
1428
1425
|
<div
|
|
1429
|
-
class="makeStyles-renderingComponentContainer"
|
|
1430
1426
|
style="transform: scaleX(1);"
|
|
1431
1427
|
>
|
|
1432
1428
|
<div
|
|
@@ -1498,7 +1494,7 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
1498
1494
|
/>
|
|
1499
1495
|
</div>
|
|
1500
1496
|
<div
|
|
1501
|
-
class="makeStyles-root"
|
|
1497
|
+
class="MuiPaper-root makeStyles-root MuiPaper-outlined MuiPaper-rounded"
|
|
1502
1498
|
>
|
|
1503
1499
|
<div
|
|
1504
1500
|
class="MuiPaper-root makeStyles-trackLabel makeStyles-trackLabelOverlap makeStyles-root MuiPaper-elevation1 MuiPaper-rounded"
|
|
@@ -1551,10 +1547,9 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
1551
1547
|
<button
|
|
1552
1548
|
aria-controls="simple-menu"
|
|
1553
1549
|
aria-haspopup="true"
|
|
1554
|
-
class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary
|
|
1550
|
+
class="MuiButtonBase-root MuiIconButton-root makeStyles-iconButton MuiIconButton-colorSecondary"
|
|
1555
1551
|
data-testid="track_menu_icon"
|
|
1556
|
-
|
|
1557
|
-
tabindex="-1"
|
|
1552
|
+
tabindex="0"
|
|
1558
1553
|
type="button"
|
|
1559
1554
|
>
|
|
1560
1555
|
<span
|
|
@@ -1571,16 +1566,18 @@ exports[`<LinearGenomeView /> renders two tracks, two regions 1`] = `
|
|
|
1571
1566
|
/>
|
|
1572
1567
|
</svg>
|
|
1573
1568
|
</span>
|
|
1569
|
+
<span
|
|
1570
|
+
class="MuiTouchRipple-root"
|
|
1571
|
+
/>
|
|
1574
1572
|
</button>
|
|
1575
1573
|
</div>
|
|
1576
1574
|
<div
|
|
1577
|
-
class="
|
|
1575
|
+
class="makeStyles-trackRenderingContainer"
|
|
1578
1576
|
data-testid="trackRenderingContainer-lgv-testConfig2"
|
|
1579
1577
|
role="presentation"
|
|
1580
1578
|
style="height: 100px;"
|
|
1581
1579
|
>
|
|
1582
1580
|
<div
|
|
1583
|
-
class="makeStyles-renderingComponentContainer"
|
|
1584
1581
|
style="transform: scaleX(1);"
|
|
1585
1582
|
>
|
|
1586
1583
|
<div
|
|
@@ -11,6 +11,7 @@ import { LinearGenomeViewStateModel, stateModelFactory } from '.'
|
|
|
11
11
|
import { BaseLinearDisplayComponent } from '..'
|
|
12
12
|
import { stateModelFactory as LinearBasicDisplayStateModelFactory } from '../LinearBareDisplay'
|
|
13
13
|
import hg38DisplayedRegions from './hg38DisplayedRegions.json'
|
|
14
|
+
import volvoxDisplayedRegions from './volvoxDisplayedRegions.json'
|
|
14
15
|
|
|
15
16
|
// use initializer function to avoid having console.warn jest.fn in a global
|
|
16
17
|
function initialize() {
|
|
@@ -54,22 +55,7 @@ function initialize() {
|
|
|
54
55
|
const Assembly = types
|
|
55
56
|
.model({})
|
|
56
57
|
.volatile(() => ({
|
|
57
|
-
regions:
|
|
58
|
-
{
|
|
59
|
-
assemblyName: 'volvox',
|
|
60
|
-
start: 0,
|
|
61
|
-
end: 50001,
|
|
62
|
-
refName: 'ctgA',
|
|
63
|
-
reversed: false,
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
assemblyName: 'volvox',
|
|
67
|
-
start: 0,
|
|
68
|
-
end: 6079,
|
|
69
|
-
refName: 'ctgB',
|
|
70
|
-
reversed: false,
|
|
71
|
-
},
|
|
72
|
-
],
|
|
58
|
+
regions: volvoxDisplayedRegions,
|
|
73
59
|
}))
|
|
74
60
|
.views(() => ({
|
|
75
61
|
getCanonicalRefName(refName: string) {
|
|
@@ -79,6 +65,19 @@ function initialize() {
|
|
|
79
65
|
return refName
|
|
80
66
|
},
|
|
81
67
|
}))
|
|
68
|
+
|
|
69
|
+
const AssemblyManager = types
|
|
70
|
+
.model({
|
|
71
|
+
assemblies: types.map(Assembly),
|
|
72
|
+
})
|
|
73
|
+
.actions(self => ({
|
|
74
|
+
isValidRefName(str: string) {
|
|
75
|
+
return !str.includes(':')
|
|
76
|
+
},
|
|
77
|
+
get(str: string) {
|
|
78
|
+
return self.assemblies.get(str)
|
|
79
|
+
},
|
|
80
|
+
}))
|
|
82
81
|
const LinearGenomeModel = stateModelFactory(stubManager)
|
|
83
82
|
const Session = types
|
|
84
83
|
.model({
|
|
@@ -86,6 +85,13 @@ function initialize() {
|
|
|
86
85
|
rpcManager: 'rpcManagerExists',
|
|
87
86
|
view: types.maybe(LinearGenomeModel),
|
|
88
87
|
configuration: types.map(types.string),
|
|
88
|
+
assemblyManager: types.optional(AssemblyManager, {
|
|
89
|
+
assemblies: {
|
|
90
|
+
volvox: {
|
|
91
|
+
regions: volvoxDisplayedRegions,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
}),
|
|
89
95
|
})
|
|
90
96
|
.actions(self => ({
|
|
91
97
|
setView(view: Instance<LinearGenomeViewStateModel>) {
|
|
@@ -93,9 +99,6 @@ function initialize() {
|
|
|
93
99
|
return view
|
|
94
100
|
},
|
|
95
101
|
}))
|
|
96
|
-
.volatile((/* self */) => ({
|
|
97
|
-
assemblyManager: new Map([['volvox', Assembly.create({})]]),
|
|
98
|
-
}))
|
|
99
102
|
|
|
100
103
|
return { Session, LinearGenomeModel, Assembly }
|
|
101
104
|
}
|
|
@@ -294,29 +297,6 @@ test('can navToMultiple', () => {
|
|
|
294
297
|
])
|
|
295
298
|
expect(model.offsetPx).toBe(2799)
|
|
296
299
|
expect(model.bpPerPx).toBeCloseTo(12.531)
|
|
297
|
-
|
|
298
|
-
expect(() =>
|
|
299
|
-
model.navToMultiple([
|
|
300
|
-
{ refName: 'ctgB', start: 5000, end: 10000 },
|
|
301
|
-
{ refName: 'ctgC', start: 5000, end: 10000 },
|
|
302
|
-
]),
|
|
303
|
-
).toThrow('Start of region ctgC:5,001..10,000 should be 1, but it is not')
|
|
304
|
-
|
|
305
|
-
expect(() =>
|
|
306
|
-
model.navToMultiple([
|
|
307
|
-
{ refName: 'ctgB', start: 0, end: 5000 },
|
|
308
|
-
{ refName: 'ctgC', start: 0, end: 5000 },
|
|
309
|
-
]),
|
|
310
|
-
).toThrow('End of region ctgB:1..5,000 should be 10,000, but it is not')
|
|
311
|
-
|
|
312
|
-
expect(() =>
|
|
313
|
-
model.navToMultiple([
|
|
314
|
-
{ refName: 'ctgA', start: 5000, end: 10000 },
|
|
315
|
-
{ refName: 'ctgA', start: 0, end: 5000 },
|
|
316
|
-
]),
|
|
317
|
-
).toThrow(
|
|
318
|
-
'Entered location ctgA:1..5,000 does not match with displayed regions',
|
|
319
|
-
)
|
|
320
300
|
})
|
|
321
301
|
|
|
322
302
|
describe('Zoom to selected displayed regions', () => {
|
|
@@ -992,3 +972,25 @@ test('navToLocString with human assembly', () => {
|
|
|
992
972
|
expect(model.view.offsetPx).toBe(9914777550)
|
|
993
973
|
model.view.navToLocString('chr3:-1,100,000,000..-1,000,000,000')
|
|
994
974
|
})
|
|
975
|
+
|
|
976
|
+
test('multi region', () => {
|
|
977
|
+
const { Session, LinearGenomeModel } = initialize()
|
|
978
|
+
const model = Session.create({
|
|
979
|
+
configuration: {},
|
|
980
|
+
}).setView(
|
|
981
|
+
LinearGenomeModel.create({
|
|
982
|
+
type: 'LinearGenomeView',
|
|
983
|
+
tracks: [{ name: 'foo track', type: 'BasicTrack' }],
|
|
984
|
+
}),
|
|
985
|
+
)
|
|
986
|
+
model.setWidth(800)
|
|
987
|
+
model.setDisplayedRegions(volvoxDisplayedRegions.slice(0, 1))
|
|
988
|
+
|
|
989
|
+
model.navToLocString('ctgA ctgB')
|
|
990
|
+
expect(model.displayedRegions[0].refName).toBe('ctgA')
|
|
991
|
+
expect(model.displayedRegions[1].refName).toBe('ctgB')
|
|
992
|
+
// [
|
|
993
|
+
// { refName: 'ctgA', start: 0, end: 50001 },
|
|
994
|
+
// { refName: 'ctgB', start: 0, end: 6079 },
|
|
995
|
+
// ])
|
|
996
|
+
})
|