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