@apollo-annotation/jbrowse-plugin-apollo 0.3.5 → 0.3.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/index.esm.js +6964 -4598
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +6610 -4261
- 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 +11563 -7493
- 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 +4 -4
- package/src/ApolloInternetAccount/addMenuItems.ts +23 -2
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -0
- package/src/ApolloInternetAccount/components/LoginButtons.tsx +1 -1
- package/src/ApolloInternetAccount/components/LoginIcons.tsx +1 -1
- package/src/ApolloInternetAccount/configSchema.ts +1 -1
- package/src/ApolloInternetAccount/model.ts +11 -10
- package/src/ApolloJobModel.ts +1 -1
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +8 -6
- package/src/ApolloRefNameAliasAdapter/index.ts +2 -2
- package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +4 -4
- package/src/ApolloSequenceAdapter/index.ts +1 -1
- package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +8 -7
- package/src/ApolloTextSearchAdapter/index.ts +1 -1
- package/src/BackendDrivers/BackendDriver.ts +7 -7
- package/src/BackendDrivers/CollaborationServerDriver.ts +14 -10
- package/src/BackendDrivers/DesktopFileDriver.ts +11 -10
- package/src/BackendDrivers/InMemoryFileDriver.ts +10 -6
- package/src/ChangeManager.ts +15 -11
- package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +8 -7
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +35 -14
- package/src/FeatureDetailsWidget/AttributeKey.tsx +50 -0
- package/src/FeatureDetailsWidget/AttributeKeySelector.tsx +104 -0
- package/src/FeatureDetailsWidget/Attributes.tsx +215 -367
- package/src/FeatureDetailsWidget/BasicInformation.tsx +6 -5
- package/src/FeatureDetailsWidget/DefaultAttributeEditor.tsx +104 -0
- package/src/FeatureDetailsWidget/DefaultAttributeViewer.tsx +22 -0
- package/src/FeatureDetailsWidget/FeatureDetailsNavigation.tsx +4 -4
- package/src/FeatureDetailsWidget/NumberTextField.tsx +1 -1
- package/src/FeatureDetailsWidget/Sequence.tsx +2 -2
- package/src/FeatureDetailsWidget/StringTextField.tsx +1 -1
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +15 -23
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +950 -196
- package/src/FeatureDetailsWidget/TranscriptWidgetSummary.tsx +8 -4
- package/src/FeatureDetailsWidget/model.ts +8 -3
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +7 -7
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +59 -72
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +253 -60
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +52 -6
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +16 -8
- package/src/LinearApolloDisplay/stateModel/base.ts +81 -10
- package/src/LinearApolloDisplay/stateModel/index.ts +4 -3
- package/src/LinearApolloDisplay/stateModel/layouts.ts +8 -39
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +63 -46
- package/src/LinearApolloDisplay/stateModel/rendering.ts +60 -31
- package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +226 -0
- package/src/LinearApolloSixFrameDisplay/components/TrackLines.tsx +32 -0
- package/src/LinearApolloSixFrameDisplay/components/index.ts +2 -0
- package/src/LinearApolloSixFrameDisplay/configSchema.ts +7 -0
- package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +940 -0
- package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +63 -0
- package/src/LinearApolloSixFrameDisplay/glyphs/index.ts +1 -0
- package/src/LinearApolloSixFrameDisplay/index.ts +2 -0
- package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +302 -0
- package/src/LinearApolloSixFrameDisplay/stateModel/index.ts +27 -0
- package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +252 -0
- package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +368 -0
- package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +201 -0
- package/src/LinearApolloSixFrameDisplay/types.ts +1 -0
- package/src/OntologyManager/OntologyStore/fulltext.test.ts +1 -1
- package/src/OntologyManager/OntologyStore/fulltext.ts +8 -3
- package/src/OntologyManager/OntologyStore/index.test.ts +3 -1
- package/src/OntologyManager/OntologyStore/index.ts +19 -14
- package/src/OntologyManager/OntologyStore/indexeddb-schema.ts +6 -5
- package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +11 -5
- package/src/OntologyManager/index.ts +12 -7
- package/src/OntologyManager/util.ts +3 -2
- package/src/TabularEditor/HybridGrid/ChangeHandling.ts +2 -2
- package/src/TabularEditor/HybridGrid/Feature.tsx +13 -7
- package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +1 -1
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +3 -2
- package/src/TabularEditor/HybridGrid/ToolBar.tsx +1 -1
- package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +114 -22
- package/src/TabularEditor/TabularEditorPane.tsx +1 -1
- package/src/TabularEditor/model.ts +2 -2
- package/src/TabularEditor/types.ts +5 -2
- package/src/components/AddAssembly.tsx +182 -179
- package/src/components/AddAssemblyAliases.tsx +114 -0
- package/src/components/AddChildFeature.tsx +8 -10
- package/src/components/AddFeature.tsx +216 -44
- package/src/components/AddRefSeqAliases.tsx +14 -12
- package/src/components/CopyFeature.tsx +10 -11
- package/src/components/CreateApolloAnnotation.tsx +342 -158
- package/src/components/DeleteAssembly.tsx +9 -8
- package/src/components/DeleteFeature.tsx +362 -14
- package/src/components/Dialog.tsx +1 -1
- package/src/components/DownloadGFF3.tsx +31 -11
- package/src/components/FilterFeatures.tsx +6 -4
- package/src/components/FilterTranscripts.tsx +86 -0
- package/src/components/ImportFeatures.tsx +7 -6
- package/src/components/LogOut.tsx +5 -4
- package/src/components/ManageChecks.tsx +9 -8
- package/src/components/ManageUsers.tsx +11 -10
- package/src/components/MergeExons.tsx +193 -0
- package/src/components/MergeTranscripts.tsx +185 -0
- package/src/components/OntologyTermAutocomplete.tsx +5 -5
- package/src/components/OntologyTermMultiSelect.tsx +6 -6
- package/src/components/OpenLocalFile.tsx +4 -3
- package/src/components/SplitExon.tsx +134 -0
- package/src/components/ViewChangeLog.tsx +7 -6
- package/src/components/ViewCheckResults.tsx +8 -7
- package/src/components/index.ts +3 -0
- package/src/config.ts +5 -0
- package/src/extensions/annotationFromJBrowseFeature.test.ts +1 -0
- package/src/extensions/annotationFromJBrowseFeature.ts +13 -10
- package/src/extensions/annotationFromPileup.ts +104 -94
- package/src/index.ts +33 -50
- package/src/makeDisplayComponent.tsx +90 -37
- package/src/session/ClientDataStore.ts +21 -17
- package/src/session/session.ts +46 -39
- package/src/types.ts +4 -4
- package/src/util/annotationFeatureUtils.ts +66 -1
- package/src/util/copyToClipboard.ts +21 -0
- package/src/util/glyphUtils.ts +49 -0
- package/src/util/index.ts +5 -3
- package/src/util/loadAssemblyIntoClient.ts +10 -3
- package/src/util/mouseEventsUtils.ts +113 -0
- package/src/ApolloSixFrameRenderer/ApolloSixFrameRenderer.tsx +0 -13
- package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +0 -707
- package/src/ApolloSixFrameRenderer/configSchema.ts +0 -7
- package/src/ApolloSixFrameRenderer/index.ts +0 -3
- package/src/SixFrameFeatureDisplay/components/TrackLines.tsx +0 -19
- package/src/SixFrameFeatureDisplay/components/index.ts +0 -1
- package/src/SixFrameFeatureDisplay/configSchema.ts +0 -21
- package/src/SixFrameFeatureDisplay/index.ts +0 -2
- package/src/SixFrameFeatureDisplay/stateModel.ts +0 -443
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import type PluginManager from '@jbrowse/core/PluginManager'
|
|
3
|
+
import { type AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
|
|
4
4
|
import { defaultCodonTable, doesIntersect2, revcom } from '@jbrowse/core/util'
|
|
5
|
-
import { Theme } from '@mui/material'
|
|
5
|
+
import { type Theme } from '@mui/material'
|
|
6
6
|
import { autorun } from 'mobx'
|
|
7
|
-
import { Instance, addDisposer } from 'mobx-state-tree'
|
|
7
|
+
import { type Instance, addDisposer, types } from 'mobx-state-tree'
|
|
8
|
+
|
|
9
|
+
import { type ApolloSessionModel } from '../../session'
|
|
8
10
|
|
|
9
|
-
import { ApolloSessionModel } from '../../session'
|
|
10
11
|
import { layoutsModelFactory } from './layouts'
|
|
11
12
|
|
|
12
13
|
export function renderingModelIntermediateFactory(
|
|
@@ -26,6 +27,7 @@ export function renderingModelIntermediateFactory(
|
|
|
26
27
|
detailsHeight: 200,
|
|
27
28
|
lastRowTooltipBufferHeight: 40,
|
|
28
29
|
isShown: true,
|
|
30
|
+
filteredTranscripts: types.array(types.string),
|
|
29
31
|
})
|
|
30
32
|
.volatile(() => ({
|
|
31
33
|
canvas: null as HTMLCanvasElement | null,
|
|
@@ -145,10 +147,10 @@ function colorCode(letter: string, theme?: Theme) {
|
|
|
145
147
|
)
|
|
146
148
|
}
|
|
147
149
|
|
|
148
|
-
function codonColorCode(letter: string) {
|
|
150
|
+
function codonColorCode(letter: string, highContrast?: boolean) {
|
|
149
151
|
const colorMap: Record<string, string | undefined> = {
|
|
150
152
|
M: '#33ee33',
|
|
151
|
-
'*': '#f44336',
|
|
153
|
+
'*': highContrast ? '#000000' : '#f44336',
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
return colorMap[letter.toUpperCase()]
|
|
@@ -188,6 +190,9 @@ function drawTranslation(
|
|
|
188
190
|
seq: string,
|
|
189
191
|
i: number,
|
|
190
192
|
reverse: boolean,
|
|
193
|
+
showStartCodons: boolean,
|
|
194
|
+
showStopCodons: boolean,
|
|
195
|
+
highContrast: boolean,
|
|
191
196
|
) {
|
|
192
197
|
let codonSeq: string = seq.slice(i, i + 3).toUpperCase()
|
|
193
198
|
if (reverse) {
|
|
@@ -198,8 +203,12 @@ function drawTranslation(
|
|
|
198
203
|
if (!codonLetter) {
|
|
199
204
|
return
|
|
200
205
|
}
|
|
201
|
-
const fillColor = codonColorCode(codonLetter)
|
|
202
|
-
if (
|
|
206
|
+
const fillColor = codonColorCode(codonLetter, highContrast)
|
|
207
|
+
if (
|
|
208
|
+
fillColor &&
|
|
209
|
+
((showStopCodons && codonLetter == '*') ||
|
|
210
|
+
(showStartCodons && codonLetter != '*'))
|
|
211
|
+
) {
|
|
203
212
|
seqTrackctx.fillStyle = fillColor
|
|
204
213
|
seqTrackctx.fillRect(trnslStartPx, trnslY, trnslWidthPx, sequenceRowHeight)
|
|
205
214
|
}
|
|
@@ -224,11 +233,13 @@ export function sequenceRenderingModelFactory(
|
|
|
224
233
|
addDisposer(
|
|
225
234
|
self,
|
|
226
235
|
autorun(
|
|
227
|
-
|
|
236
|
+
() => {
|
|
237
|
+
const { theme } = self
|
|
228
238
|
if (!self.lgv.initialized || self.regionCannotBeRendered()) {
|
|
229
239
|
return
|
|
230
240
|
}
|
|
231
|
-
|
|
241
|
+
const trnslWidthPx = 3 / self.lgv.bpPerPx
|
|
242
|
+
if (trnslWidthPx < 1) {
|
|
232
243
|
return
|
|
233
244
|
}
|
|
234
245
|
const seqTrackctx = self.seqTrackCanvas?.getContext('2d')
|
|
@@ -247,30 +258,43 @@ export function sequenceRenderingModelFactory(
|
|
|
247
258
|
? [3, 2, 1, 0, 0, -1, -2, -3]
|
|
248
259
|
: [3, 2, 1, -1, -2, -3]
|
|
249
260
|
let height = 0
|
|
250
|
-
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
261
|
+
if (theme) {
|
|
262
|
+
for (const frame of frames) {
|
|
263
|
+
let frameColor = theme.palette.framesCDS.at(frame)?.main
|
|
264
|
+
if (frameColor) {
|
|
265
|
+
let offsetPx = 0
|
|
266
|
+
if (self.highContrast) {
|
|
267
|
+
frameColor = 'white'
|
|
268
|
+
offsetPx = 1
|
|
269
|
+
// eslint-disable-next-line prefer-destructuring
|
|
270
|
+
seqTrackctx.fillStyle = theme.palette.grey[200]
|
|
271
|
+
seqTrackctx.fillRect(
|
|
272
|
+
0,
|
|
273
|
+
height,
|
|
274
|
+
self.lgv.dynamicBlocks.totalWidthPx,
|
|
275
|
+
self.sequenceRowHeight,
|
|
276
|
+
)
|
|
277
|
+
}
|
|
278
|
+
seqTrackctx.fillStyle = frameColor
|
|
279
|
+
seqTrackctx.fillRect(
|
|
280
|
+
0 + offsetPx,
|
|
281
|
+
height + offsetPx,
|
|
282
|
+
self.lgv.dynamicBlocks.totalWidthPx - 2 * offsetPx,
|
|
283
|
+
self.sequenceRowHeight - 2 * offsetPx,
|
|
284
|
+
)
|
|
285
|
+
}
|
|
286
|
+
height += self.sequenceRowHeight
|
|
260
287
|
}
|
|
261
|
-
height += self.sequenceRowHeight
|
|
262
288
|
}
|
|
263
289
|
|
|
264
290
|
for (const [idx, region] of self.regions.entries()) {
|
|
265
|
-
const
|
|
291
|
+
const { apolloDataStore } =
|
|
266
292
|
self.session as unknown as ApolloSessionModel
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
const { seq } = await driver.getSequence(region)
|
|
273
|
-
|
|
293
|
+
const assembly = apolloDataStore.assemblies.get(
|
|
294
|
+
region.assemblyName,
|
|
295
|
+
)
|
|
296
|
+
const ref = assembly?.getByRefName(region.refName)
|
|
297
|
+
const seq = ref?.getSequence(region.start, region.end)
|
|
274
298
|
if (!seq) {
|
|
275
299
|
return
|
|
276
300
|
}
|
|
@@ -283,7 +307,6 @@ export function sequenceRenderingModelFactory(
|
|
|
283
307
|
coord: region.start + i,
|
|
284
308
|
regionNumber: idx,
|
|
285
309
|
})?.offsetPx ?? 0) - self.lgv.offsetPx
|
|
286
|
-
const trnslWidthPx = 3 / self.lgv.bpPerPx
|
|
287
310
|
const trnslStartPx = self.lgv.displayedRegions[idx].reversed
|
|
288
311
|
? trnslXOffset - trnslWidthPx
|
|
289
312
|
: trnslXOffset
|
|
@@ -301,6 +324,9 @@ export function sequenceRenderingModelFactory(
|
|
|
301
324
|
seq,
|
|
302
325
|
i,
|
|
303
326
|
false,
|
|
327
|
+
self.showStartCodons,
|
|
328
|
+
self.showStopCodons,
|
|
329
|
+
self.highContrast,
|
|
304
330
|
)
|
|
305
331
|
}
|
|
306
332
|
}
|
|
@@ -375,6 +401,9 @@ export function sequenceRenderingModelFactory(
|
|
|
375
401
|
seq,
|
|
376
402
|
i,
|
|
377
403
|
true,
|
|
404
|
+
self.showStartCodons,
|
|
405
|
+
self.showStopCodons,
|
|
406
|
+
self.highContrast,
|
|
378
407
|
)
|
|
379
408
|
}
|
|
380
409
|
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
4
|
+
import { Menu, type MenuItem } from '@jbrowse/core/ui'
|
|
5
|
+
import {
|
|
6
|
+
type AbstractSessionModel,
|
|
7
|
+
doesIntersect2,
|
|
8
|
+
getContainingView,
|
|
9
|
+
} from '@jbrowse/core/util'
|
|
10
|
+
import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
11
|
+
import ErrorIcon from '@mui/icons-material/Error'
|
|
12
|
+
import { Alert, Avatar, Tooltip, useTheme } from '@mui/material'
|
|
13
|
+
import { observer } from 'mobx-react'
|
|
14
|
+
import React, { useEffect, useState } from 'react'
|
|
15
|
+
import { makeStyles } from 'tss-react/mui'
|
|
16
|
+
|
|
17
|
+
import { type LinearApolloSixFrameDisplay as LinearApolloSixFrameDisplayI } from '../stateModel'
|
|
18
|
+
|
|
19
|
+
import { TrackLines } from './TrackLines'
|
|
20
|
+
|
|
21
|
+
interface LinearApolloSixFrameDisplayProps {
|
|
22
|
+
model: LinearApolloSixFrameDisplayI
|
|
23
|
+
}
|
|
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
|
+
|
|
46
|
+
export const LinearApolloSixFrameDisplay = observer(
|
|
47
|
+
function LinearApolloSixFrameDisplay(
|
|
48
|
+
props: LinearApolloSixFrameDisplayProps,
|
|
49
|
+
) {
|
|
50
|
+
const theme = useTheme()
|
|
51
|
+
const { model } = props
|
|
52
|
+
const {
|
|
53
|
+
apolloRowHeight,
|
|
54
|
+
contextMenuItems: getContextMenuItems,
|
|
55
|
+
cursor,
|
|
56
|
+
featuresHeight,
|
|
57
|
+
isShown,
|
|
58
|
+
onMouseDown,
|
|
59
|
+
onMouseLeave,
|
|
60
|
+
onMouseMove,
|
|
61
|
+
onMouseUp,
|
|
62
|
+
regionCannotBeRendered,
|
|
63
|
+
session,
|
|
64
|
+
setCanvas,
|
|
65
|
+
setCollaboratorCanvas,
|
|
66
|
+
setOverlayCanvas,
|
|
67
|
+
setTheme,
|
|
68
|
+
} = model
|
|
69
|
+
const { classes } = useStyles()
|
|
70
|
+
const lgv = getContainingView(model) as unknown as LinearGenomeViewModel
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
setTheme(theme)
|
|
74
|
+
}, [theme, setTheme])
|
|
75
|
+
const [contextCoord, setContextCoord] = useState<Coord>()
|
|
76
|
+
const [contextMenuItems, setContextMenuItems] = useState<MenuItem[]>([])
|
|
77
|
+
const message = regionCannotBeRendered()
|
|
78
|
+
if (!isShown) {
|
|
79
|
+
return null
|
|
80
|
+
}
|
|
81
|
+
const { assemblyManager } = session as unknown as AbstractSessionModel
|
|
82
|
+
return (
|
|
83
|
+
<>
|
|
84
|
+
<div
|
|
85
|
+
className={classes.canvasContainer}
|
|
86
|
+
style={{
|
|
87
|
+
width: lgv.dynamicBlocks.totalWidthPx,
|
|
88
|
+
height: featuresHeight,
|
|
89
|
+
}}
|
|
90
|
+
onContextMenu={(event) => {
|
|
91
|
+
event.preventDefault()
|
|
92
|
+
if (contextMenuItems.length > 0) {
|
|
93
|
+
// There's already a context menu open, so close it
|
|
94
|
+
setContextMenuItems([])
|
|
95
|
+
} else {
|
|
96
|
+
const coord: [number, number] = [event.clientX, event.clientY]
|
|
97
|
+
setContextCoord(coord)
|
|
98
|
+
setContextMenuItems(getContextMenuItems(coord))
|
|
99
|
+
}
|
|
100
|
+
}}
|
|
101
|
+
>
|
|
102
|
+
{message ? (
|
|
103
|
+
<Alert severity="warning" classes={{ message: classes.ellipses }}>
|
|
104
|
+
<Tooltip title={message}>
|
|
105
|
+
<div>{message}</div>
|
|
106
|
+
</Tooltip>
|
|
107
|
+
</Alert>
|
|
108
|
+
) : (
|
|
109
|
+
// Promise.resolve() in these 3 callbacks is to avoid infinite rendering loop
|
|
110
|
+
// https://github.com/mobxjs/mobx/issues/3728#issuecomment-1715400931
|
|
111
|
+
<>
|
|
112
|
+
<TrackLines model={model} idx={0} />
|
|
113
|
+
<TrackLines
|
|
114
|
+
model={model}
|
|
115
|
+
hrStyle={{ margin: 0, top: 0, color: 'grey', opacity: 0.4 }}
|
|
116
|
+
idx={1}
|
|
117
|
+
/>
|
|
118
|
+
<TrackLines model={model} idx={2} />
|
|
119
|
+
<canvas
|
|
120
|
+
ref={async (node: HTMLCanvasElement) => {
|
|
121
|
+
await Promise.resolve()
|
|
122
|
+
setCollaboratorCanvas(node)
|
|
123
|
+
}}
|
|
124
|
+
width={lgv.dynamicBlocks.totalWidthPx}
|
|
125
|
+
height={featuresHeight}
|
|
126
|
+
className={classes.canvas}
|
|
127
|
+
data-testid="collaboratorCanvas"
|
|
128
|
+
/>
|
|
129
|
+
<canvas
|
|
130
|
+
ref={async (node: HTMLCanvasElement) => {
|
|
131
|
+
await Promise.resolve()
|
|
132
|
+
setCanvas(node)
|
|
133
|
+
}}
|
|
134
|
+
width={lgv.dynamicBlocks.totalWidthPx}
|
|
135
|
+
height={featuresHeight}
|
|
136
|
+
className={classes.canvas}
|
|
137
|
+
data-testid="canvas"
|
|
138
|
+
/>
|
|
139
|
+
<canvas
|
|
140
|
+
ref={async (node: HTMLCanvasElement) => {
|
|
141
|
+
await Promise.resolve()
|
|
142
|
+
setOverlayCanvas(node)
|
|
143
|
+
}}
|
|
144
|
+
width={lgv.dynamicBlocks.totalWidthPx}
|
|
145
|
+
height={featuresHeight}
|
|
146
|
+
onMouseMove={onMouseMove}
|
|
147
|
+
onMouseLeave={onMouseLeave}
|
|
148
|
+
onMouseDown={onMouseDown}
|
|
149
|
+
onMouseUp={onMouseUp}
|
|
150
|
+
className={classes.canvas}
|
|
151
|
+
style={{ cursor: cursor ?? 'default' }}
|
|
152
|
+
data-testid="overlayCanvas"
|
|
153
|
+
/>
|
|
154
|
+
{lgv.displayedRegions.flatMap((region, idx) => {
|
|
155
|
+
const assembly = assemblyManager.get(region.assemblyName)
|
|
156
|
+
return [...session.apolloDataStore.checkResults.values()]
|
|
157
|
+
.filter(
|
|
158
|
+
(checkResult) =>
|
|
159
|
+
assembly?.isValidRefName(checkResult.refSeq) &&
|
|
160
|
+
assembly.getCanonicalRefName(checkResult.refSeq) ===
|
|
161
|
+
region.refName &&
|
|
162
|
+
doesIntersect2(
|
|
163
|
+
region.start,
|
|
164
|
+
region.end,
|
|
165
|
+
checkResult.start,
|
|
166
|
+
checkResult.end,
|
|
167
|
+
),
|
|
168
|
+
)
|
|
169
|
+
.map((checkResult) => {
|
|
170
|
+
const left =
|
|
171
|
+
(lgv.bpToPx({
|
|
172
|
+
refName: region.refName,
|
|
173
|
+
coord: checkResult.start,
|
|
174
|
+
regionNumber: idx,
|
|
175
|
+
})?.offsetPx ?? 0) - lgv.offsetPx
|
|
176
|
+
const [feature] = checkResult.ids
|
|
177
|
+
if (!feature || !feature.parent?.looksLikeGene) {
|
|
178
|
+
return null
|
|
179
|
+
}
|
|
180
|
+
const top = 0
|
|
181
|
+
const height = apolloRowHeight
|
|
182
|
+
return (
|
|
183
|
+
<Tooltip
|
|
184
|
+
key={checkResult._id}
|
|
185
|
+
title={checkResult.message}
|
|
186
|
+
>
|
|
187
|
+
<Avatar
|
|
188
|
+
className={classes.avatar}
|
|
189
|
+
style={{ top, left, height, width: height }}
|
|
190
|
+
>
|
|
191
|
+
<ErrorIcon />
|
|
192
|
+
</Avatar>
|
|
193
|
+
</Tooltip>
|
|
194
|
+
)
|
|
195
|
+
})
|
|
196
|
+
})}
|
|
197
|
+
<Menu
|
|
198
|
+
open={contextMenuItems.length > 0}
|
|
199
|
+
onMenuItemClick={(_, callback) => {
|
|
200
|
+
callback()
|
|
201
|
+
setContextMenuItems([])
|
|
202
|
+
}}
|
|
203
|
+
onClose={() => {
|
|
204
|
+
setContextMenuItems([])
|
|
205
|
+
}}
|
|
206
|
+
TransitionProps={{
|
|
207
|
+
onExit: () => {
|
|
208
|
+
setContextMenuItems([])
|
|
209
|
+
},
|
|
210
|
+
}}
|
|
211
|
+
anchorReference="anchorPosition"
|
|
212
|
+
anchorPosition={
|
|
213
|
+
contextCoord
|
|
214
|
+
? { top: contextCoord[1], left: contextCoord[0] }
|
|
215
|
+
: undefined
|
|
216
|
+
}
|
|
217
|
+
style={{ zIndex: theme.zIndex.tooltip }}
|
|
218
|
+
menuItems={contextMenuItems}
|
|
219
|
+
/>
|
|
220
|
+
</>
|
|
221
|
+
)}
|
|
222
|
+
</div>
|
|
223
|
+
</>
|
|
224
|
+
)
|
|
225
|
+
},
|
|
226
|
+
)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { observer } from 'mobx-react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import { type LinearApolloSixFrameDisplay } from '../stateModel'
|
|
5
|
+
|
|
6
|
+
export const TrackLines = observer(function TrackLines({
|
|
7
|
+
model,
|
|
8
|
+
hrStyle = { margin: 0, top: 0, color: 'black' },
|
|
9
|
+
idx = 0,
|
|
10
|
+
}: {
|
|
11
|
+
model: LinearApolloSixFrameDisplay
|
|
12
|
+
hrStyle?: React.CSSProperties
|
|
13
|
+
idx: number
|
|
14
|
+
}) {
|
|
15
|
+
const { apolloRowHeight, highestRow, showFeatureLabels } = model
|
|
16
|
+
const featureLabelSpacer = showFeatureLabels ? 2 : 1
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div
|
|
20
|
+
style={{
|
|
21
|
+
position: 'absolute',
|
|
22
|
+
left: 0,
|
|
23
|
+
top:
|
|
24
|
+
(apolloRowHeight * featureLabelSpacer * (highestRow + 1)) / 2 +
|
|
25
|
+
idx * featureLabelSpacer * apolloRowHeight,
|
|
26
|
+
width: '100%',
|
|
27
|
+
}}
|
|
28
|
+
>
|
|
29
|
+
<hr style={hrStyle} />
|
|
30
|
+
</div>
|
|
31
|
+
)
|
|
32
|
+
})
|