@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
|
@@ -60,81 +60,84 @@ interface Props {
|
|
|
60
60
|
className?: string
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
const TrackLabel = React.forwardRef<HTMLDivElement, Props>(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
const TrackLabel = React.forwardRef<HTMLDivElement, Props>(function (
|
|
64
|
+
{ track, className },
|
|
65
|
+
ref,
|
|
66
|
+
) {
|
|
67
|
+
const { classes, cx } = useStyles()
|
|
68
|
+
const view = getContainingView(track) as LGV
|
|
69
|
+
const session = getSession(track)
|
|
70
|
+
const trackConf = track.configuration
|
|
71
|
+
const minimized = track.minimized
|
|
72
|
+
const trackId = getConf(track, 'trackId')
|
|
73
|
+
const trackName = getTrackName(trackConf, session)
|
|
72
74
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
const popupState = usePopupState({
|
|
76
|
+
popupId: 'trackLabelMenu',
|
|
77
|
+
variant: 'popover',
|
|
78
|
+
})
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
const items = [
|
|
81
|
+
{
|
|
82
|
+
label: minimized ? 'Restore track' : 'Minimize track',
|
|
83
|
+
icon: minimized ? AddIcon : MinimizeIcon,
|
|
84
|
+
onClick: () => track.setMinimized(!minimized),
|
|
85
|
+
},
|
|
86
|
+
...(session.getTrackActionMenuItems?.(trackConf) || []),
|
|
87
|
+
...track.trackMenuItems(),
|
|
88
|
+
].sort((a, b) => (b.priority || 0) - (a.priority || 0))
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
90
|
+
return (
|
|
91
|
+
<Paper ref={ref} className={cx(className, classes.root)}>
|
|
92
|
+
<span
|
|
93
|
+
draggable
|
|
94
|
+
className={classes.dragHandle}
|
|
95
|
+
onDragStart={event => {
|
|
96
|
+
const target = event.currentTarget
|
|
97
|
+
if (target.parentNode) {
|
|
98
|
+
const parent = target.parentNode as HTMLElement
|
|
99
|
+
event.dataTransfer.setDragImage(parent, 20, 20)
|
|
100
|
+
view.setDraggingTrackId(track.id)
|
|
101
|
+
}
|
|
102
|
+
}}
|
|
103
|
+
onDragEnd={() => view.setDraggingTrackId(undefined)}
|
|
104
|
+
data-testid={`dragHandle-${view.id}-${trackId}`}
|
|
105
|
+
>
|
|
106
|
+
<DragIcon className={classes.dragHandleIcon} fontSize="small" />
|
|
107
|
+
</span>
|
|
108
|
+
<IconButton
|
|
109
|
+
onClick={() => view.hideTrack(trackId)}
|
|
110
|
+
className={classes.iconButton}
|
|
111
|
+
title="close this track"
|
|
112
|
+
>
|
|
113
|
+
<CloseIcon fontSize="small" />
|
|
114
|
+
</IconButton>
|
|
113
115
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
<IconButton
|
|
122
|
-
{...bindTrigger(popupState)}
|
|
123
|
-
className={classes.iconButton}
|
|
124
|
-
data-testid="track_menu_icon"
|
|
125
|
-
disabled={!items.length}
|
|
126
|
-
>
|
|
127
|
-
<MoreVertIcon fontSize="small" />
|
|
128
|
-
</IconButton>
|
|
129
|
-
<CascadingMenu
|
|
130
|
-
{...bindPopover(popupState)}
|
|
131
|
-
onMenuItemClick={(_: unknown, callback: Function) => callback()}
|
|
132
|
-
menuItems={items}
|
|
133
|
-
popupState={popupState}
|
|
116
|
+
<Typography
|
|
117
|
+
variant="body1"
|
|
118
|
+
component="span"
|
|
119
|
+
className={classes.trackName}
|
|
120
|
+
>
|
|
121
|
+
<SanitizedHTML
|
|
122
|
+
html={`${trackName}${minimized ? ' (minimized)' : ''}`}
|
|
134
123
|
/>
|
|
135
|
-
</
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
124
|
+
</Typography>
|
|
125
|
+
<IconButton
|
|
126
|
+
{...bindTrigger(popupState)}
|
|
127
|
+
className={classes.iconButton}
|
|
128
|
+
data-testid="track_menu_icon"
|
|
129
|
+
disabled={items.length === 0}
|
|
130
|
+
>
|
|
131
|
+
<MoreVertIcon fontSize="small" />
|
|
132
|
+
</IconButton>
|
|
133
|
+
<CascadingMenu
|
|
134
|
+
{...bindPopover(popupState)}
|
|
135
|
+
onMenuItemClick={(_: unknown, callback: Function) => callback()}
|
|
136
|
+
menuItems={items}
|
|
137
|
+
popupState={popupState}
|
|
138
|
+
/>
|
|
139
|
+
</Paper>
|
|
140
|
+
)
|
|
141
|
+
})
|
|
139
142
|
|
|
140
143
|
export default observer(TrackLabel)
|
|
@@ -20,15 +20,11 @@ const useStyles = makeStyles()({
|
|
|
20
20
|
position: 'relative',
|
|
21
21
|
overflow: 'hidden',
|
|
22
22
|
},
|
|
23
|
-
spacer: {
|
|
24
|
-
position: 'relative',
|
|
25
|
-
height: 3,
|
|
26
|
-
},
|
|
27
23
|
})
|
|
28
24
|
|
|
29
25
|
type LGV = LinearGenomeViewModel
|
|
30
26
|
|
|
31
|
-
function TracksContainer({
|
|
27
|
+
export default observer(function TracksContainer({
|
|
32
28
|
children,
|
|
33
29
|
model,
|
|
34
30
|
}: {
|
|
@@ -60,6 +56,12 @@ function TracksContainer({
|
|
|
60
56
|
ref={ref}
|
|
61
57
|
data-testid="trackContainer"
|
|
62
58
|
className={classes.tracksContainer}
|
|
59
|
+
onClick={event => {
|
|
60
|
+
if (event.detail === 2) {
|
|
61
|
+
const left = ref.current?.getBoundingClientRect().left || 0
|
|
62
|
+
model.zoomTo(model.bpPerPx / 2, event.clientX - left, true)
|
|
63
|
+
}
|
|
64
|
+
}}
|
|
63
65
|
onMouseDown={event => {
|
|
64
66
|
mouseDown1(event)
|
|
65
67
|
mouseDown2(event)
|
|
@@ -106,6 +108,4 @@ function TracksContainer({
|
|
|
106
108
|
{children}
|
|
107
109
|
</div>
|
|
108
110
|
)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export default observer(TracksContainer)
|
|
111
|
+
})
|
|
@@ -11,7 +11,6 @@ exports[`renders one track, one region 1`] = `
|
|
|
11
11
|
>
|
|
12
12
|
<div
|
|
13
13
|
class="css-dznme2-rubberbandControl"
|
|
14
|
-
role="presentation"
|
|
15
14
|
>
|
|
16
15
|
<div
|
|
17
16
|
class="css-16vhz0m-scalebar"
|
|
@@ -160,11 +159,11 @@ exports[`renders one track, one region 1`] = `
|
|
|
160
159
|
<div
|
|
161
160
|
class="MuiAutocomplete-root css-l3ln04-MuiAutocomplete-root"
|
|
162
161
|
data-testid="autocomplete"
|
|
163
|
-
style="width:
|
|
162
|
+
style="width: 175px;"
|
|
164
163
|
>
|
|
165
164
|
<div
|
|
166
165
|
class="MuiFormControl-root MuiFormControl-fullWidth MuiTextField-root css-1efd6m0-MuiFormControl-root-MuiTextField-root-headerRefName"
|
|
167
|
-
style="margin: 7px;
|
|
166
|
+
style="margin: 7px;"
|
|
168
167
|
>
|
|
169
168
|
<div
|
|
170
169
|
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-adornedEnd MuiAutocomplete-inputRoot css-154xyx0-MuiInputBase-root-MuiOutlinedInput-root"
|
|
@@ -177,7 +176,7 @@ exports[`renders one track, one region 1`] = `
|
|
|
177
176
|
autocapitalize="none"
|
|
178
177
|
autocomplete="off"
|
|
179
178
|
class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputAdornedEnd MuiAutocomplete-input MuiAutocomplete-inputFocused css-nxo287-MuiInputBase-input-MuiOutlinedInput-input"
|
|
180
|
-
id="
|
|
179
|
+
id="mui-7"
|
|
181
180
|
placeholder="Search for location"
|
|
182
181
|
role="combobox"
|
|
183
182
|
spellcheck="false"
|
|
@@ -276,8 +275,7 @@ exports[`renders one track, one region 1`] = `
|
|
|
276
275
|
style="left: 0%; width: 0%;"
|
|
277
276
|
/>
|
|
278
277
|
<span
|
|
279
|
-
class="MuiSlider-thumb MuiSlider-thumbSizeSmall MuiSlider-thumbColorPrimary css-14gf62f-MuiSlider-thumb"
|
|
280
|
-
data-focusvisible="false"
|
|
278
|
+
class="MuiSlider-thumb MuiSlider-thumbSizeSmall MuiSlider-thumbColorPrimary MuiSlider-thumb MuiSlider-thumbSizeSmall MuiSlider-thumbColorPrimary css-14gf62f-MuiSlider-thumb"
|
|
281
279
|
data-index="0"
|
|
282
280
|
style="left: 0%;"
|
|
283
281
|
>
|
|
@@ -571,7 +569,6 @@ exports[`renders two tracks, two regions 1`] = `
|
|
|
571
569
|
>
|
|
572
570
|
<div
|
|
573
571
|
class="css-dznme2-rubberbandControl"
|
|
574
|
-
role="presentation"
|
|
575
572
|
>
|
|
576
573
|
<div
|
|
577
574
|
class="css-16vhz0m-scalebar"
|
|
@@ -740,7 +737,7 @@ exports[`renders two tracks, two regions 1`] = `
|
|
|
740
737
|
>
|
|
741
738
|
<div
|
|
742
739
|
class="MuiFormControl-root MuiFormControl-fullWidth MuiTextField-root css-1efd6m0-MuiFormControl-root-MuiTextField-root-headerRefName"
|
|
743
|
-
style="margin: 7px;
|
|
740
|
+
style="margin: 7px;"
|
|
744
741
|
>
|
|
745
742
|
<div
|
|
746
743
|
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-adornedEnd MuiAutocomplete-inputRoot css-154xyx0-MuiInputBase-root-MuiOutlinedInput-root"
|
|
@@ -753,7 +750,7 @@ exports[`renders two tracks, two regions 1`] = `
|
|
|
753
750
|
autocapitalize="none"
|
|
754
751
|
autocomplete="off"
|
|
755
752
|
class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputAdornedEnd MuiAutocomplete-input MuiAutocomplete-inputFocused css-nxo287-MuiInputBase-input-MuiOutlinedInput-input"
|
|
756
|
-
id="
|
|
753
|
+
id="mui-9"
|
|
757
754
|
placeholder="Search for location"
|
|
758
755
|
role="combobox"
|
|
759
756
|
spellcheck="false"
|
|
@@ -854,8 +851,7 @@ exports[`renders two tracks, two regions 1`] = `
|
|
|
854
851
|
style="left: 0%; width: 9.774680693120512%;"
|
|
855
852
|
/>
|
|
856
853
|
<span
|
|
857
|
-
class="MuiSlider-thumb MuiSlider-thumbSizeSmall MuiSlider-thumbColorPrimary css-14gf62f-MuiSlider-thumb"
|
|
858
|
-
data-focusvisible="false"
|
|
854
|
+
class="MuiSlider-thumb MuiSlider-thumbSizeSmall MuiSlider-thumbColorPrimary MuiSlider-thumb MuiSlider-thumbSizeSmall MuiSlider-thumbColorPrimary css-14gf62f-MuiSlider-thumb"
|
|
859
855
|
data-index="0"
|
|
860
856
|
style="left: 9.774680693120512%;"
|
|
861
857
|
>
|
|
@@ -239,7 +239,12 @@ export function useRangeSelect(
|
|
|
239
239
|
|
|
240
240
|
export function useWheelScroll(
|
|
241
241
|
ref: React.RefObject<HTMLDivElement>,
|
|
242
|
-
model:
|
|
242
|
+
model: {
|
|
243
|
+
bpPerPx: number
|
|
244
|
+
zoomTo: (arg: number, arg2?: number) => void
|
|
245
|
+
setScaleFactor: (arg: number) => void
|
|
246
|
+
horizontalScroll: (arg: number) => void
|
|
247
|
+
},
|
|
243
248
|
) {
|
|
244
249
|
const delta = useRef(0)
|
|
245
250
|
const timeout = useRef<Timer>()
|
|
@@ -266,6 +271,7 @@ export function useWheelScroll(
|
|
|
266
271
|
delta.current > 0
|
|
267
272
|
? model.bpPerPx * (1 + delta.current)
|
|
268
273
|
: model.bpPerPx / (1 - delta.current),
|
|
274
|
+
origEvent.clientX - (curr?.getBoundingClientRect().left || 0),
|
|
269
275
|
)
|
|
270
276
|
delta.current = 0
|
|
271
277
|
}, 300)
|
|
@@ -96,7 +96,7 @@ function initialize() {
|
|
|
96
96
|
assemblyManager: types.optional(AssemblyManager, {
|
|
97
97
|
assemblies: {
|
|
98
98
|
volvox: {
|
|
99
|
-
// @ts-
|
|
99
|
+
// @ts-expect-error
|
|
100
100
|
regions: volvoxDisplayedRegions,
|
|
101
101
|
},
|
|
102
102
|
},
|
|
@@ -311,7 +311,6 @@ test('can navToMultiple', () => {
|
|
|
311
311
|
describe('Zoom to selected displayed regions', () => {
|
|
312
312
|
const { Session, LinearGenomeModel } = initialize()
|
|
313
313
|
let model: LGV
|
|
314
|
-
let largestBpPerPx: number
|
|
315
314
|
beforeEach(() => {
|
|
316
315
|
const session = Session.create({
|
|
317
316
|
configuration: {},
|
|
@@ -357,7 +356,6 @@ describe('Zoom to selected displayed regions', () => {
|
|
|
357
356
|
},
|
|
358
357
|
)
|
|
359
358
|
|
|
360
|
-
largestBpPerPx = model.bpPerPx
|
|
361
359
|
expect(model.offsetPx).toEqual(0)
|
|
362
360
|
expect(model.bpPerPx).toBeCloseTo(31.408)
|
|
363
361
|
})
|
|
@@ -384,7 +382,6 @@ describe('Zoom to selected displayed regions', () => {
|
|
|
384
382
|
expect(model.offsetPx).toEqual(0)
|
|
385
383
|
// 10000 - 5000 = 5000 / 800 = 6.25
|
|
386
384
|
expect(model.bpPerPx).toEqual(6.25)
|
|
387
|
-
expect(model.bpPerPx).toBeLessThan(largestBpPerPx)
|
|
388
385
|
})
|
|
389
386
|
|
|
390
387
|
it('can select one region with start or end outside of displayed region', () => {
|
|
@@ -411,7 +408,6 @@ describe('Zoom to selected displayed regions', () => {
|
|
|
411
408
|
expect(Math.abs(model.offsetPx)).toEqual(0)
|
|
412
409
|
// endOffset 19000 - (-1) = 19001 / 800 = zoomTo(23.75)
|
|
413
410
|
expect(model.bpPerPx).toBeCloseTo(23.75)
|
|
414
|
-
expect(model.bpPerPx).toBeLessThan(largestBpPerPx)
|
|
415
411
|
})
|
|
416
412
|
|
|
417
413
|
it('can select over two regions in the same reference sequence', () => {
|
|
@@ -439,7 +435,6 @@ describe('Zoom to selected displayed regions', () => {
|
|
|
439
435
|
expect(model.bpPerPx).toBeCloseTo(27.78, 0)
|
|
440
436
|
// offset 5000 / bpPerPx (because that is the starting) = 180.5
|
|
441
437
|
expect(model.offsetPx).toBe(181)
|
|
442
|
-
expect(model.bpPerPx).toBeLessThan(largestBpPerPx)
|
|
443
438
|
})
|
|
444
439
|
|
|
445
440
|
it('can navigate to overlapping regions with a region between', () => {
|
|
@@ -585,7 +580,7 @@ test('can perform bpToPx in a way that makes sense on things that happen outside
|
|
|
585
580
|
model.toggleHeaderOverview()
|
|
586
581
|
expect(model.hideHeaderOverview).toEqual(true)
|
|
587
582
|
model.toggleHeaderOverview()
|
|
588
|
-
model.setError(Error('pxToBp failed to map to a region'))
|
|
583
|
+
model.setError(new Error('pxToBp failed to map to a region'))
|
|
589
584
|
expect(`${model.error}`).toEqual('Error: pxToBp failed to map to a region')
|
|
590
585
|
})
|
|
591
586
|
// determined objectively by looking at
|
|
@@ -936,7 +931,7 @@ test('navToLocString with human assembly', async () => {
|
|
|
936
931
|
assemblyManager: {
|
|
937
932
|
assemblies: {
|
|
938
933
|
hg38: {
|
|
939
|
-
// @ts-
|
|
934
|
+
// @ts-expect-error
|
|
940
935
|
regions: hg38Regions,
|
|
941
936
|
},
|
|
942
937
|
},
|
|
@@ -4,15 +4,14 @@ import { ViewType } from '@jbrowse/core/pluggableElementTypes'
|
|
|
4
4
|
import { stateModelFactory } from './model'
|
|
5
5
|
|
|
6
6
|
export default (pluginManager: PluginManager) => {
|
|
7
|
-
pluginManager.addViewType(
|
|
8
|
-
(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
)
|
|
7
|
+
pluginManager.addViewType(() => {
|
|
8
|
+
return new ViewType({
|
|
9
|
+
name: 'LinearGenomeView',
|
|
10
|
+
displayName: 'Linear genome view',
|
|
11
|
+
stateModel: stateModelFactory(pluginManager),
|
|
12
|
+
ReactComponent: lazy(() => import('./components/LinearGenomeView')),
|
|
13
|
+
})
|
|
14
|
+
})
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
export * from './model'
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
measureText,
|
|
18
18
|
parseLocString,
|
|
19
19
|
springAnimate,
|
|
20
|
+
sum,
|
|
20
21
|
} from '@jbrowse/core/util'
|
|
21
22
|
import BaseResult from '@jbrowse/core/TextSearch/BaseResults'
|
|
22
23
|
import { BlockSet, BaseBlock } from '@jbrowse/core/util/blockTypes'
|
|
@@ -52,13 +53,10 @@ import MenuOpenIcon from '@mui/icons-material/MenuOpen'
|
|
|
52
53
|
|
|
53
54
|
// locals
|
|
54
55
|
import { renderToSvg } from './svgcomponents/SVGLinearGenomeView'
|
|
55
|
-
|
|
56
|
-
import SearchBox from './components/SearchBox'
|
|
56
|
+
|
|
57
57
|
import ExportSvgDlg from './components/ExportSvgDialog'
|
|
58
58
|
import MiniControls from './components/MiniControls'
|
|
59
59
|
import Header from './components/Header'
|
|
60
|
-
import ZoomControls from './components/ZoomControls'
|
|
61
|
-
import LinearGenomeView from './components/LinearGenomeView'
|
|
62
60
|
|
|
63
61
|
// lazies
|
|
64
62
|
const SequenceSearchDialog = lazy(
|
|
@@ -365,9 +363,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
365
363
|
* #getter
|
|
366
364
|
*/
|
|
367
365
|
get trackHeights() {
|
|
368
|
-
return self.tracks
|
|
369
|
-
.map(t => t.displays[0].height)
|
|
370
|
-
.reduce((a, b) => a + b, 0)
|
|
366
|
+
return sum(self.tracks.map(t => t.displays[0].height))
|
|
371
367
|
},
|
|
372
368
|
|
|
373
369
|
/**
|
|
@@ -478,14 +474,14 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
478
474
|
*/
|
|
479
475
|
rankSearchResults(results: BaseResult[]) {
|
|
480
476
|
// order of rank
|
|
481
|
-
const openTrackIds =
|
|
482
|
-
track => track.configuration.trackId,
|
|
477
|
+
const openTrackIds = new Set(
|
|
478
|
+
self.tracks.map(track => track.configuration.trackId),
|
|
483
479
|
)
|
|
484
|
-
|
|
485
|
-
if (openTrackIds.
|
|
480
|
+
for (const result of results) {
|
|
481
|
+
if (openTrackIds.has(result.trackId)) {
|
|
486
482
|
result.updateScore(result.getScore() + 1)
|
|
487
483
|
}
|
|
488
|
-
}
|
|
484
|
+
}
|
|
489
485
|
return results
|
|
490
486
|
},
|
|
491
487
|
|
|
@@ -583,25 +579,25 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
583
579
|
/**
|
|
584
580
|
* #action
|
|
585
581
|
*/
|
|
586
|
-
zoomTo(bpPerPx: number) {
|
|
582
|
+
zoomTo(bpPerPx: number, offset = self.width / 2, centerAtOffset = false) {
|
|
587
583
|
const newBpPerPx = clamp(bpPerPx, self.minBpPerPx, self.maxBpPerPx)
|
|
588
584
|
if (newBpPerPx === self.bpPerPx) {
|
|
589
585
|
return newBpPerPx
|
|
590
586
|
}
|
|
591
587
|
const oldBpPerPx = self.bpPerPx
|
|
592
|
-
self.bpPerPx = newBpPerPx
|
|
593
588
|
|
|
594
589
|
if (Math.abs(oldBpPerPx - newBpPerPx) < 0.000001) {
|
|
595
590
|
console.warn('zoomTo bpPerPx rounding error')
|
|
596
591
|
return oldBpPerPx
|
|
597
592
|
}
|
|
593
|
+
self.bpPerPx = newBpPerPx
|
|
598
594
|
|
|
599
|
-
// tweak the offset so that the center of the view remains at the same
|
|
600
|
-
|
|
595
|
+
// tweak the offset so that the center of the view remains at the same
|
|
596
|
+
// coordinate
|
|
601
597
|
this.scrollTo(
|
|
602
598
|
Math.round(
|
|
603
|
-
((self.offsetPx +
|
|
604
|
-
|
|
599
|
+
((self.offsetPx + offset) * oldBpPerPx) / newBpPerPx -
|
|
600
|
+
(centerAtOffset ? self.width / 2 : offset),
|
|
605
601
|
),
|
|
606
602
|
)
|
|
607
603
|
return newBpPerPx
|
|
@@ -644,8 +640,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
644
640
|
*/
|
|
645
641
|
horizontallyFlip() {
|
|
646
642
|
self.displayedRegions = cast(
|
|
647
|
-
self.displayedRegions
|
|
648
|
-
.slice()
|
|
643
|
+
[...self.displayedRegions]
|
|
649
644
|
.reverse()
|
|
650
645
|
.map(region => ({ ...region, reversed: !region.reversed })),
|
|
651
646
|
)
|
|
@@ -670,9 +665,11 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
670
665
|
throw new Error(`Unknown track type ${conf.type}`)
|
|
671
666
|
}
|
|
672
667
|
const viewType = pluginManager.getViewType(self.type)
|
|
673
|
-
const supportedDisplays =
|
|
668
|
+
const supportedDisplays = new Set(
|
|
669
|
+
viewType.displayTypes.map(d => d.name),
|
|
670
|
+
)
|
|
674
671
|
const displayConf = conf.displays.find((d: AnyConfigurationModel) =>
|
|
675
|
-
supportedDisplays.
|
|
672
|
+
supportedDisplays.has(d.type),
|
|
676
673
|
)
|
|
677
674
|
if (!displayConf) {
|
|
678
675
|
throw new Error(
|
|
@@ -1366,7 +1363,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
1366
1363
|
})
|
|
1367
1364
|
} else {
|
|
1368
1365
|
self.setDisplayedRegions(
|
|
1369
|
-
// @ts-
|
|
1366
|
+
// @ts-expect-error
|
|
1370
1367
|
locations.map(r => (r.start === undefined ? r.parentRegion : r)),
|
|
1371
1368
|
)
|
|
1372
1369
|
self.showAllRegions()
|
|
@@ -1586,22 +1583,23 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
1586
1583
|
* #getter
|
|
1587
1584
|
*/
|
|
1588
1585
|
get centerLineInfo() {
|
|
1589
|
-
return self.displayedRegions.length
|
|
1586
|
+
return self.displayedRegions.length > 0
|
|
1590
1587
|
? this.pxToBp(self.width / 2)
|
|
1591
1588
|
: undefined
|
|
1592
1589
|
},
|
|
1593
1590
|
}))
|
|
1594
1591
|
}
|
|
1595
1592
|
|
|
1596
|
-
export {
|
|
1597
|
-
renderToSvg,
|
|
1598
|
-
RefNameAutocomplete,
|
|
1599
|
-
SearchBox,
|
|
1600
|
-
ZoomControls,
|
|
1601
|
-
LinearGenomeView,
|
|
1602
|
-
}
|
|
1603
|
-
|
|
1604
1593
|
export type LinearGenomeViewStateModel = ReturnType<typeof stateModelFactory>
|
|
1605
1594
|
export type LinearGenomeViewModel = Instance<LinearGenomeViewStateModel>
|
|
1606
1595
|
|
|
1607
|
-
export {
|
|
1596
|
+
export {
|
|
1597
|
+
default as ReactComponent,
|
|
1598
|
+
default as LinearGenomeView,
|
|
1599
|
+
} from './components/LinearGenomeView'
|
|
1600
|
+
|
|
1601
|
+
export { default as RefNameAutocomplete } from './components/RefNameAutocomplete'
|
|
1602
|
+
export { default as SearchBox } from './components/SearchBox'
|
|
1603
|
+
export { default as ZoomControls } from './components/ZoomControls'
|
|
1604
|
+
|
|
1605
|
+
export { renderToSvg } from './svgcomponents/SVGLinearGenomeView'
|
|
@@ -10,7 +10,7 @@ import { LinearGenomeViewModel, ExportSvgOptions } from '..'
|
|
|
10
10
|
import SVGBackground from './SVGBackground'
|
|
11
11
|
import SVGTracks from './SVGTracks'
|
|
12
12
|
import SVGHeader from './SVGHeader'
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
import { getTrackName } from '@jbrowse/core/util/tracks'
|
|
15
15
|
|
|
16
16
|
type LGV = LinearGenomeViewModel
|
|
@@ -65,9 +65,8 @@ export async function renderToSvg(model: LGV, opts: ExportSvgOptions) {
|
|
|
65
65
|
)
|
|
66
66
|
const trackLabelMaxLen =
|
|
67
67
|
max(
|
|
68
|
-
tracks.map(
|
|
69
|
-
|
|
70
|
-
fontSize,
|
|
68
|
+
tracks.map(t =>
|
|
69
|
+
measureText(getTrackName(t.configuration, session), fontSize),
|
|
71
70
|
),
|
|
72
71
|
0,
|
|
73
72
|
) + 40
|
|
@@ -111,4 +110,5 @@ export async function renderToSvg(model: LGV, opts: ExportSvgOptions) {
|
|
|
111
110
|
)
|
|
112
111
|
}
|
|
113
112
|
|
|
114
|
-
export {
|
|
113
|
+
export { default as SVGRuler } from './SVGRuler'
|
|
114
|
+
export { default as SVGTracks } from './SVGTracks'
|
|
@@ -17,6 +17,7 @@ export default function SVGTrackLabel({
|
|
|
17
17
|
const theme = useTheme()
|
|
18
18
|
const fill = theme.palette.text.primary
|
|
19
19
|
const xoff = trackLabels === 'overlay' ? 5 : 0
|
|
20
|
+
const yoff = trackLabels === 'offset' ? 5 : 0
|
|
20
21
|
return trackLabels !== 'none' ? (
|
|
21
22
|
<g>
|
|
22
23
|
{trackLabels === 'left' ? (
|
|
@@ -33,6 +34,7 @@ export default function SVGTrackLabel({
|
|
|
33
34
|
) : (
|
|
34
35
|
<text
|
|
35
36
|
x={x + xoff}
|
|
37
|
+
y={yoff}
|
|
36
38
|
fill={fill}
|
|
37
39
|
fontSize={fontSize}
|
|
38
40
|
dominantBaseline="hanging"
|
|
@@ -10,7 +10,7 @@ export function chooseGridPitch(
|
|
|
10
10
|
) {
|
|
11
11
|
scale = Math.abs(scale)
|
|
12
12
|
const minMajorPitchBp = minMajorPitchPx * scale
|
|
13
|
-
const majorMagnitude = parseInt(
|
|
13
|
+
const majorMagnitude = Number.parseInt(
|
|
14
14
|
Number(minMajorPitchBp).toExponential().split(/e/i)[1],
|
|
15
15
|
10,
|
|
16
16
|
)
|
package/src/index.ts
CHANGED
|
@@ -9,32 +9,16 @@ import LineStyleIcon from '@mui/icons-material/LineStyle'
|
|
|
9
9
|
import {
|
|
10
10
|
BaseLinearDisplay,
|
|
11
11
|
BaseLinearDisplayComponent,
|
|
12
|
-
BlockModel,
|
|
13
|
-
BlockMsg,
|
|
14
12
|
baseLinearDisplayConfigSchema,
|
|
15
13
|
} from './BaseLinearDisplay'
|
|
16
|
-
import LinearBareDisplayF
|
|
17
|
-
configSchemaFactory as linearBareDisplayConfigSchemaFactory,
|
|
18
|
-
} from './LinearBareDisplay'
|
|
14
|
+
import LinearBareDisplayF from './LinearBareDisplay'
|
|
19
15
|
import LinearGenomeViewF, {
|
|
20
|
-
LinearGenomeViewModel,
|
|
21
|
-
LinearGenomeViewStateModel,
|
|
22
|
-
RefNameAutocomplete,
|
|
23
16
|
SearchBox,
|
|
24
17
|
ZoomControls,
|
|
25
18
|
LinearGenomeView,
|
|
26
19
|
} from './LinearGenomeView'
|
|
27
20
|
|
|
28
|
-
import
|
|
29
|
-
renderToSvg,
|
|
30
|
-
totalHeight,
|
|
31
|
-
SVGTracks,
|
|
32
|
-
SVGRuler,
|
|
33
|
-
} from './LinearGenomeView/svgcomponents/SVGLinearGenomeView'
|
|
34
|
-
import LinearBasicDisplayF, {
|
|
35
|
-
configSchema as linearBasicDisplayConfigSchemaFactory,
|
|
36
|
-
modelFactory as linearBasicDisplayModelFactory,
|
|
37
|
-
} from './LinearBasicDisplay'
|
|
21
|
+
import LinearBasicDisplayF from './LinearBasicDisplay'
|
|
38
22
|
|
|
39
23
|
import FeatureTrackF from './FeatureTrack'
|
|
40
24
|
import BasicTrackF from './BasicTrack'
|
|
@@ -74,22 +58,28 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
74
58
|
}
|
|
75
59
|
}
|
|
76
60
|
|
|
61
|
+
export type { BaseLinearDisplayModel, BlockModel } from './BaseLinearDisplay'
|
|
62
|
+
|
|
63
|
+
export { configSchemaFactory as linearBareDisplayConfigSchemaFactory } from './LinearBareDisplay'
|
|
77
64
|
export {
|
|
65
|
+
BlockMsg,
|
|
78
66
|
baseLinearDisplayConfigSchema,
|
|
79
|
-
linearBareDisplayConfigSchemaFactory,
|
|
80
|
-
linearBasicDisplayConfigSchemaFactory,
|
|
81
|
-
linearBasicDisplayModelFactory,
|
|
82
|
-
renderToSvg,
|
|
83
|
-
totalHeight,
|
|
84
|
-
SVGTracks,
|
|
85
|
-
SVGRuler,
|
|
86
67
|
BaseLinearDisplayComponent,
|
|
87
68
|
BaseLinearDisplay,
|
|
69
|
+
} from './BaseLinearDisplay'
|
|
70
|
+
export {
|
|
71
|
+
type LinearGenomeViewModel,
|
|
88
72
|
RefNameAutocomplete,
|
|
73
|
+
type LinearGenomeViewStateModel,
|
|
89
74
|
SearchBox,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
75
|
+
} from './LinearGenomeView'
|
|
76
|
+
export {
|
|
77
|
+
renderToSvg,
|
|
78
|
+
SVGTracks,
|
|
79
|
+
totalHeight,
|
|
80
|
+
SVGRuler,
|
|
81
|
+
} from './LinearGenomeView/svgcomponents/SVGLinearGenomeView'
|
|
82
|
+
export {
|
|
83
|
+
configSchema as linearBasicDisplayConfigSchemaFactory,
|
|
84
|
+
modelFactory as linearBasicDisplayModelFactory,
|
|
85
|
+
} from './LinearBasicDisplay'
|