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

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 (136) hide show
  1. package/dist/index.esm.js +6964 -4598
  2. package/dist/index.esm.js.map +1 -1
  3. package/dist/jbrowse-plugin-apollo.cjs.development.js +6610 -4261
  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 +11563 -7493
  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 +4 -4
  12. package/src/ApolloInternetAccount/addMenuItems.ts +23 -2
  13. package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -0
  14. package/src/ApolloInternetAccount/components/LoginButtons.tsx +1 -1
  15. package/src/ApolloInternetAccount/components/LoginIcons.tsx +1 -1
  16. package/src/ApolloInternetAccount/configSchema.ts +1 -1
  17. package/src/ApolloInternetAccount/model.ts +11 -10
  18. package/src/ApolloJobModel.ts +1 -1
  19. package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +8 -6
  20. package/src/ApolloRefNameAliasAdapter/index.ts +2 -2
  21. package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +4 -4
  22. package/src/ApolloSequenceAdapter/index.ts +1 -1
  23. package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +8 -7
  24. package/src/ApolloTextSearchAdapter/index.ts +1 -1
  25. package/src/BackendDrivers/BackendDriver.ts +7 -7
  26. package/src/BackendDrivers/CollaborationServerDriver.ts +14 -10
  27. package/src/BackendDrivers/DesktopFileDriver.ts +11 -10
  28. package/src/BackendDrivers/InMemoryFileDriver.ts +10 -6
  29. package/src/ChangeManager.ts +15 -11
  30. package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +8 -7
  31. package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +35 -14
  32. package/src/FeatureDetailsWidget/AttributeKey.tsx +50 -0
  33. package/src/FeatureDetailsWidget/AttributeKeySelector.tsx +104 -0
  34. package/src/FeatureDetailsWidget/Attributes.tsx +215 -367
  35. package/src/FeatureDetailsWidget/BasicInformation.tsx +6 -5
  36. package/src/FeatureDetailsWidget/DefaultAttributeEditor.tsx +104 -0
  37. package/src/FeatureDetailsWidget/DefaultAttributeViewer.tsx +22 -0
  38. package/src/FeatureDetailsWidget/FeatureDetailsNavigation.tsx +4 -4
  39. package/src/FeatureDetailsWidget/NumberTextField.tsx +1 -1
  40. package/src/FeatureDetailsWidget/Sequence.tsx +2 -2
  41. package/src/FeatureDetailsWidget/StringTextField.tsx +1 -1
  42. package/src/FeatureDetailsWidget/TranscriptSequence.tsx +15 -23
  43. package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +950 -196
  44. package/src/FeatureDetailsWidget/TranscriptWidgetSummary.tsx +8 -4
  45. package/src/FeatureDetailsWidget/model.ts +8 -3
  46. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +7 -7
  47. package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +59 -72
  48. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +253 -60
  49. package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +52 -6
  50. package/src/LinearApolloDisplay/glyphs/Glyph.ts +16 -8
  51. package/src/LinearApolloDisplay/stateModel/base.ts +81 -10
  52. package/src/LinearApolloDisplay/stateModel/index.ts +4 -3
  53. package/src/LinearApolloDisplay/stateModel/layouts.ts +8 -39
  54. package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +63 -46
  55. package/src/LinearApolloDisplay/stateModel/rendering.ts +60 -31
  56. package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +226 -0
  57. package/src/LinearApolloSixFrameDisplay/components/TrackLines.tsx +32 -0
  58. package/src/LinearApolloSixFrameDisplay/components/index.ts +2 -0
  59. package/src/LinearApolloSixFrameDisplay/configSchema.ts +7 -0
  60. package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +940 -0
  61. package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +63 -0
  62. package/src/LinearApolloSixFrameDisplay/glyphs/index.ts +1 -0
  63. package/src/LinearApolloSixFrameDisplay/index.ts +2 -0
  64. package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +302 -0
  65. package/src/LinearApolloSixFrameDisplay/stateModel/index.ts +27 -0
  66. package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +252 -0
  67. package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +368 -0
  68. package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +201 -0
  69. package/src/LinearApolloSixFrameDisplay/types.ts +1 -0
  70. package/src/OntologyManager/OntologyStore/fulltext.test.ts +1 -1
  71. package/src/OntologyManager/OntologyStore/fulltext.ts +8 -3
  72. package/src/OntologyManager/OntologyStore/index.test.ts +3 -1
  73. package/src/OntologyManager/OntologyStore/index.ts +19 -14
  74. package/src/OntologyManager/OntologyStore/indexeddb-schema.ts +6 -5
  75. package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +11 -5
  76. package/src/OntologyManager/index.ts +12 -7
  77. package/src/OntologyManager/util.ts +3 -2
  78. package/src/TabularEditor/HybridGrid/ChangeHandling.ts +2 -2
  79. package/src/TabularEditor/HybridGrid/Feature.tsx +13 -7
  80. package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +1 -1
  81. package/src/TabularEditor/HybridGrid/HybridGrid.tsx +3 -2
  82. package/src/TabularEditor/HybridGrid/ToolBar.tsx +1 -1
  83. package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +114 -22
  84. package/src/TabularEditor/TabularEditorPane.tsx +1 -1
  85. package/src/TabularEditor/model.ts +2 -2
  86. package/src/TabularEditor/types.ts +5 -2
  87. package/src/components/AddAssembly.tsx +182 -179
  88. package/src/components/AddAssemblyAliases.tsx +114 -0
  89. package/src/components/AddChildFeature.tsx +8 -10
  90. package/src/components/AddFeature.tsx +216 -44
  91. package/src/components/AddRefSeqAliases.tsx +14 -12
  92. package/src/components/CopyFeature.tsx +10 -11
  93. package/src/components/CreateApolloAnnotation.tsx +342 -158
  94. package/src/components/DeleteAssembly.tsx +9 -8
  95. package/src/components/DeleteFeature.tsx +362 -14
  96. package/src/components/Dialog.tsx +1 -1
  97. package/src/components/DownloadGFF3.tsx +31 -11
  98. package/src/components/FilterFeatures.tsx +6 -4
  99. package/src/components/FilterTranscripts.tsx +86 -0
  100. package/src/components/ImportFeatures.tsx +7 -6
  101. package/src/components/LogOut.tsx +5 -4
  102. package/src/components/ManageChecks.tsx +9 -8
  103. package/src/components/ManageUsers.tsx +11 -10
  104. package/src/components/MergeExons.tsx +193 -0
  105. package/src/components/MergeTranscripts.tsx +185 -0
  106. package/src/components/OntologyTermAutocomplete.tsx +5 -5
  107. package/src/components/OntologyTermMultiSelect.tsx +6 -6
  108. package/src/components/OpenLocalFile.tsx +4 -3
  109. package/src/components/SplitExon.tsx +134 -0
  110. package/src/components/ViewChangeLog.tsx +7 -6
  111. package/src/components/ViewCheckResults.tsx +8 -7
  112. package/src/components/index.ts +3 -0
  113. package/src/config.ts +5 -0
  114. package/src/extensions/annotationFromJBrowseFeature.test.ts +1 -0
  115. package/src/extensions/annotationFromJBrowseFeature.ts +13 -10
  116. package/src/extensions/annotationFromPileup.ts +104 -94
  117. package/src/index.ts +33 -50
  118. package/src/makeDisplayComponent.tsx +90 -37
  119. package/src/session/ClientDataStore.ts +21 -17
  120. package/src/session/session.ts +46 -39
  121. package/src/types.ts +4 -4
  122. package/src/util/annotationFeatureUtils.ts +66 -1
  123. package/src/util/copyToClipboard.ts +21 -0
  124. package/src/util/glyphUtils.ts +49 -0
  125. package/src/util/index.ts +5 -3
  126. package/src/util/loadAssemblyIntoClient.ts +10 -3
  127. package/src/util/mouseEventsUtils.ts +113 -0
  128. package/src/ApolloSixFrameRenderer/ApolloSixFrameRenderer.tsx +0 -13
  129. package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +0 -707
  130. package/src/ApolloSixFrameRenderer/configSchema.ts +0 -7
  131. package/src/ApolloSixFrameRenderer/index.ts +0 -3
  132. package/src/SixFrameFeatureDisplay/components/TrackLines.tsx +0 -19
  133. package/src/SixFrameFeatureDisplay/components/index.ts +0 -1
  134. package/src/SixFrameFeatureDisplay/configSchema.ts +0 -21
  135. package/src/SixFrameFeatureDisplay/index.ts +0 -2
  136. package/src/SixFrameFeatureDisplay/stateModel.ts +0 -443
@@ -1,12 +1,13 @@
1
1
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
2
- import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
3
- import PluginManager from '@jbrowse/core/PluginManager'
2
+ import type PluginManager from '@jbrowse/core/PluginManager'
3
+ import { type AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
4
4
  import { defaultCodonTable, doesIntersect2, revcom } from '@jbrowse/core/util'
5
- import { Theme } from '@mui/material'
5
+ import { type Theme } from '@mui/material'
6
6
  import { autorun } from 'mobx'
7
- import { Instance, addDisposer } from 'mobx-state-tree'
7
+ import { type Instance, addDisposer, types } from 'mobx-state-tree'
8
+
9
+ import { type ApolloSessionModel } from '../../session'
8
10
 
9
- import { ApolloSessionModel } from '../../session'
10
11
  import { layoutsModelFactory } from './layouts'
11
12
 
12
13
  export function renderingModelIntermediateFactory(
@@ -26,6 +27,7 @@ export function renderingModelIntermediateFactory(
26
27
  detailsHeight: 200,
27
28
  lastRowTooltipBufferHeight: 40,
28
29
  isShown: true,
30
+ filteredTranscripts: types.array(types.string),
29
31
  })
30
32
  .volatile(() => ({
31
33
  canvas: null as HTMLCanvasElement | null,
@@ -145,10 +147,10 @@ function colorCode(letter: string, theme?: Theme) {
145
147
  )
146
148
  }
147
149
 
148
- function codonColorCode(letter: string) {
150
+ function codonColorCode(letter: string, highContrast?: boolean) {
149
151
  const colorMap: Record<string, string | undefined> = {
150
152
  M: '#33ee33',
151
- '*': '#f44336',
153
+ '*': highContrast ? '#000000' : '#f44336',
152
154
  }
153
155
 
154
156
  return colorMap[letter.toUpperCase()]
@@ -188,6 +190,9 @@ function drawTranslation(
188
190
  seq: string,
189
191
  i: number,
190
192
  reverse: boolean,
193
+ showStartCodons: boolean,
194
+ showStopCodons: boolean,
195
+ highContrast: boolean,
191
196
  ) {
192
197
  let codonSeq: string = seq.slice(i, i + 3).toUpperCase()
193
198
  if (reverse) {
@@ -198,8 +203,12 @@ function drawTranslation(
198
203
  if (!codonLetter) {
199
204
  return
200
205
  }
201
- const fillColor = codonColorCode(codonLetter)
202
- if (fillColor) {
206
+ const fillColor = codonColorCode(codonLetter, highContrast)
207
+ if (
208
+ fillColor &&
209
+ ((showStopCodons && codonLetter == '*') ||
210
+ (showStartCodons && codonLetter != '*'))
211
+ ) {
203
212
  seqTrackctx.fillStyle = fillColor
204
213
  seqTrackctx.fillRect(trnslStartPx, trnslY, trnslWidthPx, sequenceRowHeight)
205
214
  }
@@ -224,11 +233,13 @@ export function sequenceRenderingModelFactory(
224
233
  addDisposer(
225
234
  self,
226
235
  autorun(
227
- async () => {
236
+ () => {
237
+ const { theme } = self
228
238
  if (!self.lgv.initialized || self.regionCannotBeRendered()) {
229
239
  return
230
240
  }
231
- if (self.lgv.bpPerPx > 3) {
241
+ const trnslWidthPx = 3 / self.lgv.bpPerPx
242
+ if (trnslWidthPx < 1) {
232
243
  return
233
244
  }
234
245
  const seqTrackctx = self.seqTrackCanvas?.getContext('2d')
@@ -247,30 +258,43 @@ export function sequenceRenderingModelFactory(
247
258
  ? [3, 2, 1, 0, 0, -1, -2, -3]
248
259
  : [3, 2, 1, -1, -2, -3]
249
260
  let height = 0
250
- for (const frame of frames) {
251
- const frameColor = self.theme?.palette.framesCDS.at(frame)?.main
252
- if (frameColor) {
253
- seqTrackctx.fillStyle = frameColor
254
- seqTrackctx.fillRect(
255
- 0,
256
- height,
257
- self.lgv.dynamicBlocks.totalWidthPx,
258
- self.sequenceRowHeight,
259
- )
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
260
287
  }
261
- height += self.sequenceRowHeight
262
288
  }
263
289
 
264
290
  for (const [idx, region] of self.regions.entries()) {
265
- const driver = (
291
+ const { apolloDataStore } =
266
292
  self.session as unknown as ApolloSessionModel
267
- ).apolloDataStore.getBackendDriver(region.assemblyName)
268
-
269
- if (!driver) {
270
- throw new Error('Failed to get the backend driver')
271
- }
272
- const { seq } = await driver.getSequence(region)
273
-
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)
274
298
  if (!seq) {
275
299
  return
276
300
  }
@@ -283,7 +307,6 @@ export function sequenceRenderingModelFactory(
283
307
  coord: region.start + i,
284
308
  regionNumber: idx,
285
309
  })?.offsetPx ?? 0) - self.lgv.offsetPx
286
- const trnslWidthPx = 3 / self.lgv.bpPerPx
287
310
  const trnslStartPx = self.lgv.displayedRegions[idx].reversed
288
311
  ? trnslXOffset - trnslWidthPx
289
312
  : trnslXOffset
@@ -301,6 +324,9 @@ export function sequenceRenderingModelFactory(
301
324
  seq,
302
325
  i,
303
326
  false,
327
+ self.showStartCodons,
328
+ self.showStopCodons,
329
+ self.highContrast,
304
330
  )
305
331
  }
306
332
  }
@@ -375,6 +401,9 @@ export function sequenceRenderingModelFactory(
375
401
  seq,
376
402
  i,
377
403
  true,
404
+ self.showStartCodons,
405
+ self.showStopCodons,
406
+ self.highContrast,
378
407
  )
379
408
  }
380
409
  }
@@ -0,0 +1,226 @@
1
+ /* eslint-disable @typescript-eslint/unbound-method */
2
+ /* eslint-disable @typescript-eslint/no-misused-promises */
3
+ /* eslint-disable @typescript-eslint/no-unnecessary-condition */
4
+ import { Menu, type MenuItem } from '@jbrowse/core/ui'
5
+ import {
6
+ type AbstractSessionModel,
7
+ doesIntersect2,
8
+ getContainingView,
9
+ } from '@jbrowse/core/util'
10
+ import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
11
+ import ErrorIcon from '@mui/icons-material/Error'
12
+ import { Alert, Avatar, Tooltip, useTheme } from '@mui/material'
13
+ import { observer } from 'mobx-react'
14
+ import React, { useEffect, useState } from 'react'
15
+ import { makeStyles } from 'tss-react/mui'
16
+
17
+ import { type LinearApolloSixFrameDisplay as LinearApolloSixFrameDisplayI } from '../stateModel'
18
+
19
+ import { TrackLines } from './TrackLines'
20
+
21
+ interface LinearApolloSixFrameDisplayProps {
22
+ model: LinearApolloSixFrameDisplayI
23
+ }
24
+ export type Coord = [number, number]
25
+
26
+ const useStyles = makeStyles()((theme) => ({
27
+ canvasContainer: {
28
+ position: 'relative',
29
+ left: 0,
30
+ },
31
+ canvas: {
32
+ position: 'absolute',
33
+ left: 0,
34
+ },
35
+ ellipses: {
36
+ textOverflow: 'ellipsis',
37
+ overflow: 'hidden',
38
+ },
39
+ avatar: {
40
+ position: 'absolute',
41
+ color: theme.palette.warning.light,
42
+ backgroundColor: theme.palette.warning.contrastText,
43
+ },
44
+ }))
45
+
46
+ export const LinearApolloSixFrameDisplay = observer(
47
+ function LinearApolloSixFrameDisplay(
48
+ props: LinearApolloSixFrameDisplayProps,
49
+ ) {
50
+ const theme = useTheme()
51
+ const { model } = props
52
+ const {
53
+ apolloRowHeight,
54
+ contextMenuItems: getContextMenuItems,
55
+ cursor,
56
+ featuresHeight,
57
+ isShown,
58
+ onMouseDown,
59
+ onMouseLeave,
60
+ onMouseMove,
61
+ onMouseUp,
62
+ regionCannotBeRendered,
63
+ session,
64
+ setCanvas,
65
+ setCollaboratorCanvas,
66
+ setOverlayCanvas,
67
+ setTheme,
68
+ } = model
69
+ const { classes } = useStyles()
70
+ const lgv = getContainingView(model) as unknown as LinearGenomeViewModel
71
+
72
+ useEffect(() => {
73
+ setTheme(theme)
74
+ }, [theme, setTheme])
75
+ const [contextCoord, setContextCoord] = useState<Coord>()
76
+ const [contextMenuItems, setContextMenuItems] = useState<MenuItem[]>([])
77
+ const message = regionCannotBeRendered()
78
+ if (!isShown) {
79
+ return null
80
+ }
81
+ const { assemblyManager } = session as unknown as AbstractSessionModel
82
+ return (
83
+ <>
84
+ <div
85
+ className={classes.canvasContainer}
86
+ style={{
87
+ width: lgv.dynamicBlocks.totalWidthPx,
88
+ height: featuresHeight,
89
+ }}
90
+ onContextMenu={(event) => {
91
+ event.preventDefault()
92
+ if (contextMenuItems.length > 0) {
93
+ // There's already a context menu open, so close it
94
+ setContextMenuItems([])
95
+ } else {
96
+ const coord: [number, number] = [event.clientX, event.clientY]
97
+ setContextCoord(coord)
98
+ setContextMenuItems(getContextMenuItems(coord))
99
+ }
100
+ }}
101
+ >
102
+ {message ? (
103
+ <Alert severity="warning" classes={{ message: classes.ellipses }}>
104
+ <Tooltip title={message}>
105
+ <div>{message}</div>
106
+ </Tooltip>
107
+ </Alert>
108
+ ) : (
109
+ // Promise.resolve() in these 3 callbacks is to avoid infinite rendering loop
110
+ // https://github.com/mobxjs/mobx/issues/3728#issuecomment-1715400931
111
+ <>
112
+ <TrackLines model={model} idx={0} />
113
+ <TrackLines
114
+ model={model}
115
+ hrStyle={{ margin: 0, top: 0, color: 'grey', opacity: 0.4 }}
116
+ idx={1}
117
+ />
118
+ <TrackLines model={model} idx={2} />
119
+ <canvas
120
+ ref={async (node: HTMLCanvasElement) => {
121
+ await Promise.resolve()
122
+ setCollaboratorCanvas(node)
123
+ }}
124
+ width={lgv.dynamicBlocks.totalWidthPx}
125
+ height={featuresHeight}
126
+ className={classes.canvas}
127
+ data-testid="collaboratorCanvas"
128
+ />
129
+ <canvas
130
+ ref={async (node: HTMLCanvasElement) => {
131
+ await Promise.resolve()
132
+ setCanvas(node)
133
+ }}
134
+ width={lgv.dynamicBlocks.totalWidthPx}
135
+ height={featuresHeight}
136
+ className={classes.canvas}
137
+ data-testid="canvas"
138
+ />
139
+ <canvas
140
+ ref={async (node: HTMLCanvasElement) => {
141
+ await Promise.resolve()
142
+ setOverlayCanvas(node)
143
+ }}
144
+ width={lgv.dynamicBlocks.totalWidthPx}
145
+ height={featuresHeight}
146
+ onMouseMove={onMouseMove}
147
+ onMouseLeave={onMouseLeave}
148
+ onMouseDown={onMouseDown}
149
+ onMouseUp={onMouseUp}
150
+ className={classes.canvas}
151
+ style={{ cursor: cursor ?? 'default' }}
152
+ data-testid="overlayCanvas"
153
+ />
154
+ {lgv.displayedRegions.flatMap((region, idx) => {
155
+ const assembly = assemblyManager.get(region.assemblyName)
156
+ return [...session.apolloDataStore.checkResults.values()]
157
+ .filter(
158
+ (checkResult) =>
159
+ assembly?.isValidRefName(checkResult.refSeq) &&
160
+ assembly.getCanonicalRefName(checkResult.refSeq) ===
161
+ region.refName &&
162
+ doesIntersect2(
163
+ region.start,
164
+ region.end,
165
+ checkResult.start,
166
+ checkResult.end,
167
+ ),
168
+ )
169
+ .map((checkResult) => {
170
+ const left =
171
+ (lgv.bpToPx({
172
+ refName: region.refName,
173
+ coord: checkResult.start,
174
+ regionNumber: idx,
175
+ })?.offsetPx ?? 0) - lgv.offsetPx
176
+ const [feature] = checkResult.ids
177
+ if (!feature || !feature.parent?.looksLikeGene) {
178
+ return null
179
+ }
180
+ const top = 0
181
+ const height = apolloRowHeight
182
+ return (
183
+ <Tooltip
184
+ key={checkResult._id}
185
+ title={checkResult.message}
186
+ >
187
+ <Avatar
188
+ className={classes.avatar}
189
+ style={{ top, left, height, width: height }}
190
+ >
191
+ <ErrorIcon />
192
+ </Avatar>
193
+ </Tooltip>
194
+ )
195
+ })
196
+ })}
197
+ <Menu
198
+ open={contextMenuItems.length > 0}
199
+ onMenuItemClick={(_, callback) => {
200
+ callback()
201
+ setContextMenuItems([])
202
+ }}
203
+ onClose={() => {
204
+ setContextMenuItems([])
205
+ }}
206
+ TransitionProps={{
207
+ onExit: () => {
208
+ setContextMenuItems([])
209
+ },
210
+ }}
211
+ anchorReference="anchorPosition"
212
+ anchorPosition={
213
+ contextCoord
214
+ ? { top: contextCoord[1], left: contextCoord[0] }
215
+ : undefined
216
+ }
217
+ style={{ zIndex: theme.zIndex.tooltip }}
218
+ menuItems={contextMenuItems}
219
+ />
220
+ </>
221
+ )}
222
+ </div>
223
+ </>
224
+ )
225
+ },
226
+ )
@@ -0,0 +1,32 @@
1
+ import { observer } from 'mobx-react'
2
+ import React from 'react'
3
+
4
+ import { type LinearApolloSixFrameDisplay } from '../stateModel'
5
+
6
+ export const TrackLines = observer(function TrackLines({
7
+ model,
8
+ hrStyle = { margin: 0, top: 0, color: 'black' },
9
+ idx = 0,
10
+ }: {
11
+ model: LinearApolloSixFrameDisplay
12
+ hrStyle?: React.CSSProperties
13
+ idx: number
14
+ }) {
15
+ const { apolloRowHeight, highestRow, showFeatureLabels } = model
16
+ const featureLabelSpacer = showFeatureLabels ? 2 : 1
17
+
18
+ return (
19
+ <div
20
+ style={{
21
+ position: 'absolute',
22
+ left: 0,
23
+ top:
24
+ (apolloRowHeight * featureLabelSpacer * (highestRow + 1)) / 2 +
25
+ idx * featureLabelSpacer * apolloRowHeight,
26
+ width: '100%',
27
+ }}
28
+ >
29
+ <hr style={hrStyle} />
30
+ </div>
31
+ )
32
+ })
@@ -0,0 +1,2 @@
1
+ export * from './LinearApolloSixFrameDisplay'
2
+ export * from './TrackLines'
@@ -0,0 +1,7 @@
1
+ import { ConfigurationSchema } from '@jbrowse/core/configuration'
2
+
3
+ export const configSchema = ConfigurationSchema(
4
+ 'LinearApolloSixFrameDisplay',
5
+ {},
6
+ { explicitIdentifier: 'displayId', explicitlyTyped: true },
7
+ )