@apollo-annotation/jbrowse-plugin-apollo 0.3.12 → 1.0.0

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 (192) hide show
  1. package/dist/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.d.ts +1 -1
  2. package/dist/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.d.ts.map +1 -1
  3. package/dist/BackendDrivers/BackendDriver.d.ts +29 -4
  4. package/dist/BackendDrivers/BackendDriver.d.ts.map +1 -1
  5. package/dist/BackendDrivers/CollaborationServerDriver.d.ts +3 -1
  6. package/dist/BackendDrivers/CollaborationServerDriver.d.ts.map +1 -1
  7. package/dist/BackendDrivers/LocalDriver/LocalDriver.d.ts +22 -0
  8. package/dist/BackendDrivers/LocalDriver/LocalDriver.d.ts.map +1 -0
  9. package/dist/BackendDrivers/LocalDriver/db.d.ts +4 -0
  10. package/dist/BackendDrivers/LocalDriver/db.d.ts.map +1 -0
  11. package/dist/BackendDrivers/index.d.ts +1 -2
  12. package/dist/BackendDrivers/index.d.ts.map +1 -1
  13. package/dist/ChangeManager.d.ts +3 -3
  14. package/dist/ChangeManager.d.ts.map +1 -1
  15. package/dist/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.d.ts +0 -6
  16. package/dist/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.d.ts.map +1 -1
  17. package/dist/FeatureDetailsWidget/TranscriptWidgetEditLocation.d.ts.map +1 -1
  18. package/dist/FeatureDetailsWidget/model.d.ts +0 -2
  19. package/dist/FeatureDetailsWidget/model.d.ts.map +1 -1
  20. package/dist/LinearApolloDisplay/components/CheckResultWarnings.d.ts.map +1 -1
  21. package/dist/LinearApolloDisplay/components/LinearApolloDisplay.d.ts.map +1 -1
  22. package/dist/LinearApolloDisplay/components/OverlayCanvas.d.ts +7 -0
  23. package/dist/LinearApolloDisplay/components/OverlayCanvas.d.ts.map +1 -0
  24. package/dist/LinearApolloDisplay/components/Tooltip.d.ts +10 -0
  25. package/dist/LinearApolloDisplay/components/Tooltip.d.ts.map +1 -0
  26. package/dist/LinearApolloDisplay/glyphs/BoxGlyph.d.ts +0 -1
  27. package/dist/LinearApolloDisplay/glyphs/BoxGlyph.d.ts.map +1 -1
  28. package/dist/LinearApolloDisplay/glyphs/CDSGlyph.d.ts +3 -0
  29. package/dist/LinearApolloDisplay/glyphs/CDSGlyph.d.ts.map +1 -0
  30. package/dist/LinearApolloDisplay/glyphs/ExonGlyph.d.ts +3 -0
  31. package/dist/LinearApolloDisplay/glyphs/ExonGlyph.d.ts.map +1 -0
  32. package/dist/LinearApolloDisplay/glyphs/GeneGlyph.d.ts.map +1 -1
  33. package/dist/LinearApolloDisplay/glyphs/GenericChildGlyph.d.ts.map +1 -1
  34. package/dist/LinearApolloDisplay/glyphs/Glyph.d.ts +26 -20
  35. package/dist/LinearApolloDisplay/glyphs/Glyph.d.ts.map +1 -1
  36. package/dist/LinearApolloDisplay/glyphs/TranscriptGlyph.d.ts +3 -0
  37. package/dist/LinearApolloDisplay/glyphs/TranscriptGlyph.d.ts.map +1 -0
  38. package/dist/LinearApolloDisplay/glyphs/util.d.ts +13 -0
  39. package/dist/LinearApolloDisplay/glyphs/util.d.ts.map +1 -1
  40. package/dist/LinearApolloDisplay/stateModel/base.d.ts +17 -0
  41. package/dist/LinearApolloDisplay/stateModel/base.d.ts.map +1 -1
  42. package/dist/LinearApolloDisplay/stateModel/index.d.ts +35 -17
  43. package/dist/LinearApolloDisplay/stateModel/index.d.ts.map +1 -1
  44. package/dist/LinearApolloDisplay/stateModel/layouts.d.ts +29 -7
  45. package/dist/LinearApolloDisplay/stateModel/layouts.d.ts.map +1 -1
  46. package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts +69 -23
  47. package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts.map +1 -1
  48. package/dist/LinearApolloDisplay/stateModel/rendering.d.ts +26 -9
  49. package/dist/LinearApolloDisplay/stateModel/rendering.d.ts.map +1 -1
  50. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts +6 -0
  51. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts.map +1 -1
  52. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/index.d.ts +6 -0
  53. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/index.d.ts.map +1 -1
  54. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/rendering.d.ts +6 -0
  55. package/dist/LinearApolloReferenceSequenceDisplay/stateModel/rendering.d.ts.map +1 -1
  56. package/dist/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.d.ts.map +1 -1
  57. package/dist/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.d.ts.map +1 -1
  58. package/dist/LinearApolloSixFrameDisplay/glyphs/Glyph.d.ts +1 -1
  59. package/dist/LinearApolloSixFrameDisplay/glyphs/Glyph.d.ts.map +1 -1
  60. package/dist/LinearApolloSixFrameDisplay/stateModel/layouts.d.ts.map +1 -1
  61. package/dist/LinearApolloSixFrameDisplay/stateModel/rendering.d.ts.map +1 -1
  62. package/dist/OntologyManager/OntologyStore/fulltext.d.ts +1 -1
  63. package/dist/OntologyManager/OntologyStore/fulltext.d.ts.map +1 -1
  64. package/dist/OntologyManager/OntologyStore/index.d.ts +2 -2
  65. package/dist/OntologyManager/OntologyStore/index.d.ts.map +1 -1
  66. package/dist/OntologyManager/OntologyStore/indexeddb-storage.d.ts +1 -1
  67. package/dist/OntologyManager/OntologyStore/indexeddb-storage.d.ts.map +1 -1
  68. package/dist/OntologyManager/OntologyStore/types.d.ts +18 -0
  69. package/dist/OntologyManager/OntologyStore/types.d.ts.map +1 -0
  70. package/dist/TabularEditor/HybridGrid/featureContextMenuItems.d.ts.map +1 -1
  71. package/dist/components/AddChildFeature.d.ts.map +1 -1
  72. package/dist/components/ColorFeature.d.ts +13 -0
  73. package/dist/components/ColorFeature.d.ts.map +1 -0
  74. package/dist/components/CreateApolloAnnotation.d.ts.map +1 -1
  75. package/dist/components/DownloadGFF3.d.ts +4 -1
  76. package/dist/components/DownloadGFF3.d.ts.map +1 -1
  77. package/dist/components/DuplicateTranscript.d.ts.map +1 -1
  78. package/dist/components/ViewChangeLog.d.ts +2 -1
  79. package/dist/components/ViewChangeLog.d.ts.map +1 -1
  80. package/dist/components/ViewCheckResults.d.ts +2 -1
  81. package/dist/components/ViewCheckResults.d.ts.map +1 -1
  82. package/dist/components/index.d.ts +1 -1
  83. package/dist/components/index.d.ts.map +1 -1
  84. package/dist/config.d.ts +4 -0
  85. package/dist/config.d.ts.map +1 -0
  86. package/dist/extensions/annotationFromJBrowseFeature.d.ts.map +1 -1
  87. package/dist/extensions/annotationFromPileup.d.ts.map +1 -1
  88. package/dist/index.d.ts +11 -0
  89. package/dist/index.d.ts.map +1 -0
  90. package/dist/index.esm.js +6325 -5997
  91. package/dist/index.esm.js.map +1 -1
  92. package/dist/jbrowse-plugin-apollo.cjs.development.js +5869 -5541
  93. package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
  94. package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
  95. package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
  96. package/dist/jbrowse-plugin-apollo.umd.development.js +16782 -25897
  97. package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
  98. package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
  99. package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
  100. package/dist/makeDisplayComponent.d.ts.map +1 -1
  101. package/dist/menus/Icons.d.ts +3 -0
  102. package/dist/menus/Icons.d.ts.map +1 -0
  103. package/dist/menus/topLevelMenu.d.ts.map +1 -1
  104. package/dist/session/changeHandlers.d.ts +9 -0
  105. package/dist/session/changeHandlers.d.ts.map +1 -0
  106. package/dist/util/annotationFeatureUtils.d.ts +2 -1
  107. package/dist/util/annotationFeatureUtils.d.ts.map +1 -1
  108. package/dist/util/glyphUtils.d.ts +3 -3
  109. package/dist/util/glyphUtils.d.ts.map +1 -1
  110. package/dist/util/index.d.ts +0 -1
  111. package/dist/util/index.d.ts.map +1 -1
  112. package/package.json +4 -4
  113. package/src/ApolloInternetAccount/model.ts +68 -4
  114. package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +6 -3
  115. package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +1 -1
  116. package/src/BackendDrivers/BackendDriver.ts +36 -3
  117. package/src/BackendDrivers/CollaborationServerDriver.ts +78 -23
  118. package/src/BackendDrivers/LocalDriver/LocalDriver.ts +367 -0
  119. package/src/BackendDrivers/LocalDriver/db.ts +37 -0
  120. package/src/BackendDrivers/index.ts +1 -2
  121. package/src/ChangeManager.ts +27 -25
  122. package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +1 -1
  123. package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +69 -53
  124. package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +1 -5
  125. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +95 -115
  126. package/src/LinearApolloDisplay/components/OverlayCanvas.tsx +76 -0
  127. package/src/LinearApolloDisplay/components/Tooltip.tsx +42 -0
  128. package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +60 -302
  129. package/src/LinearApolloDisplay/glyphs/CDSGlyph.ts +145 -0
  130. package/src/LinearApolloDisplay/glyphs/ExonGlyph.ts +212 -0
  131. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +65 -999
  132. package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +71 -181
  133. package/src/LinearApolloDisplay/glyphs/Glyph.ts +42 -66
  134. package/src/LinearApolloDisplay/glyphs/TranscriptGlyph.ts +291 -0
  135. package/src/LinearApolloDisplay/glyphs/util.ts +87 -0
  136. package/src/LinearApolloDisplay/stateModel/base.ts +83 -0
  137. package/src/LinearApolloDisplay/stateModel/layouts.ts +198 -138
  138. package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +252 -158
  139. package/src/LinearApolloDisplay/stateModel/rendering.ts +103 -21
  140. package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +3 -3
  141. package/src/LinearApolloReferenceSequenceDisplay/stateModel/base.ts +20 -2
  142. package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +7 -2
  143. package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +8 -13
  144. package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +1 -1
  145. package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +4 -3
  146. package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +1 -1
  147. package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +2 -1
  148. package/src/OntologyManager/OntologyStore/__snapshots__/index.test.ts.snap +18262 -8519
  149. package/src/OntologyManager/OntologyStore/fulltext.ts +1 -2
  150. package/src/OntologyManager/OntologyStore/index.test.ts +5 -2
  151. package/src/OntologyManager/OntologyStore/index.ts +7 -8
  152. package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +2 -2
  153. package/src/OntologyManager/OntologyStore/types.ts +27 -0
  154. package/src/OntologyManager/index.ts +15 -26
  155. package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +4 -5
  156. package/src/components/AddChildFeature.tsx +15 -8
  157. package/src/components/ColorFeature.tsx +167 -0
  158. package/src/components/CreateApolloAnnotation.tsx +35 -9
  159. package/src/components/DownloadGFF3.tsx +92 -121
  160. package/src/components/DuplicateTranscript.tsx +10 -0
  161. package/src/components/ViewChangeLog.tsx +123 -83
  162. package/src/components/ViewCheckResults.tsx +15 -73
  163. package/src/components/index.ts +1 -1
  164. package/src/config.ts +37 -19
  165. package/src/extensions/annotationFromJBrowseFeature.test.ts +1 -1
  166. package/src/extensions/annotationFromJBrowseFeature.ts +91 -63
  167. package/src/extensions/annotationFromPileup.ts +40 -40
  168. package/src/index.ts +45 -1
  169. package/src/makeDisplayComponent.tsx +10 -3
  170. package/src/menus/Icons.tsx +49 -0
  171. package/src/menus/topLevelMenu.ts +24 -96
  172. package/src/session/ClientDataStore.ts +16 -17
  173. package/src/session/changeHandlers.ts +261 -0
  174. package/src/session/session.ts +77 -46
  175. package/src/util/annotationFeatureUtils.ts +29 -1
  176. package/src/util/glyphUtils.ts +74 -31
  177. package/src/util/index.ts +0 -1
  178. package/dist/BackendDrivers/DesktopFileDriver.d.ts +0 -160
  179. package/dist/BackendDrivers/DesktopFileDriver.d.ts.map +0 -1
  180. package/dist/BackendDrivers/InMemoryFileDriver.d.ts +0 -162
  181. package/dist/BackendDrivers/InMemoryFileDriver.d.ts.map +0 -1
  182. package/dist/LinearApolloDisplay/glyphs/index.d.ts +0 -4
  183. package/dist/LinearApolloDisplay/glyphs/index.d.ts.map +0 -1
  184. package/dist/components/OpenLocalFile.d.ts +0 -15
  185. package/dist/components/OpenLocalFile.d.ts.map +0 -1
  186. package/dist/util/loadAssemblyIntoClient.d.ts +0 -5
  187. package/dist/util/loadAssemblyIntoClient.d.ts.map +0 -1
  188. package/src/BackendDrivers/DesktopFileDriver.ts +0 -184
  189. package/src/BackendDrivers/InMemoryFileDriver.ts +0 -107
  190. package/src/LinearApolloDisplay/glyphs/index.ts +0 -3
  191. package/src/components/OpenLocalFile.tsx +0 -189
  192. package/src/util/loadAssemblyIntoClient.ts +0 -94
@@ -1,231 +1,92 @@
1
1
  import type { AnnotationFeature } from '@apollo-annotation/mst'
2
2
  import type { MenuItem } from '@jbrowse/core/ui'
3
+ import type { ContentBlock } from '@jbrowse/core/util/blockTypes'
3
4
  import { alpha } from '@mui/material'
4
5
 
5
- import {
6
- type MousePosition,
7
- type MousePositionWithFeature,
8
- getContextMenuItemsForFeature,
9
- isMousePositionWithFeature,
10
- isSelectedFeature,
11
- } from '../../util'
6
+ import { getContextMenuItemsForFeature, isSelectedFeature } from '../../util'
12
7
  import type { LinearApolloDisplay } from '../stateModel'
13
8
  import type { LinearApolloDisplayMouseEvents } from '../stateModel/mouseEvents'
14
- import type { LinearApolloDisplayRendering } from '../stateModel/rendering'
15
- import type { CanvasMouseEvent } from '../types'
16
9
 
17
- import type { Glyph } from './Glyph'
10
+ import type { Glyph, OverlayType } from './Glyph'
11
+ import { drawOverlayBox, getFeatureBox, strokeRectInner } from './util'
18
12
 
19
- function drawBoxOutline(
13
+ function draw(
14
+ display: LinearApolloDisplay,
20
15
  ctx: CanvasRenderingContext2D,
21
- x: number,
22
- y: number,
23
- width: number,
24
- height: number,
25
- color: string,
16
+ feature: AnnotationFeature,
17
+ row: number,
18
+ rowInFeature: number,
19
+ block: ContentBlock,
26
20
  ) {
27
- drawBox(ctx, x, y, width, height, color)
28
- if (width <= 2) {
29
- return
21
+ const { selectedFeature, theme } = display
22
+ const [top, left, width, height] = getFeatureBox(display, feature, row, block)
23
+ if (width > 2) {
24
+ ctx.fillStyle = theme.palette.background.default
25
+ ctx.fillRect(left, top, width, height)
26
+ }
27
+ strokeRectInner(ctx, left, top, width, height, theme.palette.text.primary)
28
+ if (isSelectedFeature(feature, selectedFeature)) {
29
+ drawOverlay(display, ctx, feature, row, block, 'select')
30
30
  }
31
- ctx.clearRect(x + 1, y + 1, width - 2, height - 2)
32
- }
33
-
34
- function drawBoxFill(
35
- ctx: CanvasRenderingContext2D,
36
- x: number,
37
- y: number,
38
- width: number,
39
- height: number,
40
- color: string,
41
- ) {
42
- drawBox(ctx, x + 1, y + 1, width - 2, height - 2, color)
43
31
  }
44
32
 
45
- function draw(
46
- ctx: CanvasRenderingContext2D,
33
+ function drawOverlay(
34
+ display: LinearApolloDisplay,
35
+ overlayCtx: CanvasRenderingContext2D,
47
36
  feature: AnnotationFeature,
48
37
  row: number,
49
- stateModel: LinearApolloDisplayRendering,
50
- displayedRegionIndex: number,
38
+ block: ContentBlock,
39
+ overlayType: OverlayType,
51
40
  ) {
52
- const { apolloRowHeight: heightPx, lgv, selectedFeature, theme } = stateModel
53
- const { bpPerPx, displayedRegions, offsetPx } = lgv
54
- const displayedRegion = displayedRegions[displayedRegionIndex]
55
- const minX =
56
- (lgv.bpToPx({
57
- refName: displayedRegion.refName,
58
- coord: feature.min,
59
- regionNumber: displayedRegionIndex,
60
- })?.offsetPx ?? 0) - offsetPx
61
- const { reversed } = displayedRegion
62
- const widthPx = feature.length / bpPerPx
63
- const startPx = reversed ? minX - widthPx : minX
64
- const top = row * heightPx
65
- const backgroundColor = theme.palette.background.default
66
- const textColor = theme.palette.text.primary
67
- const featureBox: [number, number, number, number] = [
68
- startPx,
41
+ const [top, left, width, height] = getFeatureBox(display, feature, row, block)
42
+ drawOverlayBox(
43
+ display,
44
+ overlayCtx,
45
+ left,
69
46
  top,
70
- widthPx,
71
- heightPx,
72
- ]
73
- drawBoxOutline(ctx, ...featureBox, textColor)
74
- if (widthPx <= 2) {
75
- // Don't need to add details if the feature is too small to see them
76
- return
77
- }
78
-
79
- drawBoxFill(ctx, startPx, top, widthPx, heightPx, backgroundColor)
80
- if (isSelectedFeature(feature, selectedFeature)) {
81
- drawHighlight(stateModel, ctx, feature, true)
82
- }
47
+ width,
48
+ height,
49
+ feature,
50
+ overlayType,
51
+ )
83
52
  }
84
53
 
85
54
  function drawDragPreview(
86
- stateModel: LinearApolloDisplay,
55
+ display: LinearApolloDisplay,
87
56
  overlayCtx: CanvasRenderingContext2D,
57
+ feature: AnnotationFeature,
58
+ row: number,
59
+ block: ContentBlock,
88
60
  ) {
89
- const { apolloDragging, apolloRowHeight, lgv, theme } = stateModel
90
- const { bpPerPx, displayedRegions, offsetPx } = lgv
61
+ const { apolloDragging, theme } = display
91
62
  if (!apolloDragging) {
92
63
  return
93
64
  }
94
- const { current, edge, feature, start } = apolloDragging
65
+ const { current, start } = apolloDragging
66
+ const min = Math.min(current.bp, start.bp)
67
+ const max = Math.max(current.bp, start.bp)
95
68
 
96
- const row = Math.floor(start.y / apolloRowHeight)
97
- const region = displayedRegions[start.regionNumber]
98
- const rowCount = getRowCount(feature)
69
+ const [top, left, width, height] = getFeatureBox(
70
+ display,
71
+ { min, max },
72
+ row,
73
+ block,
74
+ )
99
75
 
100
- const featureEdgeBp = region.reversed
101
- ? region.end - feature[edge]
102
- : feature[edge] - region.start
103
- const featureEdgePx = featureEdgeBp / bpPerPx - offsetPx
104
- const rectX = Math.min(current.x, featureEdgePx)
105
- const rectY = row * apolloRowHeight
106
- const rectWidth = Math.abs(current.x - featureEdgePx)
107
- const rectHeight = apolloRowHeight * rowCount
108
- overlayCtx.strokeStyle = theme.palette.info.main
109
- overlayCtx.setLineDash([6])
110
- overlayCtx.strokeRect(rectX, rectY, rectWidth, rectHeight)
111
76
  overlayCtx.fillStyle = alpha(theme.palette.info.main, 0.2)
112
- overlayCtx.fillRect(rectX, rectY, rectWidth, rectHeight)
113
- }
114
-
115
- function drawHighlight(
116
- stateModel: LinearApolloDisplayRendering,
117
- ctx: CanvasRenderingContext2D,
118
- feature: AnnotationFeature,
119
- selected = false,
120
- ) {
121
- const { apolloRowHeight, lgv, theme } = stateModel
122
- const position = stateModel.getFeatureLayoutPosition(feature)
123
- if (!position) {
124
- return
125
- }
126
- const { bpPerPx, displayedRegions, offsetPx } = lgv
127
- const { layoutIndex, layoutRow } = position
128
- const displayedRegion = displayedRegions[layoutIndex]
129
- const { refName, reversed } = displayedRegion
130
- const { length, max, min } = feature
131
- const startPx =
132
- (lgv.bpToPx({
133
- refName,
134
- coord: reversed ? max : min,
135
- regionNumber: layoutIndex,
136
- })?.offsetPx ?? 0) - offsetPx
137
- const top = layoutRow * apolloRowHeight
138
- const widthPx = length / bpPerPx
139
- ctx.fillStyle = selected
140
- ? theme.palette.action.disabled
141
- : theme.palette.action.focus
142
- ctx.fillRect(startPx, top, widthPx, apolloRowHeight)
143
- }
77
+ overlayCtx.fillRect(left, top, width, height)
144
78
 
145
- function drawHover(
146
- stateModel: LinearApolloDisplay,
147
- ctx: CanvasRenderingContext2D,
148
- ) {
149
- const { hoveredFeature } = stateModel
150
- if (!hoveredFeature) {
151
- return
152
- }
153
- drawHighlight(stateModel, ctx, hoveredFeature.feature)
79
+ overlayCtx.setLineDash([6])
80
+ strokeRectInner(overlayCtx, left, top, width, height, theme.palette.info.main)
154
81
  }
155
82
 
156
- function drawTooltip(
157
- display: LinearApolloDisplayMouseEvents,
158
- context: CanvasRenderingContext2D,
159
- ): void {
160
- const { hoveredFeature, apolloRowHeight, lgv, theme } = display
161
- if (!hoveredFeature) {
162
- return
163
- }
164
- const { feature } = hoveredFeature
165
- const position = display.getFeatureLayoutPosition(feature)
166
- if (!position) {
167
- return
168
- }
169
- const { featureRow, layoutIndex, layoutRow } = position
170
- const { bpPerPx, displayedRegions, offsetPx } = lgv
171
- const displayedRegion = displayedRegions[layoutIndex]
172
- const { refName, reversed } = displayedRegion
173
-
174
- let location = 'Loc: '
175
-
176
- const { length, max, min } = feature
177
- location += `${min + 1}–${max}`
178
-
179
- let startPx =
180
- (lgv.bpToPx({
181
- refName,
182
- coord: reversed ? max : min,
183
- regionNumber: layoutIndex,
184
- })?.offsetPx ?? 0) - offsetPx
185
- const top = (layoutRow + featureRow) * apolloRowHeight
186
- const widthPx = length / bpPerPx
187
-
188
- const featureType = `Type: ${feature.type}`
189
- const { attributes } = feature
190
- const featureName = attributes.get('gff_name')?.find((name) => name !== '')
191
- const textWidth = [
192
- context.measureText(featureType).width,
193
- context.measureText(location).width,
194
- ]
195
- if (featureName) {
196
- textWidth.push(context.measureText(`Name: ${featureName}`).width)
83
+ function getLayout(display: LinearApolloDisplay, feature: AnnotationFeature) {
84
+ return {
85
+ byFeature: new Map([[feature._id, 0]]),
86
+ byRow: [[{ feature, rowInFeature: 0 }]],
87
+ min: feature.min,
88
+ max: feature.max,
197
89
  }
198
- const maxWidth = Math.max(...textWidth)
199
-
200
- startPx = startPx + widthPx + 5
201
- context.fillStyle = alpha(theme.palette.text.primary, 0.7)
202
- context.fillRect(startPx, top, maxWidth + 4, textWidth.length === 3 ? 45 : 35)
203
- context.beginPath()
204
- context.moveTo(startPx, top)
205
- context.lineTo(startPx - 5, top + 5)
206
- context.lineTo(startPx, top + 10)
207
- context.fill()
208
- context.fillStyle = theme.palette.background.default
209
- let textTop = top + 12
210
- context.fillText(featureType, startPx + 2, textTop)
211
- if (featureName) {
212
- textTop = textTop + 12
213
- context.fillText(`Name: ${featureName}`, startPx + 2, textTop)
214
- }
215
- textTop = textTop + 12
216
- context.fillText(location, startPx + 2, textTop)
217
- }
218
-
219
- export function drawBox(
220
- ctx: CanvasRenderingContext2D,
221
- x: number,
222
- y: number,
223
- width: number,
224
- height: number,
225
- color: string,
226
- ) {
227
- ctx.fillStyle = color
228
- ctx.fillRect(x, y, width, height)
229
90
  }
230
91
 
231
92
  function getContextMenuItems(
@@ -238,114 +99,11 @@ function getContextMenuItems(
238
99
  return getContextMenuItemsForFeature(display, hoveredFeature.feature)
239
100
  }
240
101
 
241
- function getFeatureFromLayout(
242
- feature: AnnotationFeature,
243
- _bp: number,
244
- _row: number,
245
- ): AnnotationFeature {
246
- return feature
247
- }
248
-
249
- function getRowCount(_feature: AnnotationFeature) {
250
- return 1
251
- }
252
-
253
- function getRowForFeature(
254
- _feature: AnnotationFeature,
255
- _childFeature: AnnotationFeature,
256
- ): number | undefined {
257
- return 0
258
- }
259
-
260
- function onMouseDown(
261
- stateModel: LinearApolloDisplay,
262
- currentMousePosition: MousePositionWithFeature,
263
- event: CanvasMouseEvent,
264
- ) {
265
- const { feature } = currentMousePosition
266
- // swallow the mouseDown if we are on the edge of the feature so that we
267
- // don't start dragging the view if we try to drag the feature edge
268
- const edge = isMouseOnFeatureEdge(currentMousePosition, feature, stateModel)
269
- if (edge) {
270
- event.stopPropagation()
271
- stateModel.startDrag(currentMousePosition, feature, edge)
272
- }
273
- }
274
-
275
- function onMouseLeave(): void {
276
- return
277
- }
278
-
279
- function onMouseMove(
280
- stateModel: LinearApolloDisplay,
281
- mousePosition: MousePosition,
282
- ) {
283
- if (isMousePositionWithFeature(mousePosition)) {
284
- const { feature, bp } = mousePosition
285
- stateModel.setHoveredFeature({ feature, bp })
286
- const edge = isMouseOnFeatureEdge(mousePosition, feature, stateModel)
287
- if (edge) {
288
- stateModel.setCursor('col-resize')
289
- return
290
- }
291
- }
292
- stateModel.setCursor()
293
- }
294
-
295
- function onMouseUp(
296
- stateModel: LinearApolloDisplay,
297
- mousePosition: MousePosition,
298
- ) {
299
- if (stateModel.apolloDragging) {
300
- return
301
- }
302
- const { feature } = mousePosition
303
- if (!feature) {
304
- return
305
- }
306
- stateModel.setSelectedFeature(feature)
307
- stateModel.showFeatureDetailsWidget(feature)
308
- }
309
-
310
- /** @returns undefined if mouse not on the edge of this feature, otherwise 'start' or 'end' depending on which edge */
311
- function isMouseOnFeatureEdge(
312
- mousePosition: MousePosition,
313
- feature: AnnotationFeature,
314
- stateModel: LinearApolloDisplay,
315
- ) {
316
- const { refName, regionNumber, x } = mousePosition
317
- const { lgv } = stateModel
318
- const { offsetPx } = lgv
319
- const minPxInfo = lgv.bpToPx({ refName, coord: feature.min, regionNumber })
320
- const maxPxInfo = lgv.bpToPx({ refName, coord: feature.max, regionNumber })
321
- if (minPxInfo !== undefined && maxPxInfo !== undefined) {
322
- const minPx = minPxInfo.offsetPx - offsetPx
323
- const maxPx = maxPxInfo.offsetPx - offsetPx
324
- if (Math.abs(maxPx - minPx) < 8) {
325
- return
326
- }
327
- if (Math.abs(minPx - x) < 4) {
328
- return 'min'
329
- }
330
- if (Math.abs(maxPx - x) < 4) {
331
- return 'max'
332
- }
333
- }
334
- return
335
- }
336
-
337
102
  export const boxGlyph: Glyph = {
338
103
  draw,
339
104
  drawDragPreview,
340
- drawHover,
341
- drawTooltip,
342
- getContextMenuItemsForFeature,
105
+ drawOverlay,
343
106
  getContextMenuItems,
344
- getFeatureFromLayout,
345
- getRowCount,
346
- getRowForFeature,
347
- onMouseDown,
348
- onMouseLeave,
349
- onMouseMove,
350
- onMouseUp,
107
+ getLayout,
108
+ isDraggable: true,
351
109
  }
@@ -0,0 +1,145 @@
1
+ import type {
2
+ AnnotationFeature,
3
+ TranscriptPartCoding,
4
+ } from '@apollo-annotation/mst'
5
+ import type { MenuItem } from '@jbrowse/core/ui'
6
+ import { getFrame } from '@jbrowse/core/util'
7
+ import type { ContentBlock } from '@jbrowse/core/util/blockTypes'
8
+
9
+ import { isSelectedFeature } from '../../util'
10
+ import type { LinearApolloDisplay } from '../stateModel'
11
+
12
+ import { boxGlyph } from './BoxGlyph'
13
+ import type { Glyph, OverlayType } from './Glyph'
14
+ import { drawOverlayBox, getFeatureBox, strokeRectInner } from './util'
15
+
16
+ function drawCDSLocation(
17
+ display: LinearApolloDisplay,
18
+ ctx: CanvasRenderingContext2D,
19
+ cdsLocation: TranscriptPartCoding,
20
+ strand: 1 | -1 | undefined,
21
+ row: number,
22
+ block: ContentBlock,
23
+ ) {
24
+ const { apolloRowHeight, canvasPatterns, theme } = display
25
+ const [top, left, width] = getFeatureBox(display, cdsLocation, row, block)
26
+ const halfHeight = Math.round(apolloRowHeight / 2)
27
+ if (width > 2) {
28
+ const frame = getFrame(
29
+ cdsLocation.min,
30
+ cdsLocation.max,
31
+ strand ?? 1,
32
+ cdsLocation.phase,
33
+ )
34
+ const frameColor = theme.palette.framesCDS.at(frame)?.main
35
+ ctx.fillStyle = frameColor ?? 'black'
36
+ ctx.fillRect(left, top, width, apolloRowHeight)
37
+ const forwardFill = canvasPatterns.forward
38
+ const backwardFill = canvasPatterns.backward
39
+ if (forwardFill && backwardFill && strand) {
40
+ const { reversed } = block
41
+ const reversal = reversed ? -1 : 1
42
+ const [topFill, bottomFill] =
43
+ strand * reversal === 1
44
+ ? [forwardFill, backwardFill]
45
+ : [backwardFill, forwardFill]
46
+ ctx.fillStyle = topFill
47
+ ctx.fillRect(left, top, width, halfHeight)
48
+ ctx.fillStyle = bottomFill
49
+ ctx.fillRect(left, top + halfHeight, width, halfHeight)
50
+ }
51
+ }
52
+ strokeRectInner(
53
+ ctx,
54
+ left,
55
+ top,
56
+ width,
57
+ apolloRowHeight,
58
+ theme.palette.text.primary,
59
+ )
60
+ }
61
+
62
+ function draw(
63
+ display: LinearApolloDisplay,
64
+ ctx: CanvasRenderingContext2D,
65
+ cds: AnnotationFeature,
66
+ row: number,
67
+ rowInFeature: number,
68
+ block: ContentBlock,
69
+ ) {
70
+ const transcript = cds.parent
71
+ if (!transcript) {
72
+ boxGlyph.draw(display, ctx, cds, row, 0, block)
73
+ return
74
+ }
75
+ const { cdsLocations } = transcript
76
+ const thisCDSLocations = cdsLocations.find((loc) => {
77
+ const min = loc.at(cds.strand === 1 ? 0 : -1)?.min
78
+ const max = loc.at(cds.strand === 1 ? -1 : 0)?.max
79
+ return cds.min === min && cds.max === max
80
+ })
81
+ if (!thisCDSLocations) {
82
+ return
83
+ }
84
+ for (const cdsLocation of thisCDSLocations) {
85
+ drawCDSLocation(display, ctx, cdsLocation, cds.strand, row, block)
86
+ }
87
+ const { selectedFeature } = display
88
+ if (isSelectedFeature(cds, selectedFeature)) {
89
+ drawOverlay(display, ctx, cds, row, block, 'select')
90
+ }
91
+ }
92
+
93
+ function drawOverlay(
94
+ display: LinearApolloDisplay,
95
+ overlayCtx: CanvasRenderingContext2D,
96
+ cds: AnnotationFeature,
97
+ row: number,
98
+ block: ContentBlock,
99
+ overlayType: OverlayType,
100
+ ) {
101
+ const { apolloRowHeight } = display
102
+ const [top, left, width] = getFeatureBox(display, cds, row, block)
103
+ const height = getRowCount() * apolloRowHeight
104
+ drawOverlayBox(
105
+ display,
106
+ overlayCtx,
107
+ left,
108
+ top,
109
+ width,
110
+ height,
111
+ cds,
112
+ overlayType,
113
+ )
114
+ }
115
+
116
+ function getLayout(display: LinearApolloDisplay, feature: AnnotationFeature) {
117
+ return {
118
+ byFeature: new Map([[feature._id, 0]]),
119
+ byRow: [[{ feature, rowInFeature: 0 }]],
120
+ min: feature.min,
121
+ max: feature.max,
122
+ }
123
+ }
124
+
125
+ function getRowCount() {
126
+ return 1
127
+ }
128
+
129
+ function getContextMenuItems(): MenuItem[] {
130
+ return []
131
+ }
132
+
133
+ // False positive here, none of these functions use "this"
134
+ /* eslint-disable @typescript-eslint/unbound-method */
135
+ const { drawDragPreview } = boxGlyph
136
+ /* eslint-enable @typescript-eslint/unbound-method */
137
+
138
+ export const cdsGlyph: Glyph = {
139
+ draw,
140
+ drawDragPreview,
141
+ drawOverlay,
142
+ getContextMenuItems,
143
+ getLayout,
144
+ isDraggable: true,
145
+ }