@apollo-annotation/jbrowse-plugin-apollo 0.1.18 → 0.1.20
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 +3189 -3575
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +3185 -3570
- 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 +14884 -15905
- 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 +33 -33
- package/src/ApolloInternetAccount/addMenuItems.ts +18 -0
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -0
- package/src/ApolloInternetAccount/configSchema.ts +5 -2
- package/src/ApolloInternetAccount/model.ts +14 -5
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +94 -0
- package/src/ApolloRefNameAliasAdapter/configSchema.ts +12 -0
- package/src/ApolloRefNameAliasAdapter/index.ts +21 -0
- package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +1 -0
- package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +10 -10
- package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +35 -32
- package/src/BackendDrivers/BackendDriver.ts +8 -0
- package/src/BackendDrivers/CollaborationServerDriver.ts +49 -1
- package/src/BackendDrivers/DesktopFileDriver.ts +14 -1
- package/src/BackendDrivers/InMemoryFileDriver.ts +17 -1
- package/src/ChangeManager.ts +1 -1
- package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +5 -25
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +82 -0
- package/src/FeatureDetailsWidget/Attributes.tsx +11 -3
- package/src/FeatureDetailsWidget/BasicInformation.tsx +38 -30
- package/src/FeatureDetailsWidget/Sequence.tsx +7 -7
- package/src/FeatureDetailsWidget/TranscriptBasic.tsx +446 -0
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +365 -0
- package/src/FeatureDetailsWidget/index.ts +2 -0
- package/src/FeatureDetailsWidget/model.ts +77 -9
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +0 -2
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +453 -380
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +520 -0
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +138 -134
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +38 -370
- package/src/LinearApolloDisplay/glyphs/index.ts +1 -2
- package/src/LinearApolloDisplay/stateModel/base.ts +3 -6
- package/src/LinearApolloDisplay/stateModel/getGlyph.ts +30 -30
- package/src/LinearApolloDisplay/stateModel/index.ts +5 -1
- package/src/LinearApolloDisplay/stateModel/layouts.ts +32 -24
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +206 -217
- package/src/LinearApolloDisplay/stateModel/rendering.ts +43 -67
- package/src/OntologyManager/OntologyStore/fulltext.ts +1 -1
- package/src/OntologyManager/OntologyStore/index.ts +2 -1
- package/src/OntologyManager/index.ts +6 -2
- package/src/OntologyManager/util.ts +2 -2
- package/src/SixFrameFeatureDisplay/stateModel.ts +15 -10
- package/src/TabularEditor/HybridGrid/ChangeHandling.ts +21 -46
- package/src/TabularEditor/HybridGrid/Feature.tsx +31 -82
- package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +3 -2
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +2 -3
- package/src/TabularEditor/HybridGrid/NumberCell.tsx +1 -0
- package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +46 -5
- package/src/TabularEditor/model.ts +5 -3
- package/src/components/AddAssembly.tsx +15 -9
- package/src/components/AddChildFeature.tsx +7 -73
- package/src/components/AddFeature.tsx +2 -57
- package/src/components/AddRefSeqAliases.tsx +285 -0
- package/src/components/CopyFeature.tsx +16 -33
- package/src/components/DeleteFeature.tsx +4 -6
- package/src/components/ImportFeatures.tsx +6 -3
- package/src/components/LogOut.tsx +105 -0
- package/src/components/ManageChecks.tsx +1 -0
- package/src/components/ManageUsers.tsx +21 -1
- package/src/components/ModifyFeatureAttribute.tsx +2 -2
- package/src/components/OntologyTermAutocomplete.tsx +0 -2
- package/src/components/OntologyTermMultiSelect.tsx +1 -0
- package/src/components/OpenLocalFile.tsx +6 -5
- package/src/components/ViewChangeLog.tsx +1 -0
- package/src/components/ViewCheckResults.tsx +1 -0
- package/src/components/index.ts +4 -0
- package/src/extensions/annotationFromPileup.ts +10 -16
- package/src/index.ts +57 -3
- package/src/session/ClientDataStore.ts +49 -46
- package/src/session/session.ts +186 -114
- package/src/util/loadAssemblyIntoClient.ts +4 -210
- package/src/FeatureDetailsWidget/RelatedFeature.tsx +0 -97
- package/src/LinearApolloDisplay/glyphs/CanonicalGeneGlyph.ts +0 -1204
- package/src/LinearApolloDisplay/glyphs/ImplicitExonGeneGlyph.ts +0 -716
- package/src/LinearApolloDisplay/stateModel/glyphs.ts +0 -47
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { AnnotationFeature } from '@apollo-annotation/mst'
|
|
2
|
+
import {
|
|
3
|
+
LocationEndChange,
|
|
4
|
+
LocationStartChange,
|
|
5
|
+
} from '@apollo-annotation/shared'
|
|
4
6
|
import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
|
|
5
7
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
6
8
|
import { MenuItem } from '@jbrowse/core/ui'
|
|
@@ -15,6 +17,13 @@ import { Glyph } from '../glyphs/Glyph'
|
|
|
15
17
|
import { CanvasMouseEvent } from '../types'
|
|
16
18
|
import { getGlyph } from './getGlyph'
|
|
17
19
|
import { renderingModelFactory } from './rendering'
|
|
20
|
+
import { Frame, getFrame } from '@jbrowse/core/util'
|
|
21
|
+
|
|
22
|
+
export interface FeatureAndGlyphUnderMouse {
|
|
23
|
+
feature: AnnotationFeature
|
|
24
|
+
topLevelFeature: AnnotationFeature
|
|
25
|
+
glyph: Glyph
|
|
26
|
+
}
|
|
18
27
|
|
|
19
28
|
/** extended information about the position of the mouse on the canvas, including the refName, bp, and displayedRegion number */
|
|
20
29
|
export interface MousePosition {
|
|
@@ -23,20 +32,15 @@ export interface MousePosition {
|
|
|
23
32
|
refName: string
|
|
24
33
|
bp: number
|
|
25
34
|
regionNumber: number
|
|
35
|
+
featureAndGlyphUnderMouse?: FeatureAndGlyphUnderMouse
|
|
26
36
|
}
|
|
27
37
|
|
|
28
|
-
export
|
|
29
|
-
feature?: AnnotationFeatureI
|
|
30
|
-
topLevelFeature?: AnnotationFeatureI
|
|
31
|
-
glyph?: Glyph
|
|
32
|
-
mousePosition?: MousePosition
|
|
33
|
-
}
|
|
38
|
+
export type MousePositionWithFeatureAndGlyph = Required<MousePosition>
|
|
34
39
|
|
|
35
|
-
export
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
idx?: number
|
|
40
|
+
export function isMousePositionWithFeatureAndGlyph(
|
|
41
|
+
mousePosition: MousePosition,
|
|
42
|
+
): mousePosition is MousePositionWithFeatureAndGlyph {
|
|
43
|
+
return 'featureAndGlyphUnderMouse' in mousePosition
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
function getMousePosition(
|
|
@@ -45,26 +49,45 @@ function getMousePosition(
|
|
|
45
49
|
): MousePosition {
|
|
46
50
|
const canvas = event.currentTarget
|
|
47
51
|
const { clientX, clientY } = event
|
|
48
|
-
const { left, top } = canvas.getBoundingClientRect()
|
|
52
|
+
const { left, top } = canvas.getBoundingClientRect()
|
|
49
53
|
const x = clientX - left
|
|
50
54
|
const y = clientY - top
|
|
51
55
|
const { coord: bp, index: regionNumber, refName } = lgv.pxToBp(x)
|
|
52
56
|
return { x, y, refName, bp, regionNumber }
|
|
53
57
|
}
|
|
54
58
|
|
|
55
|
-
function
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
function getTranslationRow(frame: Frame, bpPerPx: number) {
|
|
60
|
+
const offset = bpPerPx <= 1 ? 2 : 0
|
|
61
|
+
switch (frame) {
|
|
62
|
+
case 3: {
|
|
63
|
+
return 0
|
|
64
|
+
}
|
|
65
|
+
case 2: {
|
|
66
|
+
return 1
|
|
67
|
+
}
|
|
68
|
+
case 1: {
|
|
69
|
+
return 2
|
|
70
|
+
}
|
|
71
|
+
case -1: {
|
|
72
|
+
return 3 + offset
|
|
73
|
+
}
|
|
74
|
+
case -2: {
|
|
75
|
+
return 4 + offset
|
|
76
|
+
}
|
|
77
|
+
case -3: {
|
|
78
|
+
return 5 + offset
|
|
79
|
+
}
|
|
61
80
|
}
|
|
81
|
+
}
|
|
62
82
|
|
|
63
|
-
|
|
64
|
-
|
|
83
|
+
function getSeqRow(
|
|
84
|
+
strand: 1 | -1 | undefined,
|
|
85
|
+
bpPerPx: number,
|
|
86
|
+
): number | undefined {
|
|
87
|
+
if (bpPerPx > 1 || strand === undefined) {
|
|
88
|
+
return
|
|
65
89
|
}
|
|
66
|
-
|
|
67
|
-
return
|
|
90
|
+
return strand === 1 ? 3 : 4
|
|
68
91
|
}
|
|
69
92
|
|
|
70
93
|
function highlightSeq(
|
|
@@ -99,72 +122,62 @@ export function mouseEventsModelIntermediateFactory(
|
|
|
99
122
|
return LinearApolloDisplayRendering.named('LinearApolloDisplayMouseEvents')
|
|
100
123
|
.volatile(() => ({
|
|
101
124
|
apolloDragging: null as {
|
|
102
|
-
start:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
discontinuousLocation?: CDSDiscontinuousLocation
|
|
107
|
-
mousePosition: MousePosition
|
|
108
|
-
}
|
|
109
|
-
current: {
|
|
110
|
-
glyph?: Glyph
|
|
111
|
-
feature?: AnnotationFeatureI
|
|
112
|
-
topLevelFeature?: AnnotationFeatureI
|
|
113
|
-
mousePosition: MousePosition
|
|
114
|
-
}
|
|
125
|
+
start: MousePosition
|
|
126
|
+
current: MousePosition
|
|
127
|
+
feature: AnnotationFeature
|
|
128
|
+
edge: 'min' | 'max'
|
|
115
129
|
} | null,
|
|
116
130
|
cursor: undefined as CSSProperties['cursor'] | undefined,
|
|
117
|
-
apolloHover:
|
|
131
|
+
apolloHover: undefined as FeatureAndGlyphUnderMouse | undefined,
|
|
118
132
|
}))
|
|
119
133
|
.views((self) => ({
|
|
120
|
-
|
|
121
|
-
event: CanvasMouseEvent,
|
|
122
|
-
): FeatureAndGlyphInfo {
|
|
134
|
+
getMousePosition(event: CanvasMouseEvent): MousePosition {
|
|
123
135
|
const mousePosition = getMousePosition(event, self.lgv)
|
|
124
136
|
const { bp, regionNumber, y } = mousePosition
|
|
125
137
|
const row = Math.floor(y / self.apolloRowHeight)
|
|
126
138
|
const featureLayout = self.featureLayouts[regionNumber]
|
|
127
139
|
const layoutRow = featureLayout.get(row)
|
|
128
140
|
if (!layoutRow) {
|
|
129
|
-
return
|
|
141
|
+
return mousePosition
|
|
130
142
|
}
|
|
131
143
|
const foundFeature = layoutRow.find(
|
|
132
144
|
(f) => bp >= f[1].min && bp <= f[1].max,
|
|
133
145
|
)
|
|
134
146
|
if (!foundFeature) {
|
|
135
|
-
return
|
|
147
|
+
return mousePosition
|
|
136
148
|
}
|
|
137
149
|
const [featureRow, topLevelFeature] = foundFeature
|
|
138
|
-
const glyph = getGlyph(topLevelFeature
|
|
150
|
+
const glyph = getGlyph(topLevelFeature)
|
|
139
151
|
const feature = glyph.getFeatureFromLayout(
|
|
140
152
|
topLevelFeature,
|
|
141
153
|
bp,
|
|
142
154
|
featureRow,
|
|
143
155
|
)
|
|
144
|
-
|
|
156
|
+
if (!feature) {
|
|
157
|
+
return mousePosition
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
...mousePosition,
|
|
161
|
+
featureAndGlyphUnderMouse: { feature, topLevelFeature, glyph },
|
|
162
|
+
}
|
|
145
163
|
},
|
|
146
164
|
}))
|
|
147
165
|
.actions((self) => ({
|
|
148
|
-
continueDrag(event: CanvasMouseEvent) {
|
|
166
|
+
continueDrag(mousePosition: MousePosition, event: CanvasMouseEvent) {
|
|
149
167
|
if (!self.apolloDragging) {
|
|
150
168
|
throw new Error(
|
|
151
169
|
'continueDrag() called with no current drag in progress',
|
|
152
170
|
)
|
|
153
171
|
}
|
|
154
172
|
event.stopPropagation()
|
|
155
|
-
|
|
156
|
-
const { mousePosition } = self.getFeatureAndGlyphUnderMouse(event)
|
|
157
|
-
if (!(mousePosition && glyph)) {
|
|
158
|
-
return
|
|
159
|
-
}
|
|
160
|
-
glyph.continueDrag(self, mousePosition)
|
|
173
|
+
self.apolloDragging = { ...self.apolloDragging, current: mousePosition }
|
|
161
174
|
},
|
|
162
175
|
setDragging(dragInfo?: typeof self.apolloDragging) {
|
|
163
176
|
self.apolloDragging = dragInfo ?? null
|
|
164
177
|
},
|
|
165
178
|
}))
|
|
166
179
|
.actions((self) => ({
|
|
167
|
-
setApolloHover(n
|
|
180
|
+
setApolloHover(n?: (typeof self)['apolloHover']) {
|
|
168
181
|
self.apolloHover = n
|
|
169
182
|
},
|
|
170
183
|
setCursor(cursor?: CSSProperties['cursor']) {
|
|
@@ -196,6 +209,8 @@ export function mouseEventsSeqHightlightModelFactory(
|
|
|
196
209
|
self,
|
|
197
210
|
autorun(
|
|
198
211
|
() => {
|
|
212
|
+
// This type is wrong in @jbrowse/core
|
|
213
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
199
214
|
if (!self.lgv.initialized || self.regionCannotBeRendered()) {
|
|
200
215
|
return
|
|
201
216
|
}
|
|
@@ -212,38 +227,43 @@ export function mouseEventsSeqHightlightModelFactory(
|
|
|
212
227
|
self.lgv.bpPerPx <= 1 ? 125 : 95,
|
|
213
228
|
)
|
|
214
229
|
|
|
215
|
-
const {
|
|
216
|
-
apolloHover,
|
|
217
|
-
displayedRegions,
|
|
218
|
-
lgv,
|
|
219
|
-
regions,
|
|
220
|
-
sequenceRowHeight,
|
|
221
|
-
theme,
|
|
222
|
-
} = self
|
|
230
|
+
const { apolloHover, lgv, regions, sequenceRowHeight, theme } = self
|
|
223
231
|
|
|
224
232
|
if (!apolloHover) {
|
|
225
233
|
return
|
|
226
234
|
}
|
|
227
|
-
const { feature
|
|
228
|
-
if (!feature || !mousePosition) {
|
|
229
|
-
return
|
|
230
|
-
}
|
|
235
|
+
const { feature } = apolloHover
|
|
231
236
|
|
|
232
237
|
for (const [idx, region] of regions.entries()) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
238
|
+
if (feature.type === 'CDS') {
|
|
239
|
+
const parentFeature = feature.parent
|
|
240
|
+
if (!parentFeature) {
|
|
241
|
+
continue
|
|
242
|
+
}
|
|
243
|
+
const cdsLocs = parentFeature.cdsLocations.find(
|
|
244
|
+
(loc) =>
|
|
245
|
+
feature.min === loc.at(0)?.min &&
|
|
246
|
+
feature.max === loc.at(-1)?.max,
|
|
247
|
+
)
|
|
248
|
+
if (!cdsLocs) {
|
|
249
|
+
continue
|
|
250
|
+
}
|
|
251
|
+
for (const dl of cdsLocs) {
|
|
252
|
+
const frame = getFrame(
|
|
253
|
+
dl.min,
|
|
254
|
+
dl.max,
|
|
255
|
+
feature.strand ?? 1,
|
|
256
|
+
dl.phase,
|
|
257
|
+
)
|
|
258
|
+
const row = getTranslationRow(frame, lgv.bpPerPx)
|
|
239
259
|
const offset =
|
|
240
260
|
(lgv.bpToPx({
|
|
241
261
|
refName: region.refName,
|
|
242
|
-
coord: dl.
|
|
262
|
+
coord: dl.min,
|
|
243
263
|
regionNumber: idx,
|
|
244
264
|
})?.offsetPx ?? 0) - lgv.offsetPx
|
|
245
|
-
const widthPx = (dl.
|
|
246
|
-
const startPx = displayedRegions[idx].reversed
|
|
265
|
+
const widthPx = (dl.max - dl.min) / lgv.bpPerPx
|
|
266
|
+
const startPx = lgv.displayedRegions[idx].reversed
|
|
247
267
|
? offset - widthPx
|
|
248
268
|
: offset
|
|
249
269
|
|
|
@@ -257,14 +277,15 @@ export function mouseEventsSeqHightlightModelFactory(
|
|
|
257
277
|
)
|
|
258
278
|
}
|
|
259
279
|
} else {
|
|
280
|
+
const row = getSeqRow(feature.strand, lgv.bpPerPx)
|
|
260
281
|
const offset =
|
|
261
282
|
(lgv.bpToPx({
|
|
262
283
|
refName: region.refName,
|
|
263
|
-
coord: feature.
|
|
284
|
+
coord: feature.min,
|
|
264
285
|
regionNumber: idx,
|
|
265
286
|
})?.offsetPx ?? 0) - lgv.offsetPx
|
|
266
287
|
const widthPx = feature.length / lgv.bpPerPx
|
|
267
|
-
const startPx = displayedRegions[idx].reversed
|
|
288
|
+
const startPx = lgv.displayedRegions[idx].reversed
|
|
268
289
|
? offset - widthPx
|
|
269
290
|
: offset
|
|
270
291
|
|
|
@@ -297,118 +318,130 @@ export function mouseEventsModelFactory(
|
|
|
297
318
|
|
|
298
319
|
return LinearApolloDisplayMouseEvents.views((self) => ({
|
|
299
320
|
contextMenuItems(contextCoord?: Coord): MenuItem[] {
|
|
300
|
-
const { apolloHover
|
|
301
|
-
|
|
302
|
-
if (!(topLevelFeature && contextCoord)) {
|
|
321
|
+
const { apolloHover } = self
|
|
322
|
+
if (!(apolloHover && contextCoord)) {
|
|
303
323
|
return []
|
|
304
324
|
}
|
|
305
|
-
const
|
|
325
|
+
const { topLevelFeature } = apolloHover
|
|
326
|
+
const glyph = getGlyph(topLevelFeature)
|
|
306
327
|
return glyph.getContextMenuItems(self)
|
|
307
328
|
},
|
|
308
329
|
}))
|
|
309
330
|
.actions((self) => ({
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
mousePosition.bp <= feature.discontinuousLocations[i].end
|
|
323
|
-
) {
|
|
324
|
-
idx = i
|
|
325
|
-
dl = feature.discontinuousLocations[idx]
|
|
326
|
-
break
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
self.apolloDragging = {
|
|
331
|
-
start: {
|
|
332
|
-
glyph,
|
|
333
|
-
feature,
|
|
334
|
-
topLevelFeature,
|
|
335
|
-
discontinuousLocation: dl
|
|
336
|
-
? {
|
|
337
|
-
start: dl.start,
|
|
338
|
-
end: dl.end,
|
|
339
|
-
phase: dl.phase,
|
|
340
|
-
idx,
|
|
341
|
-
}
|
|
342
|
-
: undefined,
|
|
343
|
-
mousePosition,
|
|
344
|
-
},
|
|
345
|
-
current: { glyph, feature, topLevelFeature, mousePosition },
|
|
346
|
-
}
|
|
347
|
-
if (!glyph.startDrag(self, event)) {
|
|
348
|
-
self.apolloDragging = null
|
|
349
|
-
}
|
|
331
|
+
// explicitly pass in a feature in case it's not the same as the one in
|
|
332
|
+
// mousePosition (e.g. if features are drawn overlapping).
|
|
333
|
+
startDrag(
|
|
334
|
+
mousePosition: MousePositionWithFeatureAndGlyph,
|
|
335
|
+
feature: AnnotationFeature,
|
|
336
|
+
edge: 'min' | 'max',
|
|
337
|
+
) {
|
|
338
|
+
self.apolloDragging = {
|
|
339
|
+
start: mousePosition,
|
|
340
|
+
current: mousePosition,
|
|
341
|
+
feature,
|
|
342
|
+
edge,
|
|
350
343
|
}
|
|
351
344
|
},
|
|
352
|
-
endDrag(
|
|
353
|
-
self.
|
|
354
|
-
|
|
345
|
+
endDrag() {
|
|
346
|
+
if (!self.apolloDragging) {
|
|
347
|
+
throw new Error('endDrag() called with no current drag in progress')
|
|
348
|
+
}
|
|
349
|
+
const { current, edge, feature, start } = self.apolloDragging
|
|
350
|
+
// don't do anything if it was only dragged a tiny bit
|
|
351
|
+
if (Math.abs(current.x - start.x) <= 4) {
|
|
352
|
+
self.setDragging()
|
|
353
|
+
self.setCursor()
|
|
354
|
+
return
|
|
355
|
+
}
|
|
356
|
+
const { displayedRegions } = self.lgv
|
|
357
|
+
const region = displayedRegions[start.regionNumber]
|
|
358
|
+
const assembly = self.getAssemblyId(region.assemblyName)
|
|
359
|
+
|
|
360
|
+
let change: LocationEndChange | LocationStartChange
|
|
361
|
+
if (edge === 'max') {
|
|
362
|
+
const featureId = feature._id
|
|
363
|
+
const oldEnd = feature.max
|
|
364
|
+
const newEnd = current.bp
|
|
365
|
+
change = new LocationEndChange({
|
|
366
|
+
typeName: 'LocationEndChange',
|
|
367
|
+
changedIds: [featureId],
|
|
368
|
+
featureId,
|
|
369
|
+
oldEnd,
|
|
370
|
+
newEnd,
|
|
371
|
+
assembly,
|
|
372
|
+
})
|
|
373
|
+
} else {
|
|
374
|
+
const featureId = feature._id
|
|
375
|
+
const oldStart = feature.min
|
|
376
|
+
const newStart = current.bp
|
|
377
|
+
change = new LocationStartChange({
|
|
378
|
+
typeName: 'LocationStartChange',
|
|
379
|
+
changedIds: [featureId],
|
|
380
|
+
featureId,
|
|
381
|
+
oldStart,
|
|
382
|
+
newStart,
|
|
383
|
+
assembly,
|
|
384
|
+
})
|
|
385
|
+
}
|
|
386
|
+
void self.changeManager.submit(change)
|
|
355
387
|
self.setDragging()
|
|
388
|
+
self.setCursor()
|
|
356
389
|
},
|
|
357
390
|
}))
|
|
358
391
|
.actions((self) => ({
|
|
359
392
|
onMouseDown(event: CanvasMouseEvent) {
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
393
|
+
const mousePosition = self.getMousePosition(event)
|
|
394
|
+
if (isMousePositionWithFeatureAndGlyph(mousePosition)) {
|
|
395
|
+
mousePosition.featureAndGlyphUnderMouse.glyph.onMouseDown(
|
|
396
|
+
self,
|
|
397
|
+
mousePosition,
|
|
398
|
+
event,
|
|
399
|
+
)
|
|
364
400
|
}
|
|
365
401
|
},
|
|
366
402
|
onMouseMove(event: CanvasMouseEvent) {
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
403
|
+
const mousePosition = self.getMousePosition(event)
|
|
404
|
+
if (self.apolloDragging) {
|
|
405
|
+
self.setCursor('col-resize')
|
|
406
|
+
self.continueDrag(mousePosition, event)
|
|
407
|
+
return
|
|
372
408
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
self.continueDrag(event)
|
|
380
|
-
} else {
|
|
381
|
-
// start drag if not already dragging
|
|
382
|
-
self.startDrag(event)
|
|
383
|
-
}
|
|
384
|
-
}
|
|
409
|
+
if (isMousePositionWithFeatureAndGlyph(mousePosition)) {
|
|
410
|
+
mousePosition.featureAndGlyphUnderMouse.glyph.onMouseMove(
|
|
411
|
+
self,
|
|
412
|
+
mousePosition,
|
|
413
|
+
event,
|
|
414
|
+
)
|
|
385
415
|
} else {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if (feature && glyph && topLevelFeature) {
|
|
389
|
-
self.setApolloHover(hover)
|
|
390
|
-
} else {
|
|
391
|
-
self.setApolloHover(null)
|
|
392
|
-
self.setCursor()
|
|
393
|
-
}
|
|
416
|
+
self.setApolloHover()
|
|
417
|
+
self.setCursor()
|
|
394
418
|
}
|
|
395
419
|
},
|
|
396
420
|
onMouseLeave(event: CanvasMouseEvent) {
|
|
397
421
|
self.setDragging()
|
|
422
|
+
self.setApolloHover()
|
|
398
423
|
|
|
399
|
-
const
|
|
400
|
-
if (
|
|
401
|
-
glyph.onMouseLeave(
|
|
424
|
+
const mousePosition = self.getMousePosition(event)
|
|
425
|
+
if (isMousePositionWithFeatureAndGlyph(mousePosition)) {
|
|
426
|
+
mousePosition.featureAndGlyphUnderMouse.glyph.onMouseLeave(
|
|
427
|
+
self,
|
|
428
|
+
mousePosition,
|
|
429
|
+
event,
|
|
430
|
+
)
|
|
402
431
|
}
|
|
403
432
|
},
|
|
404
433
|
onMouseUp(event: CanvasMouseEvent) {
|
|
405
|
-
const
|
|
406
|
-
if (
|
|
407
|
-
glyph.onMouseUp(
|
|
434
|
+
const mousePosition = self.getMousePosition(event)
|
|
435
|
+
if (isMousePositionWithFeatureAndGlyph(mousePosition)) {
|
|
436
|
+
mousePosition.featureAndGlyphUnderMouse.glyph.onMouseUp(
|
|
437
|
+
self,
|
|
438
|
+
mousePosition,
|
|
439
|
+
event,
|
|
440
|
+
)
|
|
408
441
|
}
|
|
409
442
|
|
|
410
443
|
if (self.apolloDragging) {
|
|
411
|
-
self.endDrag(
|
|
444
|
+
self.endDrag()
|
|
412
445
|
}
|
|
413
446
|
},
|
|
414
447
|
}))
|
|
@@ -418,6 +451,8 @@ export function mouseEventsModelFactory(
|
|
|
418
451
|
self,
|
|
419
452
|
autorun(
|
|
420
453
|
() => {
|
|
454
|
+
// This type is wrong in @jbrowse/core
|
|
455
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
421
456
|
if (!self.lgv.initialized || self.regionCannotBeRendered()) {
|
|
422
457
|
return
|
|
423
458
|
}
|
|
@@ -432,73 +467,24 @@ export function mouseEventsModelFactory(
|
|
|
432
467
|
self.featuresHeight,
|
|
433
468
|
)
|
|
434
469
|
|
|
435
|
-
const {
|
|
436
|
-
apolloDragging,
|
|
437
|
-
apolloHover,
|
|
438
|
-
displayedRegions,
|
|
439
|
-
featureLayouts,
|
|
440
|
-
lgv,
|
|
441
|
-
} = self
|
|
470
|
+
const { apolloDragging, apolloHover } = self
|
|
442
471
|
if (!apolloHover) {
|
|
443
472
|
return
|
|
444
473
|
}
|
|
445
|
-
const {
|
|
446
|
-
if (!feature) {
|
|
447
|
-
return
|
|
448
|
-
}
|
|
449
|
-
let rowNum = 0
|
|
450
|
-
let xOffset = 0
|
|
451
|
-
let reversed = false
|
|
452
|
-
for (const [idx, featureLayout] of featureLayouts.entries()) {
|
|
453
|
-
const displayedRegion = displayedRegions[idx]
|
|
454
|
-
for (const [row, featureLayoutRow] of featureLayout.entries()) {
|
|
455
|
-
if (rowNum !== 0) {
|
|
456
|
-
continue
|
|
457
|
-
}
|
|
458
|
-
for (const [, f] of featureLayoutRow) {
|
|
459
|
-
for (const [, cf] of f.children ?? new Map()) {
|
|
460
|
-
if (rowNum !== 0) {
|
|
461
|
-
continue
|
|
462
|
-
}
|
|
463
|
-
xOffset =
|
|
464
|
-
(lgv.bpToPx({
|
|
465
|
-
refName: displayedRegion.refName,
|
|
466
|
-
coord: feature.min,
|
|
467
|
-
regionNumber: idx,
|
|
468
|
-
})?.offsetPx ?? 0) - lgv.offsetPx
|
|
469
|
-
;({ reversed } = displayedRegion)
|
|
470
|
-
|
|
471
|
-
if (cf._id === feature._id) {
|
|
472
|
-
rowNum = row
|
|
473
|
-
continue
|
|
474
|
-
}
|
|
475
|
-
for (const [, annotationFeature] of cf.children ??
|
|
476
|
-
new Map()) {
|
|
477
|
-
if (rowNum !== 0) {
|
|
478
|
-
continue
|
|
479
|
-
}
|
|
480
|
-
if (annotationFeature._id === feature._id) {
|
|
481
|
-
rowNum = row
|
|
482
|
-
continue
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
}
|
|
474
|
+
const { glyph } = apolloHover
|
|
489
475
|
|
|
490
476
|
// draw mouseover hovers
|
|
491
|
-
glyph
|
|
477
|
+
glyph.drawHover(self, ctx)
|
|
492
478
|
|
|
493
479
|
// draw tooltip on hover
|
|
494
|
-
glyph
|
|
480
|
+
glyph.drawTooltip(self, ctx)
|
|
495
481
|
|
|
496
482
|
// dragging previews
|
|
497
483
|
if (apolloDragging) {
|
|
498
484
|
// NOTE: the glyph where the drag started is responsible for drawing the preview.
|
|
499
485
|
// it can call methods in other glyphs to help with this though.
|
|
500
|
-
|
|
501
|
-
|
|
486
|
+
const glyph = getGlyph(apolloDragging.feature.topLevelFeature)
|
|
487
|
+
glyph.drawDragPreview(self, ctx)
|
|
502
488
|
}
|
|
503
489
|
},
|
|
504
490
|
{ name: 'LinearApolloDisplayRenderMouseoverAndDrag' },
|
|
@@ -511,5 +497,8 @@ export function mouseEventsModelFactory(
|
|
|
511
497
|
export type LinearApolloDisplayMouseEventsModel = ReturnType<
|
|
512
498
|
typeof mouseEventsModelIntermediateFactory
|
|
513
499
|
>
|
|
514
|
-
|
|
515
|
-
|
|
500
|
+
// eslint disable because of
|
|
501
|
+
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
502
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
503
|
+
export interface LinearApolloDisplayMouseEvents
|
|
504
|
+
extends Instance<LinearApolloDisplayMouseEventsModel> {}
|