@apollo-annotation/jbrowse-plugin-apollo 0.3.6 → 0.3.8
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/index.esm.js +4603 -2045
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +4611 -2039
- package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.development.js +9387 -4016
- package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
- package/package.json +15 -15
- package/src/ApolloInternetAccount/model.ts +48 -13
- package/src/BackendDrivers/CollaborationServerDriver.ts +23 -2
- package/src/ChangeManager.ts +42 -18
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +64 -5
- package/src/FeatureDetailsWidget/Attributes.tsx +8 -3
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +70 -81
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +946 -190
- package/src/FeatureDetailsWidget/TranscriptWidgetSummary.tsx +4 -0
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +61 -73
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +55 -211
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +562 -108
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +78 -14
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +15 -9
- package/src/LinearApolloDisplay/stateModel/base.ts +63 -43
- package/src/LinearApolloDisplay/stateModel/layouts.ts +3 -2
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +79 -292
- package/src/LinearApolloDisplay/stateModel/rendering.ts +45 -344
- package/src/LinearApolloReferenceSequenceDisplay/components/LinearApolloReferenceSequenceDisplay.tsx +87 -0
- package/src/LinearApolloReferenceSequenceDisplay/components/index.ts +1 -0
- package/src/LinearApolloReferenceSequenceDisplay/configSchema.ts +7 -0
- package/src/LinearApolloReferenceSequenceDisplay/index.ts +3 -0
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/base.ts +227 -0
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/index.ts +25 -0
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/rendering.ts +481 -0
- package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +102 -40
- package/src/LinearApolloSixFrameDisplay/components/TrackLines.tsx +12 -20
- package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +382 -243
- package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +12 -8
- package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +83 -4
- package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +23 -11
- package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +118 -123
- package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +53 -63
- package/src/OntologyManager/index.ts +4 -1
- package/src/TabularEditor/HybridGrid/Feature.tsx +20 -14
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +7 -5
- package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +108 -16
- package/src/components/AddAssembly.tsx +1 -1
- package/src/components/AddAssemblyAliases.tsx +114 -0
- package/src/components/AddChildFeature.tsx +7 -7
- package/src/components/AddFeature.tsx +20 -15
- package/src/components/AddRefSeqAliases.tsx +9 -9
- package/src/components/CopyFeature.tsx +4 -4
- package/src/components/CreateApolloAnnotation.tsx +335 -151
- package/src/components/DeleteAssembly.tsx +1 -1
- package/src/components/DeleteFeature.tsx +358 -11
- package/src/components/DownloadGFF3.tsx +20 -1
- package/src/components/EditZoomThresholdDialog.tsx +69 -0
- package/src/components/FilterFeatures.tsx +7 -7
- package/src/components/FilterTranscripts.tsx +86 -0
- package/src/components/ImportFeatures.tsx +1 -1
- package/src/components/ManageChecks.tsx +1 -1
- package/src/components/MergeExons.tsx +193 -0
- package/src/components/MergeTranscripts.tsx +182 -0
- package/src/components/OntologyTermMultiSelect.tsx +11 -11
- package/src/components/OpenLocalFile.tsx +11 -7
- package/src/components/SplitExon.tsx +134 -0
- package/src/components/ViewCheckResults.tsx +1 -1
- package/src/components/index.ts +4 -0
- package/src/config.ts +11 -0
- package/src/extensions/annotationFromJBrowseFeature.ts +2 -0
- package/src/extensions/annotationFromPileup.ts +99 -89
- package/src/index.ts +42 -105
- package/src/makeDisplayComponent.tsx +0 -1
- package/src/menus/index.ts +1 -0
- package/src/{ApolloInternetAccount/addMenuItems.ts → menus/topLevelMenu.ts} +60 -33
- package/src/menus/topLevelMenuAdmin.ts +154 -0
- package/src/session/session.ts +163 -104
- package/src/util/annotationFeatureUtils.ts +59 -0
- package/src/util/copyToClipboard.ts +21 -0
- package/src/util/displayUtils.ts +149 -0
- package/src/util/glyphUtils.ts +201 -0
- package/src/util/index.ts +2 -0
- package/src/util/mouseEventsUtils.ts +145 -0
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
4
|
+
import { type CheckResultI } from '@apollo-annotation/mst'
|
|
4
5
|
import { Menu, type MenuItem } from '@jbrowse/core/ui'
|
|
5
6
|
import {
|
|
6
7
|
type AbstractSessionModel,
|
|
7
8
|
doesIntersect2,
|
|
8
9
|
getContainingView,
|
|
10
|
+
getFrame,
|
|
9
11
|
} from '@jbrowse/core/util'
|
|
10
12
|
import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
11
13
|
import ErrorIcon from '@mui/icons-material/Error'
|
|
12
|
-
import { Alert, Avatar, Tooltip, useTheme } from '@mui/material'
|
|
14
|
+
import { Alert, Avatar, Badge, Box, Tooltip, useTheme } from '@mui/material'
|
|
13
15
|
import { observer } from 'mobx-react'
|
|
14
16
|
import React, { useEffect, useState } from 'react'
|
|
15
|
-
import { makeStyles } from 'tss-react/mui'
|
|
16
17
|
|
|
18
|
+
import {
|
|
19
|
+
type Coord,
|
|
20
|
+
clusterResultByMessage,
|
|
21
|
+
useStyles,
|
|
22
|
+
} from '../../util/displayUtils'
|
|
17
23
|
import { type LinearApolloSixFrameDisplay as LinearApolloSixFrameDisplayI } from '../stateModel'
|
|
18
24
|
|
|
19
25
|
import { TrackLines } from './TrackLines'
|
|
@@ -21,31 +27,11 @@ import { TrackLines } from './TrackLines'
|
|
|
21
27
|
interface LinearApolloSixFrameDisplayProps {
|
|
22
28
|
model: LinearApolloSixFrameDisplayI
|
|
23
29
|
}
|
|
24
|
-
export type Coord = [number, number]
|
|
25
|
-
|
|
26
|
-
const useStyles = makeStyles()((theme) => ({
|
|
27
|
-
canvasContainer: {
|
|
28
|
-
position: 'relative',
|
|
29
|
-
left: 0,
|
|
30
|
-
},
|
|
31
|
-
canvas: {
|
|
32
|
-
position: 'absolute',
|
|
33
|
-
left: 0,
|
|
34
|
-
},
|
|
35
|
-
ellipses: {
|
|
36
|
-
textOverflow: 'ellipsis',
|
|
37
|
-
overflow: 'hidden',
|
|
38
|
-
},
|
|
39
|
-
avatar: {
|
|
40
|
-
position: 'absolute',
|
|
41
|
-
color: theme.palette.warning.light,
|
|
42
|
-
backgroundColor: theme.palette.warning.contrastText,
|
|
43
|
-
},
|
|
44
|
-
}))
|
|
45
30
|
|
|
46
31
|
export const LinearApolloSixFrameDisplay = observer(
|
|
47
32
|
function LinearApolloSixFrameDisplay(
|
|
48
33
|
props: LinearApolloSixFrameDisplayProps,
|
|
34
|
+
apolloDragging,
|
|
49
35
|
) {
|
|
50
36
|
const theme = useTheme()
|
|
51
37
|
const { model } = props
|
|
@@ -54,6 +40,8 @@ export const LinearApolloSixFrameDisplay = observer(
|
|
|
54
40
|
contextMenuItems: getContextMenuItems,
|
|
55
41
|
cursor,
|
|
56
42
|
featuresHeight,
|
|
43
|
+
featureLabelSpacer,
|
|
44
|
+
geneTrackRowNums,
|
|
57
45
|
isShown,
|
|
58
46
|
onMouseDown,
|
|
59
47
|
onMouseLeave,
|
|
@@ -65,6 +53,7 @@ export const LinearApolloSixFrameDisplay = observer(
|
|
|
65
53
|
setCollaboratorCanvas,
|
|
66
54
|
setOverlayCanvas,
|
|
67
55
|
setTheme,
|
|
56
|
+
showCheckResults,
|
|
68
57
|
} = model
|
|
69
58
|
const { classes } = useStyles()
|
|
70
59
|
const lgv = getContainingView(model) as unknown as LinearGenomeViewModel
|
|
@@ -95,12 +84,16 @@ export const LinearApolloSixFrameDisplay = observer(
|
|
|
95
84
|
} else {
|
|
96
85
|
const coord: [number, number] = [event.clientX, event.clientY]
|
|
97
86
|
setContextCoord(coord)
|
|
98
|
-
setContextMenuItems(getContextMenuItems(
|
|
87
|
+
setContextMenuItems(getContextMenuItems(event))
|
|
99
88
|
}
|
|
100
89
|
}}
|
|
101
90
|
>
|
|
102
91
|
{message ? (
|
|
103
|
-
<Alert
|
|
92
|
+
<Alert
|
|
93
|
+
severity="warning"
|
|
94
|
+
classes={{ message: classes.ellipses }}
|
|
95
|
+
slotProps={{ root: { className: classes.center } }}
|
|
96
|
+
>
|
|
104
97
|
<Tooltip title={message}>
|
|
105
98
|
<div>{message}</div>
|
|
106
99
|
</Tooltip>
|
|
@@ -109,8 +102,13 @@ export const LinearApolloSixFrameDisplay = observer(
|
|
|
109
102
|
// Promise.resolve() in these 3 callbacks is to avoid infinite rendering loop
|
|
110
103
|
// https://github.com/mobxjs/mobx/issues/3728#issuecomment-1715400931
|
|
111
104
|
<>
|
|
112
|
-
<TrackLines model={model}
|
|
113
|
-
<TrackLines
|
|
105
|
+
<TrackLines model={model} idx={0} />
|
|
106
|
+
<TrackLines
|
|
107
|
+
model={model}
|
|
108
|
+
hrStyle={{ margin: 0, top: 0, color: 'grey', opacity: 0.4 }}
|
|
109
|
+
idx={1}
|
|
110
|
+
/>
|
|
111
|
+
<TrackLines model={model} idx={2} />
|
|
114
112
|
<canvas
|
|
115
113
|
ref={async (node: HTMLCanvasElement) => {
|
|
116
114
|
await Promise.resolve()
|
|
@@ -147,9 +145,12 @@ export const LinearApolloSixFrameDisplay = observer(
|
|
|
147
145
|
data-testid="overlayCanvas"
|
|
148
146
|
/>
|
|
149
147
|
{lgv.displayedRegions.flatMap((region, idx) => {
|
|
148
|
+
const widthBp = lgv.bpPerPx * apolloRowHeight
|
|
150
149
|
const assembly = assemblyManager.get(region.assemblyName)
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
if (showCheckResults) {
|
|
151
|
+
const filteredCheckResults = [
|
|
152
|
+
...session.apolloDataStore.checkResults.values(),
|
|
153
|
+
].filter(
|
|
153
154
|
(checkResult) =>
|
|
154
155
|
assembly?.isValidRefName(checkResult.refSeq) &&
|
|
155
156
|
assembly.getCanonicalRefName(checkResult.refSeq) ===
|
|
@@ -161,33 +162,92 @@ export const LinearApolloSixFrameDisplay = observer(
|
|
|
161
162
|
checkResult.end,
|
|
162
163
|
),
|
|
163
164
|
)
|
|
164
|
-
|
|
165
|
+
const checkResults = clusterResultByMessage<CheckResultI>(
|
|
166
|
+
filteredCheckResults,
|
|
167
|
+
widthBp,
|
|
168
|
+
true,
|
|
169
|
+
)
|
|
170
|
+
return checkResults.map((checkResult) => {
|
|
165
171
|
const left =
|
|
166
172
|
(lgv.bpToPx({
|
|
167
173
|
refName: region.refName,
|
|
168
174
|
coord: checkResult.start,
|
|
169
175
|
regionNumber: idx,
|
|
170
176
|
})?.offsetPx ?? 0) - lgv.offsetPx
|
|
171
|
-
const [feature] = checkResult.
|
|
177
|
+
const [feature] = checkResult.featureIds
|
|
172
178
|
if (!feature || !feature.parent?.looksLikeGene) {
|
|
173
179
|
return null
|
|
174
180
|
}
|
|
175
|
-
|
|
181
|
+
|
|
182
|
+
let row
|
|
183
|
+
for (const loc of feature.cdsLocations) {
|
|
184
|
+
for (const cds of loc) {
|
|
185
|
+
let rowNum: number = getFrame(
|
|
186
|
+
cds.min,
|
|
187
|
+
cds.max,
|
|
188
|
+
feature.strand ?? 1,
|
|
189
|
+
cds.phase,
|
|
190
|
+
)
|
|
191
|
+
rowNum = featureLabelSpacer(
|
|
192
|
+
rowNum < 0 ? -1 * rowNum + 5 : rowNum,
|
|
193
|
+
)
|
|
194
|
+
if (
|
|
195
|
+
checkResult.start >= cds.min &&
|
|
196
|
+
checkResult.start <= cds.max
|
|
197
|
+
) {
|
|
198
|
+
row = rowNum - 1
|
|
199
|
+
break
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (row === undefined) {
|
|
204
|
+
const rowNum =
|
|
205
|
+
feature.strand == 1
|
|
206
|
+
? geneTrackRowNums[0]
|
|
207
|
+
: geneTrackRowNums[1]
|
|
208
|
+
row = rowNum - 1
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const top = row * apolloRowHeight
|
|
176
212
|
const height = apolloRowHeight
|
|
177
213
|
return (
|
|
178
214
|
<Tooltip
|
|
179
215
|
key={checkResult._id}
|
|
180
216
|
title={checkResult.message}
|
|
181
217
|
>
|
|
182
|
-
<
|
|
183
|
-
className={classes.
|
|
184
|
-
style={{
|
|
218
|
+
<Box
|
|
219
|
+
className={classes.box}
|
|
220
|
+
style={{
|
|
221
|
+
top,
|
|
222
|
+
left,
|
|
223
|
+
height,
|
|
224
|
+
width: height,
|
|
225
|
+
pointerEvents: apolloDragging ? 'none' : 'auto',
|
|
226
|
+
}}
|
|
185
227
|
>
|
|
186
|
-
<
|
|
187
|
-
|
|
228
|
+
<Badge
|
|
229
|
+
className={classes.badge}
|
|
230
|
+
badgeContent={checkResult.count}
|
|
231
|
+
color="primary"
|
|
232
|
+
overlap="circular"
|
|
233
|
+
anchorOrigin={{
|
|
234
|
+
vertical: 'bottom',
|
|
235
|
+
horizontal: 'right',
|
|
236
|
+
}}
|
|
237
|
+
invisible={checkResult.count <= 1}
|
|
238
|
+
>
|
|
239
|
+
<Avatar className={classes.avatar}>
|
|
240
|
+
<ErrorIcon
|
|
241
|
+
data-testid={`ErrorIcon-${checkResult.start}`}
|
|
242
|
+
/>
|
|
243
|
+
</Avatar>
|
|
244
|
+
</Badge>
|
|
245
|
+
</Box>
|
|
188
246
|
</Tooltip>
|
|
189
247
|
)
|
|
190
248
|
})
|
|
249
|
+
}
|
|
250
|
+
return null
|
|
191
251
|
})}
|
|
192
252
|
<Menu
|
|
193
253
|
open={contextMenuItems.length > 0}
|
|
@@ -198,9 +258,11 @@ export const LinearApolloSixFrameDisplay = observer(
|
|
|
198
258
|
onClose={() => {
|
|
199
259
|
setContextMenuItems([])
|
|
200
260
|
}}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
261
|
+
slotProps={{
|
|
262
|
+
transition: {
|
|
263
|
+
onExit: () => {
|
|
264
|
+
setContextMenuItems([])
|
|
265
|
+
},
|
|
204
266
|
},
|
|
205
267
|
}}
|
|
206
268
|
anchorReference="anchorPosition"
|
|
@@ -5,36 +5,28 @@ import { type LinearApolloSixFrameDisplay } from '../stateModel'
|
|
|
5
5
|
|
|
6
6
|
export const TrackLines = observer(function TrackLines({
|
|
7
7
|
model,
|
|
8
|
-
|
|
8
|
+
hrStyle = { margin: 0, top: 0, color: 'black' },
|
|
9
|
+
idx = 0,
|
|
9
10
|
}: {
|
|
10
11
|
model: LinearApolloSixFrameDisplay
|
|
11
|
-
|
|
12
|
+
hrStyle?: React.CSSProperties
|
|
13
|
+
idx: number
|
|
12
14
|
}) {
|
|
13
|
-
const { apolloRowHeight, highestRow,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
position: 'absolute',
|
|
18
|
-
left: 0,
|
|
19
|
-
top: (apolloRowHeight * (highestRow + 1)) / 2 - 2,
|
|
20
|
-
width: '100%',
|
|
21
|
-
}}
|
|
22
|
-
>
|
|
23
|
-
<hr style={{ margin: 0, top: 0, color: 'black' }} />
|
|
24
|
-
</div>
|
|
25
|
-
) : (
|
|
15
|
+
const { apolloRowHeight, highestRow, showFeatureLabels } = model
|
|
16
|
+
const featureLabelSpacer = showFeatureLabels ? 2 : 1
|
|
17
|
+
|
|
18
|
+
return (
|
|
26
19
|
<div
|
|
27
20
|
style={{
|
|
28
21
|
position: 'absolute',
|
|
29
22
|
left: 0,
|
|
30
|
-
|
|
31
|
-
(apolloRowHeight * (highestRow + 1)
|
|
32
|
-
|
|
33
|
-
3,
|
|
23
|
+
top:
|
|
24
|
+
(apolloRowHeight * featureLabelSpacer * (highestRow + 1)) / 2 +
|
|
25
|
+
idx * featureLabelSpacer * apolloRowHeight,
|
|
34
26
|
width: '100%',
|
|
35
27
|
}}
|
|
36
28
|
>
|
|
37
|
-
<hr style={
|
|
29
|
+
<hr style={hrStyle} />
|
|
38
30
|
</div>
|
|
39
31
|
)
|
|
40
32
|
})
|