@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
|
@@ -6,110 +6,22 @@ import {
|
|
|
6
6
|
import type PluginManager from '@jbrowse/core/PluginManager'
|
|
7
7
|
import { type AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
|
|
8
8
|
import { type MenuItem } from '@jbrowse/core/ui'
|
|
9
|
-
import { type Frame, getFrame } from '@jbrowse/core/util'
|
|
10
|
-
import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
11
|
-
import { type Theme } from '@mui/material'
|
|
12
9
|
import { autorun } from 'mobx'
|
|
13
10
|
import { type Instance, addDisposer } from 'mobx-state-tree'
|
|
14
11
|
import { type CSSProperties } from 'react'
|
|
15
12
|
|
|
16
|
-
import {
|
|
17
|
-
|
|
13
|
+
import {
|
|
14
|
+
type Edge,
|
|
15
|
+
type MousePosition,
|
|
16
|
+
type MousePositionWithFeature,
|
|
17
|
+
getMousePosition,
|
|
18
|
+
getPropagatedLocationChanges,
|
|
19
|
+
isMousePositionWithFeature,
|
|
20
|
+
} from '../../util'
|
|
18
21
|
import { type CanvasMouseEvent } from '../types'
|
|
19
22
|
|
|
20
23
|
import { renderingModelFactory } from './rendering'
|
|
21
24
|
|
|
22
|
-
export interface FeatureAndGlyphUnderMouse {
|
|
23
|
-
feature: AnnotationFeature
|
|
24
|
-
topLevelFeature: AnnotationFeature
|
|
25
|
-
glyph: Glyph
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** extended information about the position of the mouse on the canvas, including the refName, bp, and displayedRegion number */
|
|
29
|
-
export interface MousePosition {
|
|
30
|
-
x: number
|
|
31
|
-
y: number
|
|
32
|
-
refName: string
|
|
33
|
-
bp: number
|
|
34
|
-
regionNumber: number
|
|
35
|
-
featureAndGlyphUnderMouse?: FeatureAndGlyphUnderMouse
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export type MousePositionWithFeatureAndGlyph = Required<MousePosition>
|
|
39
|
-
|
|
40
|
-
export function isMousePositionWithFeatureAndGlyph(
|
|
41
|
-
mousePosition: MousePosition,
|
|
42
|
-
): mousePosition is MousePositionWithFeatureAndGlyph {
|
|
43
|
-
return 'featureAndGlyphUnderMouse' in mousePosition
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function getMousePosition(
|
|
47
|
-
event: CanvasMouseEvent,
|
|
48
|
-
lgv: LinearGenomeViewModel,
|
|
49
|
-
): MousePosition {
|
|
50
|
-
const canvas = event.currentTarget
|
|
51
|
-
const { clientX, clientY } = event
|
|
52
|
-
const { left, top } = canvas.getBoundingClientRect()
|
|
53
|
-
const x = clientX - left
|
|
54
|
-
const y = clientY - top
|
|
55
|
-
const { coord: bp, index: regionNumber, refName } = lgv.pxToBp(x)
|
|
56
|
-
return { x, y, refName, bp, regionNumber }
|
|
57
|
-
}
|
|
58
|
-
|
|
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
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function getSeqRow(
|
|
84
|
-
strand: 1 | -1 | undefined,
|
|
85
|
-
bpPerPx: number,
|
|
86
|
-
): number | undefined {
|
|
87
|
-
if (bpPerPx > 1 || strand === undefined) {
|
|
88
|
-
return
|
|
89
|
-
}
|
|
90
|
-
return strand === 1 ? 3 : 4
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function highlightSeq(
|
|
94
|
-
seqTrackOverlayctx: CanvasRenderingContext2D,
|
|
95
|
-
theme: Theme | undefined,
|
|
96
|
-
startPx: number,
|
|
97
|
-
sequenceRowHeight: number,
|
|
98
|
-
row: number | undefined,
|
|
99
|
-
widthPx: number,
|
|
100
|
-
) {
|
|
101
|
-
if (row !== undefined) {
|
|
102
|
-
seqTrackOverlayctx.fillStyle =
|
|
103
|
-
theme?.palette.action.focus ?? 'rgba(0,0,0,0.04)'
|
|
104
|
-
seqTrackOverlayctx.fillRect(
|
|
105
|
-
startPx,
|
|
106
|
-
sequenceRowHeight * row,
|
|
107
|
-
widthPx,
|
|
108
|
-
sequenceRowHeight,
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
25
|
export function mouseEventsModelIntermediateFactory(
|
|
114
26
|
pluginManager: PluginManager,
|
|
115
27
|
configSchema: AnyConfigurationSchemaType,
|
|
@@ -125,13 +37,13 @@ export function mouseEventsModelIntermediateFactory(
|
|
|
125
37
|
start: MousePosition
|
|
126
38
|
current: MousePosition
|
|
127
39
|
feature: AnnotationFeature
|
|
128
|
-
edge:
|
|
40
|
+
edge: Edge
|
|
41
|
+
shrinkParent: boolean
|
|
129
42
|
} | null,
|
|
130
43
|
cursor: undefined as CSSProperties['cursor'] | undefined,
|
|
131
|
-
apolloHover: undefined as FeatureAndGlyphUnderMouse | undefined,
|
|
132
44
|
}))
|
|
133
45
|
.views((self) => ({
|
|
134
|
-
getMousePosition(event:
|
|
46
|
+
getMousePosition(event: React.MouseEvent): MousePosition {
|
|
135
47
|
const mousePosition = getMousePosition(event, self.lgv)
|
|
136
48
|
const { bp, regionNumber, y } = mousePosition
|
|
137
49
|
const row = Math.floor(y / self.apolloRowHeight)
|
|
@@ -169,7 +81,7 @@ export function mouseEventsModelIntermediateFactory(
|
|
|
169
81
|
}
|
|
170
82
|
return {
|
|
171
83
|
...mousePosition,
|
|
172
|
-
|
|
84
|
+
feature,
|
|
173
85
|
}
|
|
174
86
|
},
|
|
175
87
|
}))
|
|
@@ -188,14 +100,15 @@ export function mouseEventsModelIntermediateFactory(
|
|
|
188
100
|
},
|
|
189
101
|
}))
|
|
190
102
|
.actions((self) => ({
|
|
191
|
-
setApolloHover(n?: (typeof self)['apolloHover']) {
|
|
192
|
-
self.apolloHover = n
|
|
193
|
-
},
|
|
194
103
|
setCursor(cursor?: CSSProperties['cursor']) {
|
|
195
104
|
if (self.cursor !== cursor) {
|
|
196
105
|
self.cursor = cursor
|
|
197
106
|
}
|
|
198
107
|
},
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
109
|
+
updateFilteredTranscripts(forms: string[]) {
|
|
110
|
+
return
|
|
111
|
+
},
|
|
199
112
|
}))
|
|
200
113
|
.actions(() => ({
|
|
201
114
|
// onClick(event: CanvasMouseEvent) {
|
|
@@ -205,171 +118,53 @@ export function mouseEventsModelIntermediateFactory(
|
|
|
205
118
|
}))
|
|
206
119
|
}
|
|
207
120
|
|
|
208
|
-
export function mouseEventsSeqHightlightModelFactory(
|
|
209
|
-
pluginManager: PluginManager,
|
|
210
|
-
configSchema: AnyConfigurationSchemaType,
|
|
211
|
-
) {
|
|
212
|
-
const LinearApolloDisplayRendering = mouseEventsModelIntermediateFactory(
|
|
213
|
-
pluginManager,
|
|
214
|
-
configSchema,
|
|
215
|
-
)
|
|
216
|
-
|
|
217
|
-
return LinearApolloDisplayRendering.actions((self) => ({
|
|
218
|
-
afterAttach() {
|
|
219
|
-
addDisposer(
|
|
220
|
-
self,
|
|
221
|
-
autorun(
|
|
222
|
-
() => {
|
|
223
|
-
// This type is wrong in @jbrowse/core
|
|
224
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
225
|
-
if (!self.lgv.initialized || self.regionCannotBeRendered()) {
|
|
226
|
-
return
|
|
227
|
-
}
|
|
228
|
-
const seqTrackOverlayctx =
|
|
229
|
-
self.seqTrackOverlayCanvas?.getContext('2d')
|
|
230
|
-
if (!seqTrackOverlayctx) {
|
|
231
|
-
return
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
seqTrackOverlayctx.clearRect(
|
|
235
|
-
0,
|
|
236
|
-
0,
|
|
237
|
-
self.lgv.dynamicBlocks.totalWidthPx,
|
|
238
|
-
self.lgv.bpPerPx <= 1 ? 125 : 95,
|
|
239
|
-
)
|
|
240
|
-
|
|
241
|
-
const {
|
|
242
|
-
apolloHover,
|
|
243
|
-
lgv,
|
|
244
|
-
regions,
|
|
245
|
-
sequenceRowHeight,
|
|
246
|
-
session,
|
|
247
|
-
theme,
|
|
248
|
-
} = self
|
|
249
|
-
|
|
250
|
-
if (!apolloHover) {
|
|
251
|
-
return
|
|
252
|
-
}
|
|
253
|
-
const { feature } = apolloHover
|
|
254
|
-
|
|
255
|
-
const { featureTypeOntology } =
|
|
256
|
-
session.apolloDataStore.ontologyManager
|
|
257
|
-
if (!featureTypeOntology) {
|
|
258
|
-
throw new Error('featureTypeOntology is undefined')
|
|
259
|
-
}
|
|
260
|
-
for (const [idx, region] of regions.entries()) {
|
|
261
|
-
if (featureTypeOntology.isTypeOf(feature.type, 'CDS')) {
|
|
262
|
-
const parentFeature = feature.parent
|
|
263
|
-
if (!parentFeature) {
|
|
264
|
-
continue
|
|
265
|
-
}
|
|
266
|
-
const cdsLocs = parentFeature.cdsLocations.find(
|
|
267
|
-
(loc) =>
|
|
268
|
-
feature.min === loc.at(0)?.min &&
|
|
269
|
-
feature.max === loc.at(-1)?.max,
|
|
270
|
-
)
|
|
271
|
-
if (!cdsLocs) {
|
|
272
|
-
continue
|
|
273
|
-
}
|
|
274
|
-
for (const dl of cdsLocs) {
|
|
275
|
-
const frame = getFrame(
|
|
276
|
-
dl.min,
|
|
277
|
-
dl.max,
|
|
278
|
-
feature.strand ?? 1,
|
|
279
|
-
dl.phase,
|
|
280
|
-
)
|
|
281
|
-
const row = getTranslationRow(frame, lgv.bpPerPx)
|
|
282
|
-
const offset =
|
|
283
|
-
(lgv.bpToPx({
|
|
284
|
-
refName: region.refName,
|
|
285
|
-
coord: dl.min,
|
|
286
|
-
regionNumber: idx,
|
|
287
|
-
})?.offsetPx ?? 0) - lgv.offsetPx
|
|
288
|
-
const widthPx = (dl.max - dl.min) / lgv.bpPerPx
|
|
289
|
-
const startPx = lgv.displayedRegions[idx].reversed
|
|
290
|
-
? offset - widthPx
|
|
291
|
-
: offset
|
|
292
|
-
|
|
293
|
-
highlightSeq(
|
|
294
|
-
seqTrackOverlayctx,
|
|
295
|
-
theme,
|
|
296
|
-
startPx,
|
|
297
|
-
sequenceRowHeight,
|
|
298
|
-
row,
|
|
299
|
-
widthPx,
|
|
300
|
-
)
|
|
301
|
-
}
|
|
302
|
-
} else {
|
|
303
|
-
const row = getSeqRow(feature.strand, lgv.bpPerPx)
|
|
304
|
-
const offset =
|
|
305
|
-
(lgv.bpToPx({
|
|
306
|
-
refName: region.refName,
|
|
307
|
-
coord: feature.min,
|
|
308
|
-
regionNumber: idx,
|
|
309
|
-
})?.offsetPx ?? 0) - lgv.offsetPx
|
|
310
|
-
const widthPx = feature.length / lgv.bpPerPx
|
|
311
|
-
const startPx = lgv.displayedRegions[idx].reversed
|
|
312
|
-
? offset - widthPx
|
|
313
|
-
: offset
|
|
314
|
-
|
|
315
|
-
highlightSeq(
|
|
316
|
-
seqTrackOverlayctx,
|
|
317
|
-
theme,
|
|
318
|
-
startPx,
|
|
319
|
-
sequenceRowHeight,
|
|
320
|
-
row,
|
|
321
|
-
widthPx,
|
|
322
|
-
)
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
},
|
|
326
|
-
{ name: 'LinearApolloDisplayRenderSeqHighlight' },
|
|
327
|
-
),
|
|
328
|
-
)
|
|
329
|
-
},
|
|
330
|
-
}))
|
|
331
|
-
}
|
|
332
|
-
|
|
333
121
|
export function mouseEventsModelFactory(
|
|
334
122
|
pluginManager: PluginManager,
|
|
335
123
|
configSchema: AnyConfigurationSchemaType,
|
|
336
124
|
) {
|
|
337
|
-
const LinearApolloDisplayMouseEvents =
|
|
125
|
+
const LinearApolloDisplayMouseEvents = mouseEventsModelIntermediateFactory(
|
|
338
126
|
pluginManager,
|
|
339
127
|
configSchema,
|
|
340
128
|
)
|
|
341
129
|
|
|
342
130
|
return LinearApolloDisplayMouseEvents.views((self) => ({
|
|
343
|
-
contextMenuItems(
|
|
344
|
-
const {
|
|
345
|
-
if (!
|
|
131
|
+
contextMenuItems(event: React.MouseEvent<HTMLDivElement>): MenuItem[] {
|
|
132
|
+
const { hoveredFeature } = self
|
|
133
|
+
if (!hoveredFeature) {
|
|
346
134
|
return []
|
|
347
135
|
}
|
|
348
|
-
const
|
|
136
|
+
const mousePosition = self.getMousePosition(event)
|
|
137
|
+
const { topLevelFeature } = hoveredFeature.feature
|
|
349
138
|
const glyph = self.getGlyph(topLevelFeature)
|
|
350
|
-
|
|
139
|
+
if (isMousePositionWithFeature(mousePosition)) {
|
|
140
|
+
return glyph.getContextMenuItems(self, mousePosition)
|
|
141
|
+
}
|
|
142
|
+
return []
|
|
351
143
|
},
|
|
352
144
|
}))
|
|
353
145
|
.actions((self) => ({
|
|
354
146
|
// explicitly pass in a feature in case it's not the same as the one in
|
|
355
147
|
// mousePosition (e.g. if features are drawn overlapping).
|
|
356
148
|
startDrag(
|
|
357
|
-
mousePosition:
|
|
149
|
+
mousePosition: MousePositionWithFeature,
|
|
358
150
|
feature: AnnotationFeature,
|
|
359
|
-
edge:
|
|
151
|
+
edge: Edge,
|
|
152
|
+
shrinkParent = false,
|
|
360
153
|
) {
|
|
361
154
|
self.apolloDragging = {
|
|
362
155
|
start: mousePosition,
|
|
363
156
|
current: mousePosition,
|
|
364
157
|
feature,
|
|
365
158
|
edge,
|
|
159
|
+
shrinkParent,
|
|
366
160
|
}
|
|
367
161
|
},
|
|
368
162
|
endDrag() {
|
|
369
163
|
if (!self.apolloDragging) {
|
|
370
164
|
throw new Error('endDrag() called with no current drag in progress')
|
|
371
165
|
}
|
|
372
|
-
const { current, edge, feature, start } =
|
|
166
|
+
const { current, edge, feature, start, shrinkParent } =
|
|
167
|
+
self.apolloDragging
|
|
373
168
|
// don't do anything if it was only dragged a tiny bit
|
|
374
169
|
if (Math.abs(current.x - start.x) <= 4) {
|
|
375
170
|
self.setDragging()
|
|
@@ -379,33 +174,35 @@ export function mouseEventsModelFactory(
|
|
|
379
174
|
const { displayedRegions } = self.lgv
|
|
380
175
|
const region = displayedRegions[start.regionNumber]
|
|
381
176
|
const assembly = self.getAssemblyId(region.assemblyName)
|
|
177
|
+
const changes = getPropagatedLocationChanges(
|
|
178
|
+
feature,
|
|
179
|
+
current.bp,
|
|
180
|
+
edge,
|
|
181
|
+
shrinkParent,
|
|
182
|
+
)
|
|
382
183
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
newStart,
|
|
406
|
-
assembly,
|
|
407
|
-
})
|
|
408
|
-
}
|
|
184
|
+
const change: LocationEndChange | LocationStartChange =
|
|
185
|
+
edge === 'max'
|
|
186
|
+
? new LocationEndChange({
|
|
187
|
+
typeName: 'LocationEndChange',
|
|
188
|
+
changedIds: changes.map((c) => c.featureId),
|
|
189
|
+
changes: changes.map((c) => ({
|
|
190
|
+
featureId: c.featureId,
|
|
191
|
+
oldEnd: c.oldLocation,
|
|
192
|
+
newEnd: c.newLocation,
|
|
193
|
+
})),
|
|
194
|
+
assembly,
|
|
195
|
+
})
|
|
196
|
+
: new LocationStartChange({
|
|
197
|
+
typeName: 'LocationStartChange',
|
|
198
|
+
changedIds: changes.map((c) => c.featureId),
|
|
199
|
+
changes: changes.map((c) => ({
|
|
200
|
+
featureId: c.featureId,
|
|
201
|
+
oldStart: c.oldLocation,
|
|
202
|
+
newStart: c.newLocation,
|
|
203
|
+
})),
|
|
204
|
+
assembly,
|
|
205
|
+
})
|
|
409
206
|
void self.changeManager.submit(change)
|
|
410
207
|
self.setDragging()
|
|
411
208
|
self.setCursor()
|
|
@@ -414,12 +211,9 @@ export function mouseEventsModelFactory(
|
|
|
414
211
|
.actions((self) => ({
|
|
415
212
|
onMouseDown(event: CanvasMouseEvent) {
|
|
416
213
|
const mousePosition = self.getMousePosition(event)
|
|
417
|
-
if (
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
mousePosition,
|
|
421
|
-
event,
|
|
422
|
-
)
|
|
214
|
+
if (isMousePositionWithFeature(mousePosition)) {
|
|
215
|
+
const glyph = self.getGlyph(mousePosition.feature)
|
|
216
|
+
glyph.onMouseDown(self, mousePosition, event)
|
|
423
217
|
}
|
|
424
218
|
},
|
|
425
219
|
onMouseMove(event: CanvasMouseEvent) {
|
|
@@ -429,38 +223,31 @@ export function mouseEventsModelFactory(
|
|
|
429
223
|
self.continueDrag(mousePosition, event)
|
|
430
224
|
return
|
|
431
225
|
}
|
|
432
|
-
if (
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
mousePosition,
|
|
436
|
-
event,
|
|
437
|
-
)
|
|
226
|
+
if (isMousePositionWithFeature(mousePosition)) {
|
|
227
|
+
const glyph = self.getGlyph(mousePosition.feature)
|
|
228
|
+
glyph.onMouseMove(self, mousePosition, event)
|
|
438
229
|
} else {
|
|
439
|
-
self.
|
|
230
|
+
self.setHoveredFeature()
|
|
440
231
|
self.setCursor()
|
|
441
232
|
}
|
|
442
233
|
},
|
|
443
234
|
onMouseLeave(event: CanvasMouseEvent) {
|
|
444
235
|
self.setDragging()
|
|
445
|
-
self.
|
|
236
|
+
self.setHoveredFeature()
|
|
446
237
|
|
|
447
238
|
const mousePosition = self.getMousePosition(event)
|
|
448
|
-
if (
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
mousePosition,
|
|
452
|
-
event,
|
|
453
|
-
)
|
|
239
|
+
if (isMousePositionWithFeature(mousePosition)) {
|
|
240
|
+
const glyph = self.getGlyph(mousePosition.feature)
|
|
241
|
+
glyph.onMouseLeave(self, mousePosition, event)
|
|
454
242
|
}
|
|
455
243
|
},
|
|
456
244
|
onMouseUp(event: CanvasMouseEvent) {
|
|
457
245
|
const mousePosition = self.getMousePosition(event)
|
|
458
|
-
if (
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
)
|
|
246
|
+
if (isMousePositionWithFeature(mousePosition)) {
|
|
247
|
+
const glyph = self.getGlyph(mousePosition.feature)
|
|
248
|
+
glyph.onMouseUp(self, mousePosition, event)
|
|
249
|
+
} else {
|
|
250
|
+
self.setSelectedFeature()
|
|
464
251
|
}
|
|
465
252
|
|
|
466
253
|
if (self.apolloDragging) {
|
|
@@ -490,11 +277,11 @@ export function mouseEventsModelFactory(
|
|
|
490
277
|
self.featuresHeight,
|
|
491
278
|
)
|
|
492
279
|
|
|
493
|
-
const { apolloDragging,
|
|
494
|
-
if (!
|
|
280
|
+
const { apolloDragging, hoveredFeature } = self
|
|
281
|
+
if (!hoveredFeature) {
|
|
495
282
|
return
|
|
496
283
|
}
|
|
497
|
-
const
|
|
284
|
+
const glyph = self.getGlyph(hoveredFeature.feature)
|
|
498
285
|
|
|
499
286
|
// draw mouseover hovers
|
|
500
287
|
glyph.drawHover(self, ctx)
|