@apollo-annotation/jbrowse-plugin-apollo 0.3.7 → 0.3.9

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 (86) hide show
  1. package/dist/index.esm.js +11212 -10483
  2. package/dist/index.esm.js.map +1 -1
  3. package/dist/jbrowse-plugin-apollo.cjs.development.js +11251 -10509
  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 +7726 -9014
  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 +18 -18
  12. package/src/ApolloInternetAccount/model.ts +123 -70
  13. package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +4 -4
  14. package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +9 -7
  15. package/src/BackendDrivers/CollaborationServerDriver.ts +72 -20
  16. package/src/BackendDrivers/DesktopFileDriver.ts +2 -2
  17. package/src/ChangeManager.ts +36 -14
  18. package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +64 -5
  19. package/src/FeatureDetailsWidget/BasicInformation.tsx +6 -4
  20. package/src/FeatureDetailsWidget/NumberTextField.tsx +5 -2
  21. package/src/FeatureDetailsWidget/TranscriptSequence.tsx +70 -73
  22. package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +72 -234
  23. package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +92 -0
  24. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +23 -131
  25. package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +50 -194
  26. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +279 -217
  27. package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +53 -34
  28. package/src/LinearApolloDisplay/glyphs/Glyph.ts +7 -9
  29. package/src/LinearApolloDisplay/glyphs/util.ts +19 -0
  30. package/src/LinearApolloDisplay/stateModel/base.ts +34 -43
  31. package/src/LinearApolloDisplay/stateModel/layouts.ts +3 -2
  32. package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +32 -261
  33. package/src/LinearApolloDisplay/stateModel/rendering.ts +43 -343
  34. package/src/LinearApolloReferenceSequenceDisplay/components/LinearApolloReferenceSequenceDisplay.tsx +87 -0
  35. package/src/LinearApolloReferenceSequenceDisplay/components/index.ts +1 -0
  36. package/src/LinearApolloReferenceSequenceDisplay/configSchema.ts +7 -0
  37. package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +181 -0
  38. package/src/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.ts +218 -0
  39. package/src/LinearApolloReferenceSequenceDisplay/index.ts +3 -0
  40. package/src/LinearApolloReferenceSequenceDisplay/stateModel/base.ts +227 -0
  41. package/src/LinearApolloReferenceSequenceDisplay/stateModel/index.ts +25 -0
  42. package/src/LinearApolloReferenceSequenceDisplay/stateModel/rendering.ts +157 -0
  43. package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +101 -38
  44. package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +334 -262
  45. package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +12 -8
  46. package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +42 -4
  47. package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +4 -8
  48. package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +73 -97
  49. package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +49 -61
  50. package/src/TabularEditor/HybridGrid/Feature.tsx +16 -14
  51. package/src/TabularEditor/HybridGrid/HybridGrid.tsx +7 -5
  52. package/src/components/AddAssembly.tsx +34 -38
  53. package/src/components/AddAssemblyAliases.tsx +1 -1
  54. package/src/components/AddChildFeature.tsx +5 -2
  55. package/src/components/AddFeature.tsx +30 -21
  56. package/src/components/AddRefSeqAliases.tsx +64 -50
  57. package/src/components/CopyFeature.tsx +4 -2
  58. package/src/components/CreateApolloAnnotation.tsx +22 -9
  59. package/src/components/DeleteAssembly.tsx +3 -10
  60. package/src/components/DownloadGFF3.tsx +2 -2
  61. package/src/components/EditZoomThresholdDialog.tsx +69 -0
  62. package/src/components/FilterFeatures.tsx +7 -7
  63. package/src/components/FilterTranscripts.tsx +6 -6
  64. package/src/components/ImportFeatures.tsx +1 -1
  65. package/src/components/ManageChecks.tsx +3 -10
  66. package/src/components/ManageUsers.tsx +23 -22
  67. package/src/components/MergeTranscripts.tsx +12 -15
  68. package/src/components/OntologyTermAutocomplete.tsx +1 -8
  69. package/src/components/OntologyTermMultiSelect.tsx +11 -11
  70. package/src/components/OpenLocalFile.tsx +11 -7
  71. package/src/components/ViewChangeLog.tsx +25 -50
  72. package/src/components/ViewCheckResults.tsx +2 -8
  73. package/src/components/index.ts +1 -0
  74. package/src/config.ts +6 -0
  75. package/src/index.ts +53 -115
  76. package/src/makeDisplayComponent.tsx +9 -14
  77. package/src/menus/index.ts +1 -0
  78. package/src/{ApolloInternetAccount/addMenuItems.ts → menus/topLevelMenu.ts} +56 -47
  79. package/src/menus/topLevelMenuAdmin.ts +154 -0
  80. package/src/session/ClientDataStore.ts +32 -14
  81. package/src/session/session.ts +159 -121
  82. package/src/util/annotationFeatureUtils.ts +15 -21
  83. package/src/util/displayUtils.ts +149 -0
  84. package/src/util/glyphUtils.ts +329 -0
  85. package/src/util/loadAssemblyIntoClient.ts +3 -2
  86. 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 { 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
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 renderingModelIntermediateFactory(
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
- seqTrackCanvas: null as HTMLCanvasElement | null,
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
- function colorCode(letter: string, theme?: Theme) {
143
- return (
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
- // disable because sequence is all ascii
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
- if (self.lgv.bpPerPx <= 1) {
335
- const xOffset =
336
- (self.lgv.bpToPx({
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
- { name: 'LinearApolloDisplayRenderSequence' },
414
- ),
415
- )
416
- },
417
- }))
418
- }
419
-
420
- export function renderingModelFactory(
421
- pluginManager: PluginManager,
422
- configSchema: AnyConfigurationSchemaType,
423
- ) {
424
- const LinearApolloDisplayRendering = sequenceRenderingModelFactory(
425
- pluginManager,
426
- configSchema,
427
- )
428
-
429
- return LinearApolloDisplayRendering.actions((self) => ({
430
- afterAttach() {
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
- { name: 'LinearApolloDisplayRenderFeatures' },
470
- ),
471
- )
472
- },
473
- }))
168
+ },
169
+ { name: 'LinearApolloDisplayRenderFeatures' },
170
+ ),
171
+ )
172
+ },
173
+ }))
474
174
  }
475
175
 
476
176
  export type LinearApolloDisplayRenderingModel = ReturnType<
477
- typeof renderingModelIntermediateFactory
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
@@ -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
+ )