@apollo-annotation/jbrowse-plugin-apollo 0.3.7 → 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 +2371 -1642
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +2384 -1641
- 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 +4387 -2952
- 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 +33 -13
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +64 -5
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +70 -73
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +33 -31
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +60 -72
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +50 -194
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +441 -180
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +53 -34
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +7 -9
- package/src/LinearApolloDisplay/stateModel/base.ts +34 -43
- package/src/LinearApolloDisplay/stateModel/layouts.ts +3 -2
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +32 -261
- package/src/LinearApolloDisplay/stateModel/rendering.ts +43 -343
- 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 +95 -38
- package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +221 -201
- package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +12 -8
- package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +42 -4
- package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +4 -8
- package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +73 -97
- package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +49 -61
- package/src/TabularEditor/HybridGrid/Feature.tsx +16 -14
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +7 -5
- package/src/components/AddAssembly.tsx +1 -1
- package/src/components/AddAssemblyAliases.tsx +1 -1
- package/src/components/AddChildFeature.tsx +5 -2
- package/src/components/AddFeature.tsx +9 -3
- package/src/components/AddRefSeqAliases.tsx +9 -9
- package/src/components/CopyFeature.tsx +3 -1
- package/src/components/CreateApolloAnnotation.tsx +1 -0
- package/src/components/DeleteAssembly.tsx +1 -1
- package/src/components/EditZoomThresholdDialog.tsx +69 -0
- package/src/components/FilterFeatures.tsx +7 -7
- package/src/components/FilterTranscripts.tsx +6 -6
- package/src/components/ImportFeatures.tsx +1 -1
- package/src/components/ManageChecks.tsx +1 -1
- package/src/components/MergeTranscripts.tsx +12 -15
- package/src/components/OntologyTermMultiSelect.tsx +11 -11
- package/src/components/OpenLocalFile.tsx +11 -7
- package/src/components/ViewCheckResults.tsx +1 -1
- package/src/components/index.ts +1 -0
- package/src/config.ts +6 -0
- 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} +56 -47
- package/src/menus/topLevelMenuAdmin.ts +154 -0
- package/src/session/session.ts +162 -116
- package/src/util/annotationFeatureUtils.ts +15 -21
- package/src/util/displayUtils.ts +149 -0
- package/src/util/glyphUtils.ts +152 -0
- package/src/util/mouseEventsUtils.ts +32 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
2
2
|
import type PluginManager from '@jbrowse/core/PluginManager'
|
|
3
3
|
import { type AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
|
|
4
|
-
import {
|
|
5
|
-
import { type Theme } from '@mui/material'
|
|
4
|
+
import { doesIntersect2 } from '@jbrowse/core/util'
|
|
5
|
+
import { type Theme, createTheme } from '@mui/material'
|
|
6
6
|
import { autorun } from 'mobx'
|
|
7
7
|
import { type Instance, addDisposer, types } from 'mobx-state-tree'
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ import { type ApolloSessionModel } from '../../session'
|
|
|
10
10
|
|
|
11
11
|
import { layoutsModelFactory } from './layouts'
|
|
12
12
|
|
|
13
|
-
export function
|
|
13
|
+
export function renderingModelFactory(
|
|
14
14
|
pluginManager: PluginManager,
|
|
15
15
|
configSchema: AnyConfigurationSchemaType,
|
|
16
16
|
) {
|
|
@@ -21,7 +21,6 @@ export function renderingModelIntermediateFactory(
|
|
|
21
21
|
|
|
22
22
|
return LinearApolloDisplayLayouts.named('LinearApolloDisplayRendering')
|
|
23
23
|
.props({
|
|
24
|
-
sequenceRowHeight: 15,
|
|
25
24
|
apolloRowHeight: 20,
|
|
26
25
|
detailsMinHeight: 200,
|
|
27
26
|
detailsHeight: 200,
|
|
@@ -33,9 +32,7 @@ export function renderingModelIntermediateFactory(
|
|
|
33
32
|
canvas: null as HTMLCanvasElement | null,
|
|
34
33
|
overlayCanvas: null as HTMLCanvasElement | null,
|
|
35
34
|
collaboratorCanvas: null as HTMLCanvasElement | null,
|
|
36
|
-
|
|
37
|
-
seqTrackOverlayCanvas: null as HTMLCanvasElement | null,
|
|
38
|
-
theme: undefined as Theme | undefined,
|
|
35
|
+
theme: createTheme(),
|
|
39
36
|
}))
|
|
40
37
|
.views((self) => ({
|
|
41
38
|
get featuresHeight() {
|
|
@@ -66,15 +63,11 @@ export function renderingModelIntermediateFactory(
|
|
|
66
63
|
setCollaboratorCanvas(canvas: HTMLCanvasElement | null) {
|
|
67
64
|
self.collaboratorCanvas = canvas
|
|
68
65
|
},
|
|
69
|
-
setSeqTrackCanvas(canvas: HTMLCanvasElement | null) {
|
|
70
|
-
self.seqTrackCanvas = canvas
|
|
71
|
-
},
|
|
72
|
-
setSeqTrackOverlayCanvas(canvas: HTMLCanvasElement | null) {
|
|
73
|
-
self.seqTrackOverlayCanvas = canvas
|
|
74
|
-
},
|
|
75
66
|
setTheme(theme: Theme) {
|
|
76
67
|
self.theme = theme
|
|
77
68
|
},
|
|
69
|
+
}))
|
|
70
|
+
.actions((self) => ({
|
|
78
71
|
afterAttach() {
|
|
79
72
|
addDisposer(
|
|
80
73
|
self,
|
|
@@ -135,346 +128,53 @@ export function renderingModelIntermediateFactory(
|
|
|
135
128
|
{ name: 'LinearApolloDisplayRenderCollaborators' },
|
|
136
129
|
),
|
|
137
130
|
)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
theme?.palette.bases[
|
|
145
|
-
letter.toUpperCase() as keyof Theme['palette']['bases']
|
|
146
|
-
].main.toString() ?? 'lightgray'
|
|
147
|
-
)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function codonColorCode(letter: string, highContrast?: boolean) {
|
|
151
|
-
const colorMap: Record<string, string | undefined> = {
|
|
152
|
-
M: '#33ee33',
|
|
153
|
-
'*': highContrast ? '#000000' : '#f44336',
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return colorMap[letter.toUpperCase()]
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function reverseCodonSeq(seq: string): string {
|
|
160
|
-
// disable because sequence is all ascii
|
|
161
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-spread
|
|
162
|
-
return [...seq]
|
|
163
|
-
.map((c) => revcom(c))
|
|
164
|
-
.reverse()
|
|
165
|
-
.join('')
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function drawLetter(
|
|
169
|
-
seqTrackctx: CanvasRenderingContext2D,
|
|
170
|
-
startPx: number,
|
|
171
|
-
widthPx: number,
|
|
172
|
-
letter: string,
|
|
173
|
-
textY: number,
|
|
174
|
-
) {
|
|
175
|
-
const fontSize = Math.min(widthPx, 10)
|
|
176
|
-
seqTrackctx.fillStyle = '#000'
|
|
177
|
-
seqTrackctx.font = `${fontSize}px`
|
|
178
|
-
const textWidth = seqTrackctx.measureText(letter).width
|
|
179
|
-
const textX = startPx + (widthPx - textWidth) / 2
|
|
180
|
-
seqTrackctx.fillText(letter, textX, textY + 10)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
function drawTranslation(
|
|
184
|
-
seqTrackctx: CanvasRenderingContext2D,
|
|
185
|
-
bpPerPx: number,
|
|
186
|
-
trnslStartPx: number,
|
|
187
|
-
trnslY: number,
|
|
188
|
-
trnslWidthPx: number,
|
|
189
|
-
sequenceRowHeight: number,
|
|
190
|
-
seq: string,
|
|
191
|
-
i: number,
|
|
192
|
-
reverse: boolean,
|
|
193
|
-
showStartCodons: boolean,
|
|
194
|
-
showStopCodons: boolean,
|
|
195
|
-
highContrast: boolean,
|
|
196
|
-
) {
|
|
197
|
-
let codonSeq: string = seq.slice(i, i + 3).toUpperCase()
|
|
198
|
-
if (reverse) {
|
|
199
|
-
codonSeq = reverseCodonSeq(codonSeq)
|
|
200
|
-
}
|
|
201
|
-
const codonLetter =
|
|
202
|
-
defaultCodonTable[codonSeq as keyof typeof defaultCodonTable]
|
|
203
|
-
if (!codonLetter) {
|
|
204
|
-
return
|
|
205
|
-
}
|
|
206
|
-
const fillColor = codonColorCode(codonLetter, highContrast)
|
|
207
|
-
if (
|
|
208
|
-
fillColor &&
|
|
209
|
-
((showStopCodons && codonLetter == '*') ||
|
|
210
|
-
(showStartCodons && codonLetter != '*'))
|
|
211
|
-
) {
|
|
212
|
-
seqTrackctx.fillStyle = fillColor
|
|
213
|
-
seqTrackctx.fillRect(trnslStartPx, trnslY, trnslWidthPx, sequenceRowHeight)
|
|
214
|
-
}
|
|
215
|
-
if (bpPerPx <= 0.1) {
|
|
216
|
-
seqTrackctx.rect(trnslStartPx, trnslY, trnslWidthPx, sequenceRowHeight)
|
|
217
|
-
seqTrackctx.stroke()
|
|
218
|
-
drawLetter(seqTrackctx, trnslStartPx, trnslWidthPx, codonLetter, trnslY)
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
export function sequenceRenderingModelFactory(
|
|
223
|
-
pluginManager: PluginManager,
|
|
224
|
-
configSchema: AnyConfigurationSchemaType,
|
|
225
|
-
) {
|
|
226
|
-
const LinearApolloDisplayRendering = renderingModelIntermediateFactory(
|
|
227
|
-
pluginManager,
|
|
228
|
-
configSchema,
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
return LinearApolloDisplayRendering.actions((self) => ({
|
|
232
|
-
afterAttach() {
|
|
233
|
-
addDisposer(
|
|
234
|
-
self,
|
|
235
|
-
autorun(
|
|
236
|
-
() => {
|
|
237
|
-
const { theme } = self
|
|
238
|
-
if (!self.lgv.initialized || self.regionCannotBeRendered()) {
|
|
239
|
-
return
|
|
240
|
-
}
|
|
241
|
-
const trnslWidthPx = 3 / self.lgv.bpPerPx
|
|
242
|
-
if (trnslWidthPx < 1) {
|
|
243
|
-
return
|
|
244
|
-
}
|
|
245
|
-
const seqTrackctx = self.seqTrackCanvas?.getContext('2d')
|
|
246
|
-
if (!seqTrackctx) {
|
|
247
|
-
return
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
seqTrackctx.clearRect(
|
|
251
|
-
0,
|
|
252
|
-
0,
|
|
253
|
-
self.lgv.dynamicBlocks.totalWidthPx,
|
|
254
|
-
self.lgv.bpPerPx <= 1 ? 125 : 95,
|
|
255
|
-
)
|
|
256
|
-
const frames =
|
|
257
|
-
self.lgv.bpPerPx <= 1
|
|
258
|
-
? [3, 2, 1, 0, 0, -1, -2, -3]
|
|
259
|
-
: [3, 2, 1, -1, -2, -3]
|
|
260
|
-
let height = 0
|
|
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
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
for (const [idx, region] of self.regions.entries()) {
|
|
291
|
-
const { apolloDataStore } =
|
|
292
|
-
self.session as unknown as ApolloSessionModel
|
|
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)
|
|
298
|
-
if (!seq) {
|
|
131
|
+
addDisposer(
|
|
132
|
+
self,
|
|
133
|
+
autorun(
|
|
134
|
+
() => {
|
|
135
|
+
const { canvas, featureLayouts, featuresHeight, lgv } = self
|
|
136
|
+
if (!lgv.initialized || self.regionCannotBeRendered()) {
|
|
299
137
|
return
|
|
300
138
|
}
|
|
301
|
-
|
|
302
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-spread
|
|
303
|
-
for (const [i, letter] of [...seq].entries()) {
|
|
304
|
-
const trnslXOffset =
|
|
305
|
-
(self.lgv.bpToPx({
|
|
306
|
-
refName: region.refName,
|
|
307
|
-
coord: region.start + i,
|
|
308
|
-
regionNumber: idx,
|
|
309
|
-
})?.offsetPx ?? 0) - self.lgv.offsetPx
|
|
310
|
-
const trnslStartPx = self.lgv.displayedRegions[idx].reversed
|
|
311
|
-
? trnslXOffset - trnslWidthPx
|
|
312
|
-
: trnslXOffset
|
|
313
|
-
|
|
314
|
-
// Draw translation forward
|
|
315
|
-
for (let j = 2; j >= 0; j--) {
|
|
316
|
-
if ((region.start + i) % 3 === j) {
|
|
317
|
-
drawTranslation(
|
|
318
|
-
seqTrackctx,
|
|
319
|
-
self.lgv.bpPerPx,
|
|
320
|
-
trnslStartPx,
|
|
321
|
-
self.sequenceRowHeight * (2 - j),
|
|
322
|
-
trnslWidthPx,
|
|
323
|
-
self.sequenceRowHeight,
|
|
324
|
-
seq,
|
|
325
|
-
i,
|
|
326
|
-
false,
|
|
327
|
-
self.showStartCodons,
|
|
328
|
-
self.showStopCodons,
|
|
329
|
-
self.highContrast,
|
|
330
|
-
)
|
|
331
|
-
}
|
|
332
|
-
}
|
|
139
|
+
const { displayedRegions, dynamicBlocks } = lgv
|
|
333
140
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
refName: region.refName,
|
|
338
|
-
coord: region.start + i,
|
|
339
|
-
regionNumber: idx,
|
|
340
|
-
})?.offsetPx ?? 0) - self.lgv.offsetPx
|
|
341
|
-
const widthPx = 1 / self.lgv.bpPerPx
|
|
342
|
-
const startPx = self.lgv.displayedRegions[idx].reversed
|
|
343
|
-
? xOffset - widthPx
|
|
344
|
-
: xOffset
|
|
345
|
-
|
|
346
|
-
// Draw forward
|
|
347
|
-
seqTrackctx.beginPath()
|
|
348
|
-
seqTrackctx.fillStyle = colorCode(letter, self.theme)
|
|
349
|
-
seqTrackctx.rect(
|
|
350
|
-
startPx,
|
|
351
|
-
self.sequenceRowHeight * 3,
|
|
352
|
-
widthPx,
|
|
353
|
-
self.sequenceRowHeight,
|
|
354
|
-
)
|
|
355
|
-
seqTrackctx.fill()
|
|
356
|
-
if (self.lgv.bpPerPx <= 0.1) {
|
|
357
|
-
seqTrackctx.stroke()
|
|
358
|
-
drawLetter(
|
|
359
|
-
seqTrackctx,
|
|
360
|
-
startPx,
|
|
361
|
-
widthPx,
|
|
362
|
-
letter,
|
|
363
|
-
self.sequenceRowHeight * 3,
|
|
364
|
-
)
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Draw reverse
|
|
368
|
-
const revLetter = revcom(letter)
|
|
369
|
-
seqTrackctx.beginPath()
|
|
370
|
-
seqTrackctx.fillStyle = colorCode(revLetter, self.theme)
|
|
371
|
-
seqTrackctx.rect(
|
|
372
|
-
startPx,
|
|
373
|
-
self.sequenceRowHeight * 4,
|
|
374
|
-
widthPx,
|
|
375
|
-
self.sequenceRowHeight,
|
|
376
|
-
)
|
|
377
|
-
seqTrackctx.fill()
|
|
378
|
-
if (self.lgv.bpPerPx <= 0.1) {
|
|
379
|
-
seqTrackctx.stroke()
|
|
380
|
-
drawLetter(
|
|
381
|
-
seqTrackctx,
|
|
382
|
-
startPx,
|
|
383
|
-
widthPx,
|
|
384
|
-
revLetter,
|
|
385
|
-
self.sequenceRowHeight * 4,
|
|
386
|
-
)
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// Draw translation reverse
|
|
391
|
-
for (let k = 0; k <= 2; k++) {
|
|
392
|
-
const rowOffset = self.lgv.bpPerPx <= 1 ? 5 : 3
|
|
393
|
-
if ((region.start + i) % 3 === k) {
|
|
394
|
-
drawTranslation(
|
|
395
|
-
seqTrackctx,
|
|
396
|
-
self.lgv.bpPerPx,
|
|
397
|
-
trnslStartPx,
|
|
398
|
-
self.sequenceRowHeight * (rowOffset + k),
|
|
399
|
-
trnslWidthPx,
|
|
400
|
-
self.sequenceRowHeight,
|
|
401
|
-
seq,
|
|
402
|
-
i,
|
|
403
|
-
true,
|
|
404
|
-
self.showStartCodons,
|
|
405
|
-
self.showStopCodons,
|
|
406
|
-
self.highContrast,
|
|
407
|
-
)
|
|
408
|
-
}
|
|
409
|
-
}
|
|
141
|
+
const ctx = canvas?.getContext('2d')
|
|
142
|
+
if (!ctx) {
|
|
143
|
+
return
|
|
410
144
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
addDisposer(
|
|
432
|
-
self,
|
|
433
|
-
autorun(
|
|
434
|
-
() => {
|
|
435
|
-
const { canvas, featureLayouts, featuresHeight, lgv } = self
|
|
436
|
-
if (!lgv.initialized || self.regionCannotBeRendered()) {
|
|
437
|
-
return
|
|
438
|
-
}
|
|
439
|
-
const { displayedRegions, dynamicBlocks } = lgv
|
|
440
|
-
|
|
441
|
-
const ctx = canvas?.getContext('2d')
|
|
442
|
-
if (!ctx) {
|
|
443
|
-
return
|
|
444
|
-
}
|
|
445
|
-
ctx.clearRect(0, 0, dynamicBlocks.totalWidthPx, featuresHeight)
|
|
446
|
-
for (const [idx, featureLayout] of featureLayouts.entries()) {
|
|
447
|
-
const displayedRegion = displayedRegions[idx]
|
|
448
|
-
for (const [row, featureLayoutRow] of featureLayout.entries()) {
|
|
449
|
-
for (const [featureRow, featureId] of featureLayoutRow) {
|
|
450
|
-
const feature = self.getAnnotationFeatureById(featureId)
|
|
451
|
-
if (featureRow > 0 || !feature) {
|
|
452
|
-
continue
|
|
453
|
-
}
|
|
454
|
-
if (
|
|
455
|
-
!doesIntersect2(
|
|
456
|
-
displayedRegion.start,
|
|
457
|
-
displayedRegion.end,
|
|
458
|
-
feature.min,
|
|
459
|
-
feature.max,
|
|
460
|
-
)
|
|
461
|
-
) {
|
|
462
|
-
continue
|
|
145
|
+
ctx.clearRect(0, 0, dynamicBlocks.totalWidthPx, featuresHeight)
|
|
146
|
+
for (const [idx, featureLayout] of featureLayouts.entries()) {
|
|
147
|
+
const displayedRegion = displayedRegions[idx]
|
|
148
|
+
for (const [row, featureLayoutRow] of featureLayout.entries()) {
|
|
149
|
+
for (const [featureRow, featureId] of featureLayoutRow) {
|
|
150
|
+
const feature = self.getAnnotationFeatureById(featureId)
|
|
151
|
+
if (featureRow > 0 || !feature) {
|
|
152
|
+
continue
|
|
153
|
+
}
|
|
154
|
+
if (
|
|
155
|
+
!doesIntersect2(
|
|
156
|
+
displayedRegion.start,
|
|
157
|
+
displayedRegion.end,
|
|
158
|
+
feature.min,
|
|
159
|
+
feature.max,
|
|
160
|
+
)
|
|
161
|
+
) {
|
|
162
|
+
continue
|
|
163
|
+
}
|
|
164
|
+
self.getGlyph(feature).draw(ctx, feature, row, self, idx)
|
|
463
165
|
}
|
|
464
|
-
self.getGlyph(feature).draw(ctx, feature, row, self, idx)
|
|
465
166
|
}
|
|
466
167
|
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
)
|
|
471
|
-
|
|
472
|
-
}
|
|
473
|
-
}))
|
|
168
|
+
},
|
|
169
|
+
{ name: 'LinearApolloDisplayRenderFeatures' },
|
|
170
|
+
),
|
|
171
|
+
)
|
|
172
|
+
},
|
|
173
|
+
}))
|
|
474
174
|
}
|
|
475
175
|
|
|
476
176
|
export type LinearApolloDisplayRenderingModel = ReturnType<
|
|
477
|
-
typeof
|
|
177
|
+
typeof renderingModelFactory
|
|
478
178
|
>
|
|
479
179
|
// eslint disable because of
|
|
480
180
|
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
package/src/LinearApolloReferenceSequenceDisplay/components/LinearApolloReferenceSequenceDisplay.tsx
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
3
|
+
import { getContainingView } from '@jbrowse/core/util'
|
|
4
|
+
import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
5
|
+
import { Alert, Tooltip, useTheme } from '@mui/material'
|
|
6
|
+
import { observer } from 'mobx-react'
|
|
7
|
+
import React, { useEffect } from 'react'
|
|
8
|
+
|
|
9
|
+
import { useStyles } from '../../util/displayUtils'
|
|
10
|
+
import { type LinearApolloReferenceSequenceDisplay as LinearApolloReferenceSequenceDisplayI } from '../stateModel'
|
|
11
|
+
|
|
12
|
+
interface LinearApolloReferenceSequenceDisplayProps {
|
|
13
|
+
model: LinearApolloReferenceSequenceDisplayI
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const LinearApolloReferenceSequenceDisplay = observer(
|
|
17
|
+
function LinearApolloReferenceSequenceDisplay(
|
|
18
|
+
props: LinearApolloReferenceSequenceDisplayProps,
|
|
19
|
+
) {
|
|
20
|
+
const theme = useTheme()
|
|
21
|
+
const { model } = props
|
|
22
|
+
const {
|
|
23
|
+
height,
|
|
24
|
+
regionCannotBeRendered,
|
|
25
|
+
setSeqTrackCanvas,
|
|
26
|
+
setSeqTrackOverlayCanvas,
|
|
27
|
+
setTheme,
|
|
28
|
+
} = model
|
|
29
|
+
const { classes } = useStyles()
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
setTheme(theme)
|
|
32
|
+
}, [theme, setTheme])
|
|
33
|
+
|
|
34
|
+
const lgv = getContainingView(model) as unknown as LinearGenomeViewModel
|
|
35
|
+
const message = regionCannotBeRendered()
|
|
36
|
+
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
38
|
+
if (message) {
|
|
39
|
+
return (
|
|
40
|
+
<Alert
|
|
41
|
+
severity="warning"
|
|
42
|
+
classes={{ message: classes.ellipses }}
|
|
43
|
+
slotProps={{ root: { className: classes.center } }}
|
|
44
|
+
>
|
|
45
|
+
<Tooltip title={message}>
|
|
46
|
+
<div>{message}</div>
|
|
47
|
+
</Tooltip>
|
|
48
|
+
</Alert>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<>
|
|
54
|
+
{3 / lgv.bpPerPx >= 1 ? (
|
|
55
|
+
<div
|
|
56
|
+
className={classes.canvasContainer}
|
|
57
|
+
style={{
|
|
58
|
+
width: lgv.dynamicBlocks.totalWidthPx,
|
|
59
|
+
height,
|
|
60
|
+
}}
|
|
61
|
+
>
|
|
62
|
+
<canvas
|
|
63
|
+
ref={async (node: HTMLCanvasElement) => {
|
|
64
|
+
await Promise.resolve()
|
|
65
|
+
setSeqTrackCanvas(node)
|
|
66
|
+
}}
|
|
67
|
+
width={lgv.dynamicBlocks.totalWidthPx}
|
|
68
|
+
height={height}
|
|
69
|
+
className={classes.canvas}
|
|
70
|
+
data-testid="seqTrackCanvas"
|
|
71
|
+
/>
|
|
72
|
+
<canvas
|
|
73
|
+
ref={async (node: HTMLCanvasElement) => {
|
|
74
|
+
await Promise.resolve()
|
|
75
|
+
setSeqTrackOverlayCanvas(node)
|
|
76
|
+
}}
|
|
77
|
+
width={lgv.dynamicBlocks.totalWidthPx}
|
|
78
|
+
height={height}
|
|
79
|
+
className={classes.canvas}
|
|
80
|
+
data-testid="seqTrackOverlayCanvas"
|
|
81
|
+
/>
|
|
82
|
+
</div>
|
|
83
|
+
) : null}
|
|
84
|
+
</>
|
|
85
|
+
)
|
|
86
|
+
},
|
|
87
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './LinearApolloReferenceSequenceDisplay'
|