@jbrowse/plugin-linear-genome-view 1.7.9 → 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.js +3 -2
- package/dist/LinearGenomeView/components/Header.js +5 -2
- package/dist/LinearGenomeView/components/HelpDialog.js +2 -3
- 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/ScaleBar.d.ts +6 -2
- package/dist/LinearGenomeView/components/ScaleBar.js +8 -3
- package/dist/LinearGenomeView/components/TrackLabel.js +25 -41
- package/dist/LinearGenomeView/index.d.ts +3 -8
- package/dist/LinearGenomeView/index.js +59 -32
- 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 +10 -4
- package/src/LinearGenomeView/components/Header.tsx +3 -2
- package/src/LinearGenomeView/components/HelpDialog.tsx +5 -4
- 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/ScaleBar.tsx +6 -9
- 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 +54 -26
- package/src/index.ts +35 -30
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import React, { useState, useMemo } from 'react'
|
|
2
|
+
import { getConf } from '@jbrowse/core/configuration'
|
|
3
|
+
import { observer } from 'mobx-react'
|
|
4
|
+
import { Portal, alpha, makeStyles } from '@material-ui/core'
|
|
5
|
+
import { usePopper } from 'react-popper'
|
|
6
|
+
|
|
7
|
+
// locals
|
|
8
|
+
import { BaseLinearDisplayModel } from '../models/BaseLinearDisplayModel'
|
|
9
|
+
|
|
10
|
+
function round(value: number) {
|
|
11
|
+
return Math.round(value * 1e5) / 1e5
|
|
12
|
+
}
|
|
13
|
+
const useStyles = makeStyles(theme => ({
|
|
14
|
+
// these styles come from
|
|
15
|
+
// https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Tooltip/Tooltip.js
|
|
16
|
+
tooltip: {
|
|
17
|
+
pointerEvents: 'none',
|
|
18
|
+
backgroundColor: alpha(theme.palette.grey[700], 0.9),
|
|
19
|
+
borderRadius: theme.shape.borderRadius,
|
|
20
|
+
color: theme.palette.common.white,
|
|
21
|
+
fontFamily: theme.typography.fontFamily,
|
|
22
|
+
padding: '4px 8px',
|
|
23
|
+
fontSize: theme.typography.pxToRem(12),
|
|
24
|
+
lineHeight: `${round(14 / 10)}em`,
|
|
25
|
+
maxWidth: 300,
|
|
26
|
+
wordWrap: 'break-word',
|
|
27
|
+
},
|
|
28
|
+
}))
|
|
29
|
+
|
|
30
|
+
const TooltipContents = React.forwardRef<
|
|
31
|
+
HTMLDivElement,
|
|
32
|
+
{ message: React.ReactNode | string }
|
|
33
|
+
>(({ message }: { message: React.ReactNode | string }, ref) => {
|
|
34
|
+
return <div ref={ref}>{message}</div>
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
type Coord = [number, number]
|
|
38
|
+
const Tooltip = observer(
|
|
39
|
+
({
|
|
40
|
+
model,
|
|
41
|
+
clientMouseCoord,
|
|
42
|
+
}: {
|
|
43
|
+
model: BaseLinearDisplayModel
|
|
44
|
+
clientMouseCoord: Coord
|
|
45
|
+
}) => {
|
|
46
|
+
const classes = useStyles()
|
|
47
|
+
const { featureUnderMouse } = model
|
|
48
|
+
const [width, setWidth] = useState(0)
|
|
49
|
+
const [popperElt, setPopperElt] = useState<HTMLDivElement | null>(null)
|
|
50
|
+
|
|
51
|
+
// must be memoized a la https://github.com/popperjs/react-popper/issues/391
|
|
52
|
+
const virtElement = useMemo(
|
|
53
|
+
() => ({
|
|
54
|
+
getBoundingClientRect: () => {
|
|
55
|
+
const x = clientMouseCoord[0] + width / 2 + 20
|
|
56
|
+
const y = clientMouseCoord[1]
|
|
57
|
+
return {
|
|
58
|
+
top: y,
|
|
59
|
+
left: x,
|
|
60
|
+
bottom: y,
|
|
61
|
+
right: x,
|
|
62
|
+
width: 0,
|
|
63
|
+
height: 0,
|
|
64
|
+
x,
|
|
65
|
+
y,
|
|
66
|
+
toJSON() {},
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
}),
|
|
70
|
+
[clientMouseCoord, width],
|
|
71
|
+
)
|
|
72
|
+
const { styles, attributes } = usePopper(virtElement, popperElt)
|
|
73
|
+
|
|
74
|
+
const contents = featureUnderMouse
|
|
75
|
+
? getConf(model, 'mouseover', { feature: featureUnderMouse })
|
|
76
|
+
: undefined
|
|
77
|
+
|
|
78
|
+
return featureUnderMouse && contents ? (
|
|
79
|
+
<Portal>
|
|
80
|
+
<div
|
|
81
|
+
ref={setPopperElt}
|
|
82
|
+
className={classes.tooltip}
|
|
83
|
+
// zIndex needed to go over widget drawer
|
|
84
|
+
style={{ ...styles.popper, zIndex: 100000 }}
|
|
85
|
+
{...attributes.popper}
|
|
86
|
+
>
|
|
87
|
+
<TooltipContents
|
|
88
|
+
ref={elt => setWidth(elt?.getBoundingClientRect().width || 0)}
|
|
89
|
+
message={contents}
|
|
90
|
+
/>
|
|
91
|
+
</div>
|
|
92
|
+
</Portal>
|
|
93
|
+
) : null
|
|
94
|
+
},
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
export default Tooltip
|
|
@@ -7,6 +7,7 @@ import { MenuItem } from '@jbrowse/core/ui'
|
|
|
7
7
|
import {
|
|
8
8
|
isAbortException,
|
|
9
9
|
getContainingView,
|
|
10
|
+
getContainingTrack,
|
|
10
11
|
getSession,
|
|
11
12
|
getViewParams,
|
|
12
13
|
isSelectionContainer,
|
|
@@ -333,8 +334,13 @@ export const BaseLinearDisplay = types
|
|
|
333
334
|
const featureWidget = session.addWidget(
|
|
334
335
|
'BaseFeatureWidget',
|
|
335
336
|
'baseFeature',
|
|
336
|
-
{
|
|
337
|
+
{
|
|
338
|
+
view: getContainingView(self),
|
|
339
|
+
track: getContainingTrack(self),
|
|
340
|
+
featureData: feature.toJSON(),
|
|
341
|
+
},
|
|
337
342
|
)
|
|
343
|
+
|
|
338
344
|
session.showWidget(featureWidget)
|
|
339
345
|
}
|
|
340
346
|
if (isSelectionContainer(session)) {
|
|
@@ -551,7 +557,7 @@ export const BaseLinearDisplay = types
|
|
|
551
557
|
self.currBpPerPx !== view.bpPerPx || !self.estimatedRegionStats,
|
|
552
558
|
rpcDriverName: self.rpcDriverName,
|
|
553
559
|
displayModel: self,
|
|
554
|
-
onFeatureClick(_: unknown, featureId
|
|
560
|
+
onFeatureClick(_: unknown, featureId?: string) {
|
|
555
561
|
const f = featureId || self.featureIdUnderMouse
|
|
556
562
|
if (!f) {
|
|
557
563
|
self.clearFeatureSelection()
|
|
@@ -566,7 +572,7 @@ export const BaseLinearDisplay = types
|
|
|
566
572
|
self.clearFeatureSelection()
|
|
567
573
|
},
|
|
568
574
|
// similar to click but opens a menu with further options
|
|
569
|
-
onFeatureContextMenu(_: unknown, featureId
|
|
575
|
+
onFeatureContextMenu(_: unknown, featureId?: string) {
|
|
570
576
|
const f = featureId || self.featureIdUnderMouse
|
|
571
577
|
if (!f) {
|
|
572
578
|
self.clearFeatureSelection()
|
|
@@ -576,7 +582,7 @@ export const BaseLinearDisplay = types
|
|
|
576
582
|
}
|
|
577
583
|
},
|
|
578
584
|
|
|
579
|
-
onMouseMove(_: unknown, featureId
|
|
585
|
+
onMouseMove(_: unknown, featureId?: string) {
|
|
580
586
|
self.setFeatureIdUnderMouse(featureId)
|
|
581
587
|
},
|
|
582
588
|
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
makeStyles,
|
|
8
8
|
alpha,
|
|
9
9
|
} from '@material-ui/core'
|
|
10
|
+
import { getTickDisplayStr2 } from '@jbrowse/core/util'
|
|
10
11
|
import SearchBox from './SearchBox'
|
|
11
12
|
|
|
12
13
|
// icons
|
|
@@ -97,10 +98,10 @@ function PanControls({ model }: { model: LGV }) {
|
|
|
97
98
|
|
|
98
99
|
const RegionWidth = observer(({ model }: { model: LGV }) => {
|
|
99
100
|
const classes = useStyles()
|
|
100
|
-
const { coarseTotalBp } = model
|
|
101
|
+
const { coarseTotalBp, bpPerPx } = model
|
|
101
102
|
return (
|
|
102
103
|
<Typography variant="body2" color="textSecondary" className={classes.bp}>
|
|
103
|
-
{
|
|
104
|
+
{getTickDisplayStr2(coarseTotalBp, bpPerPx)}
|
|
104
105
|
</Typography>
|
|
105
106
|
)
|
|
106
107
|
})
|
|
@@ -32,11 +32,8 @@ export default function HelpDialog({
|
|
|
32
32
|
Using the search box
|
|
33
33
|
{handleClose ? (
|
|
34
34
|
<IconButton
|
|
35
|
-
data-testid="close-resultsDialog"
|
|
36
35
|
className={classes.closeButton}
|
|
37
|
-
onClick={() =>
|
|
38
|
-
handleClose()
|
|
39
|
-
}}
|
|
36
|
+
onClick={() => handleClose()}
|
|
40
37
|
>
|
|
41
38
|
<CloseIcon />
|
|
42
39
|
</IconButton>
|
|
@@ -81,6 +78,10 @@ export default function HelpDialog({
|
|
|
81
78
|
<code>chr1:1-100[rev] chr2:1-100</code> - open up the first region
|
|
82
79
|
in the horizontally flipped orientation
|
|
83
80
|
</li>
|
|
81
|
+
<li>
|
|
82
|
+
<code>chr1 100 200</code> - use whitespace separated refname, start,
|
|
83
|
+
end
|
|
84
|
+
</li>
|
|
84
85
|
</ul>
|
|
85
86
|
</DialogContent>
|
|
86
87
|
<Divider />
|
|
@@ -79,7 +79,7 @@ describe('<LinearGenomeView />', () => {
|
|
|
79
79
|
await findByText('Foo Track')
|
|
80
80
|
// test needs to wait until it's updated to display 100 bp in the header to
|
|
81
81
|
// make snapshot pass
|
|
82
|
-
await findByText('
|
|
82
|
+
await findByText('100bp')
|
|
83
83
|
expect(container.firstChild).toMatchSnapshot()
|
|
84
84
|
})
|
|
85
85
|
it('renders two tracks, two regions', async () => {
|
|
@@ -145,7 +145,7 @@ describe('<LinearGenomeView />', () => {
|
|
|
145
145
|
<LinearGenomeView model={model} />,
|
|
146
146
|
)
|
|
147
147
|
await findByText('Foo Track')
|
|
148
|
-
await findByText('
|
|
148
|
+
await findByText('798bp')
|
|
149
149
|
await findAllByTestId('svgfeatures')
|
|
150
150
|
|
|
151
151
|
expect(container.firstChild).toMatchSnapshot()
|
|
@@ -92,16 +92,22 @@ const LinearGenomeView = observer(({ model }: { model: LGV }) => {
|
|
|
92
92
|
<TracksContainer model={model}>
|
|
93
93
|
{!tracks.length ? (
|
|
94
94
|
<Paper variant="outlined" className={classes.note}>
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
95
|
+
{!model.hideNoTracksActive ? (
|
|
96
|
+
<>
|
|
97
|
+
<Typography>No tracks active.</Typography>
|
|
98
|
+
<Button
|
|
99
|
+
variant="contained"
|
|
100
|
+
color="primary"
|
|
101
|
+
onClick={model.activateTrackSelector}
|
|
102
|
+
style={{ zIndex: 1000 }}
|
|
103
|
+
startIcon={<TrackSelectorIcon />}
|
|
104
|
+
>
|
|
105
|
+
Open track selector
|
|
106
|
+
</Button>
|
|
107
|
+
</>
|
|
108
|
+
) : (
|
|
109
|
+
<div style={{ height: '48px' }}></div>
|
|
110
|
+
)}
|
|
105
111
|
</Paper>
|
|
106
112
|
) : (
|
|
107
113
|
tracks.map(track => (
|
|
@@ -5,7 +5,7 @@ import { Instance } from 'mobx-state-tree'
|
|
|
5
5
|
import clsx from 'clsx'
|
|
6
6
|
|
|
7
7
|
import Base1DView, { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel'
|
|
8
|
-
import { getSession } from '@jbrowse/core/util'
|
|
8
|
+
import { getSession, getTickDisplayStr } from '@jbrowse/core/util'
|
|
9
9
|
import { ContentBlock } from '@jbrowse/core/util/blockTypes'
|
|
10
10
|
import { Assembly } from '@jbrowse/core/assemblyManager/assembly'
|
|
11
11
|
|
|
@@ -51,7 +51,6 @@ const useStyles = makeStyles(theme => {
|
|
|
51
51
|
},
|
|
52
52
|
scaleBarLabel: {
|
|
53
53
|
height: HEADER_OVERVIEW_HEIGHT,
|
|
54
|
-
width: 1,
|
|
55
54
|
position: 'absolute',
|
|
56
55
|
display: 'flex',
|
|
57
56
|
justifyContent: 'center',
|
|
@@ -301,7 +300,7 @@ const OverviewBox = observer(
|
|
|
301
300
|
overview: Base1DViewModel
|
|
302
301
|
}) => {
|
|
303
302
|
const classes = useStyles()
|
|
304
|
-
const { cytobandOffset, showCytobands } = model
|
|
303
|
+
const { cytobandOffset, bpPerPx, showCytobands } = model
|
|
305
304
|
const { start, end, reversed, refName, assemblyName } = block
|
|
306
305
|
const { majorPitch } = chooseGridPitch(scale, 120, 15)
|
|
307
306
|
const { assemblyManager } = getSession(model)
|
|
@@ -354,7 +353,7 @@ const OverviewBox = observer(
|
|
|
354
353
|
color: refNameColor,
|
|
355
354
|
}}
|
|
356
355
|
>
|
|
357
|
-
{tickLabel
|
|
356
|
+
{getTickDisplayStr(tickLabel, bpPerPx)}
|
|
358
357
|
</Typography>
|
|
359
358
|
))
|
|
360
359
|
: null}
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
InterRegionPaddingBlock as InterRegionPaddingBlockComponent,
|
|
15
15
|
} from '../../BaseLinearDisplay/components/Block'
|
|
16
16
|
import { makeTicks } from '../util'
|
|
17
|
+
import { getTickDisplayStr } from '@jbrowse/core/util'
|
|
17
18
|
|
|
18
19
|
type LGV = LinearGenomeViewModel
|
|
19
20
|
|
|
@@ -95,18 +96,14 @@ const RenderedRefNameLabels = observer(({ model }: { model: LGV }) => {
|
|
|
95
96
|
|
|
96
97
|
const RenderedScaleBarLabels = observer(({ model }: { model: LGV }) => {
|
|
97
98
|
const classes = useStyles()
|
|
99
|
+
const { bpPerPx } = model
|
|
98
100
|
|
|
99
101
|
return (
|
|
100
102
|
<>
|
|
101
103
|
{model.staticBlocks.map((block, index) => {
|
|
102
104
|
if (block instanceof ContentBlock) {
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
block.end,
|
|
106
|
-
model.bpPerPx,
|
|
107
|
-
true,
|
|
108
|
-
false,
|
|
109
|
-
)
|
|
105
|
+
const { start, end } = block
|
|
106
|
+
const ticks = makeTicks(start, end, bpPerPx, true, false)
|
|
110
107
|
|
|
111
108
|
return (
|
|
112
109
|
<ContentBlockComponent key={`${block.key}-${index}`} block={block}>
|
|
@@ -116,7 +113,7 @@ const RenderedScaleBarLabels = observer(({ model }: { model: LGV }) => {
|
|
|
116
113
|
(block.reversed
|
|
117
114
|
? block.end - tick.base
|
|
118
115
|
: tick.base - block.start) / model.bpPerPx
|
|
119
|
-
const baseNumber =
|
|
116
|
+
const baseNumber = tick.base + 1
|
|
120
117
|
return (
|
|
121
118
|
<div
|
|
122
119
|
key={tick.base}
|
|
@@ -125,7 +122,7 @@ const RenderedScaleBarLabels = observer(({ model }: { model: LGV }) => {
|
|
|
125
122
|
>
|
|
126
123
|
{baseNumber ? (
|
|
127
124
|
<Typography className={classes.majorTickLabel}>
|
|
128
|
-
{baseNumber}
|
|
125
|
+
{getTickDisplayStr(baseNumber, bpPerPx)}
|
|
129
126
|
</Typography>
|
|
130
127
|
) : null}
|
|
131
128
|
</div>
|
|
@@ -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
|
})
|