@jbrowse/plugin-linear-comparative-view 2.6.1 → 2.6.3

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 (209) hide show
  1. package/dist/LGVSyntenyDisplay/configSchemaF.d.ts +1 -3
  2. package/dist/LGVSyntenyDisplay/configSchemaF.js +0 -1
  3. package/dist/LGVSyntenyDisplay/index.js +0 -1
  4. package/dist/LGVSyntenyDisplay/model.d.ts +17 -76
  5. package/dist/LGVSyntenyDisplay/model.js +22 -4
  6. package/dist/LaunchLinearSyntenyView.js +0 -1
  7. package/dist/LinearComparativeDisplay/configSchemaF.js +0 -1
  8. package/dist/LinearComparativeDisplay/index.js +0 -1
  9. package/dist/LinearComparativeDisplay/stateModelFactory.js +0 -1
  10. package/dist/LinearComparativeView/components/Header.js +11 -2
  11. package/dist/LinearComparativeView/components/LinearComparativeView.js +0 -1
  12. package/dist/LinearComparativeView/components/Rubberband.js +11 -33
  13. package/dist/LinearComparativeView/components/VerticalGuide.d.ts +8 -0
  14. package/dist/LinearComparativeView/components/VerticalGuide.js +33 -0
  15. package/dist/LinearComparativeView/index.js +0 -1
  16. package/dist/LinearComparativeView/model.d.ts +9 -15
  17. package/dist/LinearComparativeView/model.js +0 -1
  18. package/dist/LinearReadVsRef/LinearReadVsRef.js +0 -1
  19. package/dist/LinearReadVsRef/index.js +0 -1
  20. package/dist/LinearSyntenyDisplay/afterAttach.js +0 -1
  21. package/dist/LinearSyntenyDisplay/components/Component.js +0 -1
  22. package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +0 -1
  23. package/dist/LinearSyntenyDisplay/components/SyntenyTooltip.js +0 -1
  24. package/dist/LinearSyntenyDisplay/components/util.js +0 -1
  25. package/dist/LinearSyntenyDisplay/configSchemaF.js +0 -1
  26. package/dist/LinearSyntenyDisplay/drawSynteny.js +0 -1
  27. package/dist/LinearSyntenyDisplay/index.js +0 -1
  28. package/dist/LinearSyntenyDisplay/model.js +0 -1
  29. package/dist/LinearSyntenyView/components/ExportSvgDialog.js +0 -1
  30. package/dist/LinearSyntenyView/components/Icons.js +0 -1
  31. package/dist/LinearSyntenyView/components/ImportCustomTrack.js +0 -1
  32. package/dist/LinearSyntenyView/components/ImportForm.js +0 -1
  33. package/dist/LinearSyntenyView/components/ImportSyntenyTrackSelector.js +0 -1
  34. package/dist/LinearSyntenyView/components/LinearSyntenyView.js +0 -1
  35. package/dist/LinearSyntenyView/index.js +0 -1
  36. package/dist/LinearSyntenyView/model.d.ts +9 -9
  37. package/dist/LinearSyntenyView/model.js +0 -1
  38. package/dist/LinearSyntenyView/svgcomponents/SVGBackground.js +2 -2
  39. package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +0 -1
  40. package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.js +0 -1
  41. package/dist/SyntenyFeatureDetail/index.js +0 -1
  42. package/dist/SyntenyTrack/configSchema.js +0 -1
  43. package/dist/SyntenyTrack/index.js +0 -1
  44. package/dist/index.js +0 -1
  45. package/dist/util.js +0 -1
  46. package/esm/LGVSyntenyDisplay/configSchemaF.d.ts +1 -3
  47. package/esm/LGVSyntenyDisplay/configSchemaF.js +0 -1
  48. package/esm/LGVSyntenyDisplay/index.js +0 -1
  49. package/esm/LGVSyntenyDisplay/model.d.ts +17 -76
  50. package/esm/LGVSyntenyDisplay/model.js +23 -5
  51. package/esm/LaunchLinearSyntenyView.js +0 -1
  52. package/esm/LinearComparativeDisplay/configSchemaF.js +0 -1
  53. package/esm/LinearComparativeDisplay/index.js +0 -1
  54. package/esm/LinearComparativeDisplay/stateModelFactory.js +0 -1
  55. package/esm/LinearComparativeView/components/Header.js +11 -2
  56. package/esm/LinearComparativeView/components/LinearComparativeView.js +0 -1
  57. package/esm/LinearComparativeView/components/Rubberband.js +8 -33
  58. package/esm/LinearComparativeView/components/VerticalGuide.d.ts +8 -0
  59. package/esm/LinearComparativeView/components/VerticalGuide.js +28 -0
  60. package/esm/LinearComparativeView/index.js +0 -1
  61. package/esm/LinearComparativeView/model.d.ts +9 -15
  62. package/esm/LinearComparativeView/model.js +0 -1
  63. package/esm/LinearReadVsRef/LinearReadVsRef.js +0 -1
  64. package/esm/LinearReadVsRef/index.js +0 -1
  65. package/esm/LinearSyntenyDisplay/afterAttach.js +0 -1
  66. package/esm/LinearSyntenyDisplay/components/Component.js +0 -1
  67. package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js +0 -1
  68. package/esm/LinearSyntenyDisplay/components/SyntenyTooltip.js +0 -1
  69. package/esm/LinearSyntenyDisplay/components/util.js +0 -1
  70. package/esm/LinearSyntenyDisplay/configSchemaF.js +0 -1
  71. package/esm/LinearSyntenyDisplay/drawSynteny.js +0 -1
  72. package/esm/LinearSyntenyDisplay/index.js +0 -1
  73. package/esm/LinearSyntenyDisplay/model.js +0 -1
  74. package/esm/LinearSyntenyView/components/ExportSvgDialog.js +0 -1
  75. package/esm/LinearSyntenyView/components/Icons.js +0 -1
  76. package/esm/LinearSyntenyView/components/ImportCustomTrack.js +0 -1
  77. package/esm/LinearSyntenyView/components/ImportForm.js +0 -1
  78. package/esm/LinearSyntenyView/components/ImportSyntenyTrackSelector.js +0 -1
  79. package/esm/LinearSyntenyView/components/LinearSyntenyView.js +0 -1
  80. package/esm/LinearSyntenyView/index.js +0 -1
  81. package/esm/LinearSyntenyView/model.d.ts +9 -9
  82. package/esm/LinearSyntenyView/model.js +0 -1
  83. package/esm/LinearSyntenyView/svgcomponents/SVGBackground.js +2 -2
  84. package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js +0 -1
  85. package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.js +0 -1
  86. package/esm/SyntenyFeatureDetail/index.js +0 -1
  87. package/esm/SyntenyTrack/configSchema.js +0 -1
  88. package/esm/SyntenyTrack/index.js +0 -1
  89. package/esm/index.js +0 -1
  90. package/esm/util.js +0 -1
  91. package/package.json +4 -4
  92. package/dist/LGVSyntenyDisplay/configSchemaF.js.map +0 -1
  93. package/dist/LGVSyntenyDisplay/index.js.map +0 -1
  94. package/dist/LGVSyntenyDisplay/model.js.map +0 -1
  95. package/dist/LaunchLinearSyntenyView.js.map +0 -1
  96. package/dist/LinearComparativeDisplay/configSchemaF.js.map +0 -1
  97. package/dist/LinearComparativeDisplay/index.js.map +0 -1
  98. package/dist/LinearComparativeDisplay/stateModelFactory.js.map +0 -1
  99. package/dist/LinearComparativeView/components/Header.js.map +0 -1
  100. package/dist/LinearComparativeView/components/LinearComparativeView.js.map +0 -1
  101. package/dist/LinearComparativeView/components/Rubberband.js.map +0 -1
  102. package/dist/LinearComparativeView/index.js.map +0 -1
  103. package/dist/LinearComparativeView/model.js.map +0 -1
  104. package/dist/LinearReadVsRef/LinearReadVsRef.js.map +0 -1
  105. package/dist/LinearReadVsRef/index.js.map +0 -1
  106. package/dist/LinearSyntenyDisplay/afterAttach.js.map +0 -1
  107. package/dist/LinearSyntenyDisplay/components/Component.js.map +0 -1
  108. package/dist/LinearSyntenyDisplay/components/LinearSyntenyRendering.js.map +0 -1
  109. package/dist/LinearSyntenyDisplay/components/SyntenyTooltip.js.map +0 -1
  110. package/dist/LinearSyntenyDisplay/components/util.js.map +0 -1
  111. package/dist/LinearSyntenyDisplay/configSchemaF.js.map +0 -1
  112. package/dist/LinearSyntenyDisplay/drawSynteny.js.map +0 -1
  113. package/dist/LinearSyntenyDisplay/index.js.map +0 -1
  114. package/dist/LinearSyntenyDisplay/model.js.map +0 -1
  115. package/dist/LinearSyntenyView/components/ExportSvgDialog.js.map +0 -1
  116. package/dist/LinearSyntenyView/components/Icons.js.map +0 -1
  117. package/dist/LinearSyntenyView/components/ImportCustomTrack.js.map +0 -1
  118. package/dist/LinearSyntenyView/components/ImportForm.js.map +0 -1
  119. package/dist/LinearSyntenyView/components/ImportSyntenyTrackSelector.js.map +0 -1
  120. package/dist/LinearSyntenyView/components/LinearSyntenyView.js.map +0 -1
  121. package/dist/LinearSyntenyView/index.js.map +0 -1
  122. package/dist/LinearSyntenyView/model.js.map +0 -1
  123. package/dist/LinearSyntenyView/svgcomponents/SVGBackground.js.map +0 -1
  124. package/dist/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js.map +0 -1
  125. package/dist/SyntenyFeatureDetail/SyntenyFeatureDetail.js.map +0 -1
  126. package/dist/SyntenyFeatureDetail/index.js.map +0 -1
  127. package/dist/SyntenyTrack/configSchema.js.map +0 -1
  128. package/dist/SyntenyTrack/index.js.map +0 -1
  129. package/dist/index.js.map +0 -1
  130. package/dist/util.js.map +0 -1
  131. package/esm/LGVSyntenyDisplay/configSchemaF.js.map +0 -1
  132. package/esm/LGVSyntenyDisplay/index.js.map +0 -1
  133. package/esm/LGVSyntenyDisplay/model.js.map +0 -1
  134. package/esm/LaunchLinearSyntenyView.js.map +0 -1
  135. package/esm/LinearComparativeDisplay/configSchemaF.js.map +0 -1
  136. package/esm/LinearComparativeDisplay/index.js.map +0 -1
  137. package/esm/LinearComparativeDisplay/stateModelFactory.js.map +0 -1
  138. package/esm/LinearComparativeView/components/Header.js.map +0 -1
  139. package/esm/LinearComparativeView/components/LinearComparativeView.js.map +0 -1
  140. package/esm/LinearComparativeView/components/Rubberband.js.map +0 -1
  141. package/esm/LinearComparativeView/index.js.map +0 -1
  142. package/esm/LinearComparativeView/model.js.map +0 -1
  143. package/esm/LinearReadVsRef/LinearReadVsRef.js.map +0 -1
  144. package/esm/LinearReadVsRef/index.js.map +0 -1
  145. package/esm/LinearSyntenyDisplay/afterAttach.js.map +0 -1
  146. package/esm/LinearSyntenyDisplay/components/Component.js.map +0 -1
  147. package/esm/LinearSyntenyDisplay/components/LinearSyntenyRendering.js.map +0 -1
  148. package/esm/LinearSyntenyDisplay/components/SyntenyTooltip.js.map +0 -1
  149. package/esm/LinearSyntenyDisplay/components/util.js.map +0 -1
  150. package/esm/LinearSyntenyDisplay/configSchemaF.js.map +0 -1
  151. package/esm/LinearSyntenyDisplay/drawSynteny.js.map +0 -1
  152. package/esm/LinearSyntenyDisplay/index.js.map +0 -1
  153. package/esm/LinearSyntenyDisplay/model.js.map +0 -1
  154. package/esm/LinearSyntenyView/components/ExportSvgDialog.js.map +0 -1
  155. package/esm/LinearSyntenyView/components/Icons.js.map +0 -1
  156. package/esm/LinearSyntenyView/components/ImportCustomTrack.js.map +0 -1
  157. package/esm/LinearSyntenyView/components/ImportForm.js.map +0 -1
  158. package/esm/LinearSyntenyView/components/ImportSyntenyTrackSelector.js.map +0 -1
  159. package/esm/LinearSyntenyView/components/LinearSyntenyView.js.map +0 -1
  160. package/esm/LinearSyntenyView/index.js.map +0 -1
  161. package/esm/LinearSyntenyView/model.js.map +0 -1
  162. package/esm/LinearSyntenyView/svgcomponents/SVGBackground.js.map +0 -1
  163. package/esm/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.js.map +0 -1
  164. package/esm/SyntenyFeatureDetail/SyntenyFeatureDetail.js.map +0 -1
  165. package/esm/SyntenyFeatureDetail/index.js.map +0 -1
  166. package/esm/SyntenyTrack/configSchema.js.map +0 -1
  167. package/esm/SyntenyTrack/index.js.map +0 -1
  168. package/esm/index.js.map +0 -1
  169. package/esm/util.js.map +0 -1
  170. package/src/LGVSyntenyDisplay/configSchemaF.ts +0 -22
  171. package/src/LGVSyntenyDisplay/index.ts +0 -20
  172. package/src/LGVSyntenyDisplay/model.ts +0 -177
  173. package/src/LaunchLinearSyntenyView.ts +0 -86
  174. package/src/LinearComparativeDisplay/configSchemaF.ts +0 -22
  175. package/src/LinearComparativeDisplay/index.ts +0 -21
  176. package/src/LinearComparativeDisplay/stateModelFactory.ts +0 -212
  177. package/src/LinearComparativeView/components/Header.tsx +0 -103
  178. package/src/LinearComparativeView/components/LinearComparativeView.tsx +0 -152
  179. package/src/LinearComparativeView/components/Rubberband.tsx +0 -329
  180. package/src/LinearComparativeView/index.ts +0 -15
  181. package/src/LinearComparativeView/model.ts +0 -395
  182. package/src/LinearReadVsRef/LinearReadVsRef.tsx +0 -360
  183. package/src/LinearReadVsRef/index.ts +0 -58
  184. package/src/LinearSyntenyDisplay/afterAttach.ts +0 -149
  185. package/src/LinearSyntenyDisplay/components/Component.tsx +0 -75
  186. package/src/LinearSyntenyDisplay/components/LinearSyntenyRendering.tsx +0 -200
  187. package/src/LinearSyntenyDisplay/components/SyntenyTooltip.tsx +0 -82
  188. package/src/LinearSyntenyDisplay/components/util.ts +0 -142
  189. package/src/LinearSyntenyDisplay/configSchemaF.ts +0 -38
  190. package/src/LinearSyntenyDisplay/drawSynteny.ts +0 -266
  191. package/src/LinearSyntenyDisplay/index.ts +0 -21
  192. package/src/LinearSyntenyDisplay/model.ts +0 -187
  193. package/src/LinearSyntenyView/components/ExportSvgDialog.tsx +0 -148
  194. package/src/LinearSyntenyView/components/Icons.tsx +0 -24
  195. package/src/LinearSyntenyView/components/ImportCustomTrack.tsx +0 -262
  196. package/src/LinearSyntenyView/components/ImportForm.tsx +0 -221
  197. package/src/LinearSyntenyView/components/ImportSyntenyTrackSelector.tsx +0 -82
  198. package/src/LinearSyntenyView/components/LinearSyntenyView.tsx +0 -20
  199. package/src/LinearSyntenyView/index.ts +0 -15
  200. package/src/LinearSyntenyView/model.test.ts +0 -1605
  201. package/src/LinearSyntenyView/model.ts +0 -169
  202. package/src/LinearSyntenyView/svgcomponents/SVGBackground.tsx +0 -21
  203. package/src/LinearSyntenyView/svgcomponents/SVGLinearSyntenyView.tsx +0 -176
  204. package/src/SyntenyFeatureDetail/SyntenyFeatureDetail.tsx +0 -64
  205. package/src/SyntenyFeatureDetail/index.ts +0 -36
  206. package/src/SyntenyTrack/configSchema.ts +0 -23
  207. package/src/SyntenyTrack/index.tsx +0 -15
  208. package/src/index.tsx +0 -42
  209. package/src/util.ts +0 -124
@@ -1,266 +0,0 @@
1
- import { doesIntersect2, getContainingView } from '@jbrowse/core/util'
2
- import { LinearSyntenyViewModel } from '../LinearSyntenyView/model'
3
- import { LinearSyntenyDisplayModel } from './model'
4
- import { draw, drawMatchSimple } from './components/util'
5
-
6
- export const MAX_COLOR_RANGE = 255 * 255 * 255 // max color range
7
-
8
- function makeColor(idx: number) {
9
- const r = Math.floor(idx / (255 * 255)) % 255
10
- const g = Math.floor(idx / 255) % 255
11
- const b = idx % 255
12
- return `rgb(${r},${g},${b})`
13
- }
14
-
15
- const colorMap = {
16
- I: '#ff03',
17
- N: '#0a03',
18
- D: '#00f3',
19
- X: 'brown',
20
- M: '#f003',
21
- '=': '#f003',
22
- }
23
-
24
- const lineLimit = 3
25
-
26
- const oobLimit = 1600
27
-
28
- export function getId(r: number, g: number, b: number, unitMultiplier: number) {
29
- return Math.floor((r * 255 * 255 + g * 255 + b - 1) / unitMultiplier)
30
- }
31
-
32
- export function drawRef(
33
- model: LinearSyntenyDisplayModel,
34
- ctx1: CanvasRenderingContext2D,
35
- ctx3?: CanvasRenderingContext2D,
36
- ) {
37
- const view = getContainingView(model) as LinearSyntenyViewModel
38
- const drawCurves = view.drawCurves
39
- const drawCIGAR = view.drawCIGAR
40
- const height = view.middleComparativeHeight
41
- const width = view.width
42
- const bpPerPxs = view.views.map(v => v.bpPerPx)
43
-
44
- if (ctx3) {
45
- ctx3.imageSmoothingEnabled = false
46
- }
47
-
48
- ctx1.beginPath()
49
- const featPos = model.featPositions
50
- const offsets = view.views.map(v => v.offsetPx)
51
-
52
- const unitMultiplier = Math.floor(MAX_COLOR_RANGE / featPos.length)
53
-
54
- // this loop is optimized to draw many thin lines with a single ctx.stroke
55
- // call, a separate loop below draws larger boxes
56
- ctx1.fillStyle = colorMap.M
57
- ctx1.strokeStyle = colorMap.M
58
- for (let i = 0; i < featPos.length; i++) {
59
- const { p11, p12, p21, p22 } = featPos[i]
60
- const x11 = p11.offsetPx - offsets[0]
61
- const x12 = p12.offsetPx - offsets[0]
62
- const x21 = p21.offsetPx - offsets[1]
63
- const x22 = p22.offsetPx - offsets[1]
64
- const l1 = Math.abs(x12 - x11)
65
- const l2 = Math.abs(x22 - x21)
66
- const y1 = 0
67
- const y2 = height
68
- const mid = (y2 - y1) / 2
69
-
70
- // drawing a line if the results are thin results in much less pixellation
71
- // than filling in a thin polygon
72
- if (
73
- l1 <= lineLimit &&
74
- l2 <= lineLimit &&
75
- x21 < width + oobLimit &&
76
- x21 > -oobLimit
77
- ) {
78
- ctx1.moveTo(x11, y1)
79
- if (drawCurves) {
80
- ctx1.bezierCurveTo(x11, mid, x21, mid, x21, y2)
81
- } else {
82
- ctx1.lineTo(x21, y2)
83
- }
84
- }
85
- }
86
- ctx1.stroke()
87
-
88
- // this loop only draws small lines as a polyline, the polyline calls
89
- // ctx.stroke once is much more efficient than calling stroke() many times
90
- ctx1.fillStyle = colorMap.M
91
- ctx1.strokeStyle = colorMap.M
92
- for (let i = 0; i < featPos.length; i++) {
93
- const { p11, p12, p21, p22, f, cigar } = featPos[i]
94
- const x11 = p11.offsetPx - offsets[0]
95
- const x12 = p12.offsetPx - offsets[0]
96
- const x21 = p21.offsetPx - offsets[1]
97
- const x22 = p22.offsetPx - offsets[1]
98
- const l1 = Math.abs(x12 - x11)
99
- const l2 = Math.abs(x22 - x21)
100
- const minX = Math.min(x21, x22)
101
- const maxX = Math.max(x21, x22)
102
- const y1 = 0
103
- const y2 = height
104
- const mid = (y2 - y1) / 2
105
-
106
- if (
107
- !(l1 <= lineLimit && l2 <= lineLimit) &&
108
- doesIntersect2(minX, maxX, -oobLimit, view.width + oobLimit)
109
- ) {
110
- const s1 = f.get('strand')
111
- const k1 = s1 === -1 ? x12 : x11
112
- const k2 = s1 === -1 ? x11 : x12
113
-
114
- // rev1/rev2 flip the direction of the CIGAR drawing in horizontally flipped
115
- // modes. somewhat heuristically determined, but tested for
116
- const rev1 = k1 < k2 ? 1 : -1
117
- const rev2 = (x21 < x22 ? 1 : -1) * s1
118
-
119
- // cx1/cx2 are the current x positions on top and bottom rows
120
- let cx1 = k1
121
- let cx2 = s1 === -1 ? x22 : x21
122
- if (cigar?.length && drawCIGAR) {
123
- // continuingFlag skips drawing commands on very small CIGAR features
124
- let continuingFlag = false
125
-
126
- // px1/px2 are the previous x positions on the top and bottom rows
127
- let px1 = 0
128
- let px2 = 0
129
- const unitMultiplier2 = Math.floor(MAX_COLOR_RANGE / cigar.length)
130
- for (let j = 0; j < cigar.length; j += 2) {
131
- const idx = j * unitMultiplier2 + 1
132
-
133
- const len = +cigar[j]
134
- const op = cigar[j + 1] as keyof typeof colorMap
135
-
136
- if (!continuingFlag) {
137
- px1 = cx1
138
- px2 = cx2
139
- }
140
-
141
- const d1 = len / bpPerPxs[0]
142
- const d2 = len / bpPerPxs[1]
143
-
144
- if (op === 'M' || op === '=' || op === 'X') {
145
- cx1 += d1 * rev1
146
- cx2 += d2 * rev2
147
- } else if (op === 'D' || op === 'N') {
148
- cx1 += d1 * rev1
149
- } else if (op === 'I') {
150
- cx2 += d2 * rev2
151
- }
152
-
153
- // check that we are even drawing in view here, e.g. that all
154
- // points are not all less than 0 or greater than width
155
- if (
156
- !(
157
- Math.max(px1, px2, cx1, cx2) < 0 ||
158
- Math.min(px1, px2, cx1, cx2) > width
159
- )
160
- ) {
161
- // if it is a small feature and not the last element of the
162
- // CIGAR (which could skip rendering it entire if we did turn
163
- // it on), then turn on continuing flag
164
- const isNotLast = j < cigar.length - 2
165
- if (
166
- Math.abs(cx1 - px1) <= 1 &&
167
- Math.abs(cx2 - px2) <= 1 &&
168
- isNotLast
169
- ) {
170
- continuingFlag = true
171
- } else {
172
- continuingFlag = false
173
-
174
- // allow rendering the dominant color when using continuing
175
- // flag if the last element of continuing was a large
176
- // feature, else just use match
177
- ctx1.fillStyle =
178
- colorMap[(continuingFlag && d1 > 1) || d2 > 1 ? op : 'M']
179
-
180
- draw(ctx1, px1, cx1, y1, cx2, px2, y2, mid, drawCurves)
181
- if (ctx3) {
182
- ctx3.fillStyle = makeColor(idx)
183
- draw(ctx3, px1, cx1, y1, cx2, px2, y2, mid, drawCurves)
184
- }
185
- }
186
- }
187
- }
188
- } else {
189
- draw(ctx1, x11, x12, y1, x22, x21, y2, mid, drawCurves)
190
- }
191
- }
192
- }
193
-
194
- // draw click map
195
- const ctx2 = model.clickMapCanvas?.getContext('2d')
196
- if (!ctx2) {
197
- return
198
- }
199
- ctx2.imageSmoothingEnabled = false
200
- ctx2.clearRect(0, 0, width, height)
201
- for (let i = 0; i < featPos.length; i++) {
202
- const feature = featPos[i]
203
- const idx = i * unitMultiplier + 1
204
- ctx2.fillStyle = makeColor(idx)
205
-
206
- // too many click map false positives with colored stroked lines
207
- drawMatchSimple({
208
- cb: ctx => ctx.fill(),
209
- feature,
210
- ctx: ctx2,
211
- drawCurves,
212
- offsets,
213
- oobLimit,
214
- viewWidth: view.width,
215
- hideTiny: true,
216
- height,
217
- })
218
- }
219
- }
220
-
221
- export function drawMouseoverSynteny(model: LinearSyntenyDisplayModel) {
222
- const { clickId, mouseoverId } = model
223
- const highResolutionScaling = 1
224
- const view = getContainingView(model) as LinearSyntenyViewModel
225
- const drawCurves = view.drawCurves
226
- const height = view.middleComparativeHeight
227
- const width = view.width
228
- const ctx = model.mouseoverCanvas?.getContext('2d')
229
- const offsets = view.views.map(v => v.offsetPx)
230
-
231
- if (!ctx) {
232
- return
233
- }
234
- ctx.resetTransform()
235
- ctx.scale(highResolutionScaling, highResolutionScaling)
236
- ctx.clearRect(0, 0, width, height)
237
- const feature1 = model.featMap[mouseoverId || '']
238
- if (feature1) {
239
- ctx.fillStyle = 'rgb(0,0,0,0.1)'
240
- drawMatchSimple({
241
- cb: ctx => ctx.fill(),
242
- feature: feature1,
243
- ctx,
244
- oobLimit,
245
- viewWidth: view.width,
246
- drawCurves,
247
- offsets,
248
- height,
249
- })
250
- }
251
- const feature2 = model.featMap[clickId || '']
252
- if (feature2) {
253
- ctx.strokeStyle = 'rgb(0, 0, 0, 0.9)'
254
-
255
- drawMatchSimple({
256
- cb: ctx => ctx.stroke(),
257
- feature: feature2,
258
- ctx,
259
- oobLimit,
260
- viewWidth: view.width,
261
- drawCurves,
262
- offsets,
263
- height,
264
- })
265
- }
266
- }
@@ -1,21 +0,0 @@
1
- import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'
2
- import PluginManager from '@jbrowse/core/PluginManager'
3
-
4
- // locals
5
- import configSchemaF from './configSchemaF'
6
- import stateModelFactory from './model'
7
- import { lazy } from 'react'
8
-
9
- export default (pluginManager: PluginManager) => {
10
- pluginManager.addDisplayType(() => {
11
- const configSchema = configSchemaF(pluginManager)
12
- return new DisplayType({
13
- name: 'LinearSyntenyDisplay',
14
- configSchema,
15
- stateModel: stateModelFactory(configSchema),
16
- trackType: 'SyntenyTrack',
17
- viewType: 'LinearSyntenyView',
18
- ReactComponent: lazy(() => import('./components/Component')),
19
- })
20
- })
21
- }
@@ -1,187 +0,0 @@
1
- import { types, Instance } from 'mobx-state-tree'
2
- import {
3
- getConf,
4
- ConfigurationReference,
5
- AnyConfigurationSchemaType,
6
- } from '@jbrowse/core/configuration'
7
- import { Feature } from '@jbrowse/core/util'
8
-
9
- // locals
10
- import baseModelFactory from '../LinearComparativeDisplay/stateModelFactory'
11
-
12
- interface Pos {
13
- offsetPx: number
14
- }
15
-
16
- interface FeatPos {
17
- p11: Pos
18
- p12: Pos
19
- p21: Pos
20
- p22: Pos
21
- f: Feature
22
- cigar: string[]
23
- }
24
-
25
- /**
26
- * #stateModel LinearSyntenyDisplay
27
- * extends `LinearComparativeDisplay` model
28
- */
29
- function stateModelFactory(configSchema: AnyConfigurationSchemaType) {
30
- return types
31
- .compose(
32
- 'LinearSyntenyDisplay',
33
- baseModelFactory(configSchema),
34
- types.model({
35
- /**
36
- * #property
37
- */
38
- type: types.literal('LinearSyntenyDisplay'),
39
- /**
40
- * #property
41
- */
42
- configuration: ConfigurationReference(configSchema),
43
- }),
44
- )
45
- .volatile(() => ({
46
- // canvas used for drawing visible screen
47
- mainCanvas: null as HTMLCanvasElement | null,
48
-
49
- // canvas used for drawing click map with feature ids
50
- // this renders a unique color per alignment, so that it can be re-traced
51
- // after a feature click with getImageData at that pixel
52
- clickMapCanvas: null as HTMLCanvasElement | null,
53
-
54
- // canvas used for drawing click map with cigar data
55
- // this can show if you are mousing over a insertion/deletion. it is similar
56
- // in purpose to the clickMapRef but was not feasible to pack this into the
57
- // clickMapRef
58
- cigarClickMapCanvas: null as HTMLCanvasElement | null,
59
-
60
- // canvas for drawing mouseover shading
61
- // this is separate from the other code for speed: don't have to redraw
62
- // entire canvas to do a feature's mouseover shading
63
- mouseoverCanvas: null as HTMLCanvasElement | null,
64
-
65
- // assigned by reaction
66
- featPositions: [] as FeatPos[],
67
-
68
- // currently mouse'd over feature
69
- mouseoverId: undefined as string | undefined,
70
-
71
- // currently click'd over feature
72
- clickId: undefined as string | undefined,
73
-
74
- // currently mouseover'd CIGAR subfeature
75
- cigarMouseoverId: -1,
76
- }))
77
- .actions(self => ({
78
- /**
79
- * #action
80
- */
81
- setFeatPositions(arg: FeatPos[]) {
82
- self.featPositions = arg
83
- },
84
- /**
85
- * #action
86
- */
87
- setMainCanvasRef(ref: HTMLCanvasElement | null) {
88
- self.mainCanvas = ref
89
- },
90
- /**
91
- * #action
92
- */
93
- setClickMapCanvasRef(ref: HTMLCanvasElement | null) {
94
- self.clickMapCanvas = ref
95
- },
96
- /**
97
- * #action
98
- */
99
- setCigarClickMapCanvasRef(ref: HTMLCanvasElement | null) {
100
- self.cigarClickMapCanvas = ref
101
- },
102
- /**
103
- * #action
104
- */
105
- setMouseoverCanvasRef(ref: HTMLCanvasElement | null) {
106
- self.mouseoverCanvas = ref
107
- },
108
- /**
109
- * #action
110
- */
111
- setMouseoverId(arg?: string) {
112
- self.mouseoverId = arg
113
- },
114
- /**
115
- * #action
116
- */
117
- setCigarMouseoverId(arg: number) {
118
- self.cigarMouseoverId = arg
119
- },
120
- /**
121
- * #action
122
- */
123
- setClickId(arg?: string) {
124
- self.clickId = arg
125
- },
126
- }))
127
-
128
- .views(self => ({
129
- /**
130
- * #getter
131
- */
132
- get adapterConfig() {
133
- return {
134
- name: self.parentTrack.configuration.adapter.type,
135
- assemblyNames: getConf(self, 'assemblyNames'),
136
- ...getConf(self.parentTrack, 'adapter'),
137
- }
138
- },
139
- /**
140
- * #getter
141
- */
142
- get trackIds() {
143
- return getConf(self, 'trackIds') as string[]
144
- },
145
- /**
146
- * #getter
147
- */
148
- get numFeats() {
149
- return self.featPositions.length
150
- },
151
- /**
152
- * #getter
153
- * used for synteny svg rendering
154
- */
155
- get ready() {
156
- return this.numFeats > 0
157
- },
158
-
159
- /**
160
- * #getter
161
- */
162
- get featMap() {
163
- return Object.fromEntries(self.featPositions.map(f => [f.f.id(), f]))
164
- },
165
- }))
166
- .actions(self => ({
167
- afterAttach() {
168
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
169
- ;(async () => {
170
- try {
171
- const { doAfterAttach } = await import('./afterAttach')
172
- doAfterAttach(self)
173
- } catch (e) {
174
- console.error(e)
175
- self.setError(e)
176
- }
177
- })()
178
- },
179
- }))
180
- }
181
-
182
- export type LinearSyntenyDisplayStateModel = ReturnType<
183
- typeof stateModelFactory
184
- >
185
- export type LinearSyntenyDisplayModel = Instance<LinearSyntenyDisplayStateModel>
186
-
187
- export default stateModelFactory
@@ -1,148 +0,0 @@
1
- import React, { useState } from 'react'
2
- import {
3
- Button,
4
- Checkbox,
5
- CircularProgress,
6
- DialogActions,
7
- DialogContent,
8
- FormControlLabel,
9
- MenuItem,
10
- TextField,
11
- Typography,
12
- } from '@mui/material'
13
- import { Dialog, ErrorMessage } from '@jbrowse/core/ui'
14
- import { ExportSvgOptions } from '../model'
15
- import { getSession, useLocalStorage } from '@jbrowse/core/util'
16
-
17
- function LoadingMessage() {
18
- return (
19
- <div>
20
- <CircularProgress size={20} style={{ marginRight: 20 }} />
21
- <Typography display="inline">Creating SVG</Typography>
22
- </div>
23
- )
24
- }
25
-
26
- function useSvgLocal<T>(key: string, val: T) {
27
- return useLocalStorage('svg-' + key, val)
28
- }
29
-
30
- export default function ExportSvgDlg({
31
- model,
32
- handleClose,
33
- }: {
34
- model: { exportSvg(opts: ExportSvgOptions): Promise<void> }
35
- handleClose: () => void
36
- }) {
37
- const session = getSession(model)
38
- const offscreenCanvas = typeof OffscreenCanvas !== 'undefined'
39
- const [rasterizeLayers, setRasterizeLayers] = useState(offscreenCanvas)
40
- const [loading, setLoading] = useState(false)
41
- const [filename, setFilename] = useSvgLocal('file', 'jbrowse.svg')
42
- const [trackLabels, setTrackLabels] = useSvgLocal('tracklabels', 'offset')
43
- const [themeName, setThemeName] = useSvgLocal(
44
- 'theme',
45
- session.themeName || 'default',
46
- )
47
- const [error, setError] = useState<unknown>()
48
- return (
49
- <Dialog open onClose={handleClose} title="Export SVG">
50
- <DialogContent>
51
- {error ? (
52
- <ErrorMessage error={error} />
53
- ) : loading ? (
54
- <LoadingMessage />
55
- ) : null}
56
- <TextField
57
- helperText="filename"
58
- value={filename}
59
- onChange={event => setFilename(event.target.value)}
60
- />
61
- <br />
62
-
63
- <TextField
64
- select
65
- label="Track label positioning"
66
- variant="outlined"
67
- value={trackLabels}
68
- style={{ width: 150 }}
69
- onChange={event => setTrackLabels(event.target.value)}
70
- >
71
- <MenuItem value="offset">Offset</MenuItem>
72
- <MenuItem value="overlay">Overlay</MenuItem>
73
- <MenuItem value="left">Left</MenuItem>
74
- <MenuItem value="none">None</MenuItem>
75
- </TextField>
76
- <br />
77
- {session.allThemes ? (
78
- <TextField
79
- select
80
- label="Theme"
81
- variant="outlined"
82
- value={themeName}
83
- onChange={event => setThemeName(event.target.value)}
84
- >
85
- {Object.entries(session.allThemes()).map(([key, val]) => (
86
- <MenuItem key={key} value={key}>
87
- {
88
- // @ts-expect-error
89
- val.name || '(Unknown name)'
90
- }
91
- </MenuItem>
92
- ))}
93
- </TextField>
94
- ) : null}
95
- {offscreenCanvas ? (
96
- <FormControlLabel
97
- control={
98
- <Checkbox
99
- checked={rasterizeLayers}
100
- onChange={() => setRasterizeLayers(val => !val)}
101
- />
102
- }
103
- label="Rasterize canvas based tracks? File may be much larger if this is turned off"
104
- />
105
- ) : (
106
- <Typography>
107
- Note: rasterizing layers not yet supported in this browser, so SVG
108
- size may be large
109
- </Typography>
110
- )}
111
- </DialogContent>
112
- <DialogActions>
113
- <Button
114
- variant="contained"
115
- color="secondary"
116
- onClick={() => handleClose()}
117
- >
118
- Cancel
119
- </Button>
120
- <Button
121
- variant="contained"
122
- color="primary"
123
- type="submit"
124
- onClick={async () => {
125
- setLoading(true)
126
- setError(undefined)
127
- try {
128
- await model.exportSvg({
129
- rasterizeLayers,
130
- filename,
131
- themeName,
132
- trackLabels,
133
- })
134
- handleClose()
135
- } catch (e) {
136
- console.error(e)
137
- setError(e)
138
- } finally {
139
- setLoading(false)
140
- }
141
- }}
142
- >
143
- Submit
144
- </Button>
145
- </DialogActions>
146
- </Dialog>
147
- )
148
- }
@@ -1,24 +0,0 @@
1
- import React from 'react'
2
- import { SvgIcon, SvgIconProps } from '@mui/material'
3
-
4
- export function Curves(props: SvgIconProps) {
5
- return (
6
- <SvgIcon {...props}>
7
- <path
8
- fill="currentColor"
9
- d="M16.5,21C13.5,21 12.31,16.76 11.05,12.28C10.14,9.04 9,5 7.5,5C4.11,5 4,11.93 4,12H2C2,11.63 2.06,3 7.5,3C10.5,3 11.71,7.25 12.97,11.74C13.83,14.8 15,19 16.5,19C19.94,19 20.03,12.07 20.03,12H22.03C22.03,12.37 21.97,21 16.5,21Z"
10
- />
11
- </SvgIcon>
12
- )
13
- }
14
-
15
- export function StraightLines(props: SvgIconProps) {
16
- return (
17
- <SvgIcon {...props}>
18
- <path
19
- fill="currentColor"
20
- d="M22 12L17 22L7.1 6.04L4.24 12H2L7 2L16.9 17.96L19.76 12H22Z"
21
- />
22
- </SvgIcon>
23
- )
24
- }