@jbrowse/plugin-alignments 2.6.2 → 2.7.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 (133) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.d.ts +2 -2
  2. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +2 -1
  3. package/dist/AlignmentsFeatureDetail/util.d.ts +1 -3
  4. package/dist/BamAdapter/BamAdapter.d.ts +2 -9
  5. package/dist/CramAdapter/CramAdapter.d.ts +3 -11
  6. package/dist/CramAdapter/CramAdapter.js +2 -1
  7. package/dist/CramAdapter/util.js +3 -6
  8. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +3 -4
  9. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +3 -3
  10. package/dist/LinearAlignmentsDisplay/models/model.d.ts +5 -9
  11. package/dist/LinearAlignmentsDisplay/models/model.js +1 -0
  12. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +514 -0
  13. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +547 -0
  14. package/dist/LinearPileupDisplay/components/ColorByModifications.d.ts +4 -5
  15. package/dist/LinearPileupDisplay/components/ColorByModifications.js +3 -4
  16. package/dist/LinearPileupDisplay/components/ColorByTag.d.ts +7 -5
  17. package/dist/LinearPileupDisplay/components/ColorByTag.js +4 -7
  18. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.d.ts +3 -4
  19. package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +2 -2
  20. package/dist/LinearPileupDisplay/components/SetFeatureHeight.d.ts +4 -5
  21. package/dist/LinearPileupDisplay/components/SetFeatureHeight.js +3 -3
  22. package/dist/LinearPileupDisplay/components/SetMaxHeight.d.ts +3 -4
  23. package/dist/LinearPileupDisplay/components/SetMaxHeight.js +3 -3
  24. package/dist/LinearPileupDisplay/components/SortByTag.d.ts +3 -4
  25. package/dist/LinearPileupDisplay/components/SortByTag.js +3 -3
  26. package/dist/LinearPileupDisplay/index.d.ts +1 -0
  27. package/dist/LinearPileupDisplay/index.js +3 -1
  28. package/dist/LinearPileupDisplay/model.d.ts +142 -234
  29. package/dist/LinearPileupDisplay/model.js +50 -446
  30. package/dist/LinearReadArcsDisplay/components/ReactComponent.d.ts +2 -2
  31. package/dist/LinearReadArcsDisplay/components/ReactComponent.js +2 -1
  32. package/dist/LinearReadArcsDisplay/model.d.ts +9 -14
  33. package/dist/LinearReadCloudDisplay/components/ReactComponent.d.ts +2 -2
  34. package/dist/LinearReadCloudDisplay/components/ReactComponent.js +2 -1
  35. package/dist/LinearReadCloudDisplay/drawPairChains.js +1 -2
  36. package/dist/LinearReadCloudDisplay/model.d.ts +13 -15
  37. package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +1 -1
  38. package/dist/LinearSNPCoverageDisplay/models/model.d.ts +18 -423
  39. package/dist/LinearSNPCoverageDisplay/models/model.js +18 -0
  40. package/dist/MismatchParser/index.js +6 -8
  41. package/dist/PileupRenderer/PileupRenderer.js +0 -25
  42. package/dist/PileupRenderer/colorBy.js +1 -1
  43. package/dist/PileupRenderer/components/PileupRendering.d.ts +9 -10
  44. package/dist/PileupRenderer/components/PileupRendering.js +3 -5
  45. package/dist/PileupRenderer/getAlignmentShapeColor.js +1 -1
  46. package/dist/PileupRenderer/layoutFeature.js +1 -2
  47. package/dist/PileupRenderer/makeImageData.d.ts +1 -3
  48. package/dist/PileupRenderer/renderMethylation.js +5 -10
  49. package/dist/PileupRenderer/renderMismatches.d.ts +2 -6
  50. package/dist/PileupRenderer/renderMismatches.js +8 -11
  51. package/dist/PileupRenderer/renderModifications.js +4 -8
  52. package/dist/PileupRenderer/renderSoftClipping.js +26 -25
  53. package/dist/PileupRenderer/sortUtil.js +2 -2
  54. package/dist/SNPCoverageAdapter/util.d.ts +9 -13
  55. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +6 -12
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.js +2 -1
  58. package/dist/shared/BaseDisplayComponent.d.ts +2 -2
  59. package/dist/shared/BaseDisplayComponent.js +2 -1
  60. package/dist/shared/FilterByTag.d.ts +6 -15
  61. package/dist/shared/FilterByTag.js +4 -6
  62. package/dist/shared/color.d.ts +10 -0
  63. package/dist/shared/color.js +7 -1
  64. package/dist/shared/fetchChains.js +1 -0
  65. package/dist/shared/index.d.ts +9 -0
  66. package/dist/util.d.ts +3 -9
  67. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.d.ts +2 -2
  68. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +2 -1
  69. package/esm/AlignmentsFeatureDetail/util.d.ts +1 -3
  70. package/esm/BamAdapter/BamAdapter.d.ts +2 -9
  71. package/esm/CramAdapter/CramAdapter.d.ts +3 -11
  72. package/esm/CramAdapter/CramAdapter.js +2 -1
  73. package/esm/CramAdapter/util.js +3 -6
  74. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +3 -4
  75. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +3 -3
  76. package/esm/LinearAlignmentsDisplay/models/model.d.ts +5 -9
  77. package/esm/LinearAlignmentsDisplay/models/model.js +1 -0
  78. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +514 -0
  79. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +517 -0
  80. package/esm/LinearPileupDisplay/components/ColorByModifications.d.ts +4 -5
  81. package/esm/LinearPileupDisplay/components/ColorByModifications.js +3 -4
  82. package/esm/LinearPileupDisplay/components/ColorByTag.d.ts +7 -5
  83. package/esm/LinearPileupDisplay/components/ColorByTag.js +4 -7
  84. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.d.ts +3 -4
  85. package/esm/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +2 -2
  86. package/esm/LinearPileupDisplay/components/SetFeatureHeight.d.ts +4 -5
  87. package/esm/LinearPileupDisplay/components/SetFeatureHeight.js +3 -3
  88. package/esm/LinearPileupDisplay/components/SetMaxHeight.d.ts +3 -4
  89. package/esm/LinearPileupDisplay/components/SetMaxHeight.js +3 -3
  90. package/esm/LinearPileupDisplay/components/SortByTag.d.ts +3 -4
  91. package/esm/LinearPileupDisplay/components/SortByTag.js +3 -3
  92. package/esm/LinearPileupDisplay/index.d.ts +1 -0
  93. package/esm/LinearPileupDisplay/index.js +1 -0
  94. package/esm/LinearPileupDisplay/model.d.ts +142 -234
  95. package/esm/LinearPileupDisplay/model.js +51 -447
  96. package/esm/LinearReadArcsDisplay/components/ReactComponent.d.ts +2 -2
  97. package/esm/LinearReadArcsDisplay/components/ReactComponent.js +2 -1
  98. package/esm/LinearReadArcsDisplay/model.d.ts +9 -14
  99. package/esm/LinearReadCloudDisplay/components/ReactComponent.d.ts +2 -2
  100. package/esm/LinearReadCloudDisplay/components/ReactComponent.js +2 -1
  101. package/esm/LinearReadCloudDisplay/drawPairChains.js +1 -2
  102. package/esm/LinearReadCloudDisplay/model.d.ts +13 -15
  103. package/esm/LinearSNPCoverageDisplay/components/Tooltip.js +1 -1
  104. package/esm/LinearSNPCoverageDisplay/models/model.d.ts +18 -423
  105. package/esm/LinearSNPCoverageDisplay/models/model.js +18 -0
  106. package/esm/MismatchParser/index.js +6 -8
  107. package/esm/PileupRenderer/PileupRenderer.js +0 -2
  108. package/esm/PileupRenderer/colorBy.js +1 -1
  109. package/esm/PileupRenderer/components/PileupRendering.d.ts +9 -10
  110. package/esm/PileupRenderer/components/PileupRendering.js +3 -5
  111. package/esm/PileupRenderer/getAlignmentShapeColor.js +1 -1
  112. package/esm/PileupRenderer/layoutFeature.js +1 -2
  113. package/esm/PileupRenderer/makeImageData.d.ts +1 -3
  114. package/esm/PileupRenderer/renderMethylation.js +5 -10
  115. package/esm/PileupRenderer/renderMismatches.d.ts +2 -6
  116. package/esm/PileupRenderer/renderMismatches.js +8 -11
  117. package/esm/PileupRenderer/renderModifications.js +4 -8
  118. package/esm/PileupRenderer/renderSoftClipping.js +26 -25
  119. package/esm/PileupRenderer/sortUtil.js +2 -2
  120. package/esm/SNPCoverageAdapter/util.d.ts +9 -13
  121. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js +6 -12
  122. package/esm/index.d.ts +1 -1
  123. package/esm/index.js +1 -1
  124. package/esm/shared/BaseDisplayComponent.d.ts +2 -2
  125. package/esm/shared/BaseDisplayComponent.js +3 -2
  126. package/esm/shared/FilterByTag.d.ts +6 -15
  127. package/esm/shared/FilterByTag.js +4 -6
  128. package/esm/shared/color.d.ts +10 -0
  129. package/esm/shared/color.js +6 -0
  130. package/esm/shared/fetchChains.js +1 -0
  131. package/esm/shared/index.d.ts +9 -0
  132. package/esm/util.d.ts +3 -9
  133. package/package.json +3 -4
@@ -0,0 +1,517 @@
1
+ import { lazy } from 'react';
2
+ import { autorun, observable } from 'mobx';
3
+ import { cast, types, addDisposer, getSnapshot } from 'mobx-state-tree';
4
+ import copy from 'copy-to-clipboard';
5
+ import { ConfigurationReference, readConfObject, getConf, } from '@jbrowse/core/configuration';
6
+ import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
7
+ import { getRpcSessionId } from '@jbrowse/core/util/tracks';
8
+ import { getEnv, getSession, isSessionModelWithWidgets, getContainingView, SimpleFeature, } from '@jbrowse/core/util';
9
+ import { BaseLinearDisplay, } from '@jbrowse/plugin-linear-genome-view';
10
+ // icons
11
+ import { ContentCopy as ContentCopyIcon } from '@jbrowse/core/ui/Icons';
12
+ import MenuOpenIcon from '@mui/icons-material/MenuOpen';
13
+ import FilterListIcon from '@mui/icons-material/ClearAll';
14
+ // locals
15
+ import LinearPileupDisplayBlurb from './components/LinearPileupDisplayBlurb';
16
+ import { getUniqueTagValues, FilterModel } from '../shared';
17
+ import { createAutorun } from '../util';
18
+ import { ColorByModel } from '../shared/color';
19
+ // async
20
+ const FilterByTagDlg = lazy(() => import('../shared/FilterByTag'));
21
+ const ColorByTagDlg = lazy(() => import('./components/ColorByTag'));
22
+ const SetFeatureHeightDlg = lazy(() => import('./components/SetFeatureHeight'));
23
+ const SetMaxHeightDlg = lazy(() => import('./components/SetMaxHeight'));
24
+ // using a map because it preserves order
25
+ const rendererTypes = new Map([
26
+ ['pileup', 'PileupRenderer'],
27
+ ['svg', 'SvgFeatureRenderer'],
28
+ ]);
29
+ /**
30
+ * #stateModel SharedLinearPileupDisplayMixin
31
+ * #category display
32
+ * extends `BaseLinearDisplay`
33
+ */
34
+ export function SharedLinearPileupDisplayMixin(configSchema) {
35
+ return types
36
+ .compose(BaseLinearDisplay, types.model({
37
+ /**
38
+ * #property
39
+ */
40
+ configuration: ConfigurationReference(configSchema),
41
+ /**
42
+ * #property
43
+ */
44
+ featureHeight: types.maybe(types.number),
45
+ /**
46
+ * #property
47
+ */
48
+ noSpacing: types.maybe(types.boolean),
49
+ /**
50
+ * #property
51
+ */
52
+ fadeLikelihood: types.maybe(types.boolean),
53
+ /**
54
+ * #property
55
+ */
56
+ trackMaxHeight: types.maybe(types.number),
57
+ /**
58
+ * #property
59
+ */
60
+ colorBy: ColorByModel,
61
+ /**
62
+ * #property
63
+ */
64
+ filterBy: types.optional(FilterModel, {}),
65
+ /**
66
+ * #property
67
+ */
68
+ jexlFilters: types.optional(types.array(types.string), []),
69
+ }))
70
+ .volatile(() => ({
71
+ colorTagMap: observable.map({}),
72
+ featureUnderMouseVolatile: undefined,
73
+ tagsReady: false,
74
+ }))
75
+ .views(self => ({
76
+ get autorunReady() {
77
+ const view = getContainingView(self);
78
+ return (view.initialized &&
79
+ self.featureDensityStatsReady &&
80
+ !self.regionTooLarge);
81
+ },
82
+ }))
83
+ .actions(self => ({
84
+ /**
85
+ * #action
86
+ */
87
+ setTagsReady(flag) {
88
+ self.tagsReady = flag;
89
+ },
90
+ /**
91
+ * #action
92
+ */
93
+ setMaxHeight(n) {
94
+ self.trackMaxHeight = n;
95
+ },
96
+ /**
97
+ * #action
98
+ */
99
+ setFeatureHeight(n) {
100
+ self.featureHeight = n;
101
+ },
102
+ /**
103
+ * #action
104
+ */
105
+ setNoSpacing(flag) {
106
+ self.noSpacing = flag;
107
+ },
108
+ /**
109
+ * #action
110
+ */
111
+ setColorScheme(colorScheme) {
112
+ self.colorTagMap = observable.map({}); // clear existing mapping
113
+ self.colorBy = cast(colorScheme);
114
+ if (colorScheme.tag) {
115
+ self.tagsReady = false;
116
+ }
117
+ },
118
+ /**
119
+ * #action
120
+ */
121
+ updateColorTagMap(uniqueTag) {
122
+ // pale color scheme
123
+ // https://cran.r-project.org/web/packages/khroma/vignettes/tol.html
124
+ // e.g. "tol_light"
125
+ const colorPalette = [
126
+ '#BBCCEE',
127
+ 'pink',
128
+ '#CCDDAA',
129
+ '#EEEEBB',
130
+ '#FFCCCC',
131
+ 'lightblue',
132
+ 'lightgreen',
133
+ 'tan',
134
+ '#CCEEFF',
135
+ 'lightsalmon',
136
+ ];
137
+ uniqueTag.forEach(value => {
138
+ if (!self.colorTagMap.has(value)) {
139
+ const totalKeys = [...self.colorTagMap.keys()].length;
140
+ self.colorTagMap.set(value, colorPalette[totalKeys]);
141
+ }
142
+ });
143
+ },
144
+ /**
145
+ * #action
146
+ */
147
+ setFeatureUnderMouse(feat) {
148
+ self.featureUnderMouseVolatile = feat;
149
+ },
150
+ /**
151
+ * #action
152
+ */
153
+ selectFeature(feature) {
154
+ const session = getSession(self);
155
+ if (isSessionModelWithWidgets(session)) {
156
+ const featureWidget = session.addWidget('AlignmentsFeatureWidget', 'alignmentFeature', { featureData: feature.toJSON(), view: getContainingView(self) });
157
+ session.showWidget(featureWidget);
158
+ }
159
+ session.setSelection(feature);
160
+ },
161
+ /**
162
+ * #action
163
+ * uses copy-to-clipboard and generates notification
164
+ */
165
+ copyFeatureToClipboard(feature) {
166
+ const { uniqueId, ...rest } = feature.toJSON();
167
+ const session = getSession(self);
168
+ copy(JSON.stringify(rest, null, 4));
169
+ session.notify('Copied to clipboard', 'success');
170
+ },
171
+ /**
172
+ * #action
173
+ */
174
+ setConfig(conf) {
175
+ self.configuration = conf;
176
+ },
177
+ /**
178
+ * #action
179
+ */
180
+ setFilterBy(filter) {
181
+ self.filterBy = cast(filter);
182
+ },
183
+ /**
184
+ * #action
185
+ */
186
+ setJexlFilters(filters) {
187
+ self.jexlFilters = cast(filters);
188
+ },
189
+ }))
190
+ .views(self => ({
191
+ /**
192
+ * #getter
193
+ */
194
+ get rendererConfig() {
195
+ const { featureHeight, noSpacing, trackMaxHeight, rendererTypeName } = self;
196
+ const configBlob = getConf(self, ['renderers', rendererTypeName]) || {};
197
+ return self.rendererType.configSchema.create({
198
+ ...configBlob,
199
+ ...(featureHeight !== undefined ? { height: featureHeight } : {}),
200
+ ...(noSpacing !== undefined ? { noSpacing } : {}),
201
+ ...(trackMaxHeight !== undefined
202
+ ? { maxHeight: trackMaxHeight }
203
+ : {}),
204
+ }, getEnv(self));
205
+ },
206
+ }))
207
+ .views(self => ({
208
+ /**
209
+ * #getter
210
+ */
211
+ get maxHeight() {
212
+ return readConfObject(self.rendererConfig, 'maxHeight');
213
+ },
214
+ /**
215
+ * #getter
216
+ */
217
+ get featureHeightSetting() {
218
+ return readConfObject(self.rendererConfig, 'height');
219
+ },
220
+ /**
221
+ * #getter
222
+ */
223
+ get featureUnderMouse() {
224
+ return self.featureUnderMouseVolatile;
225
+ },
226
+ /**
227
+ * #getter
228
+ */
229
+ renderReady() {
230
+ return self.tagsReady;
231
+ },
232
+ /**
233
+ * #getter
234
+ */
235
+ get filters() {
236
+ return new SerializableFilterChain({ filters: self.jexlFilters });
237
+ },
238
+ }))
239
+ .views(self => {
240
+ const { trackMenuItems: superTrackMenuItems, renderProps: superRenderProps, } = self;
241
+ return {
242
+ /**
243
+ * #getter
244
+ */
245
+ get rendererTypeName() {
246
+ const viewName = getConf(self, 'defaultRendering');
247
+ const rendererType = rendererTypes.get(viewName);
248
+ if (!rendererType) {
249
+ throw new Error(`unknown alignments view name ${viewName}`);
250
+ }
251
+ return rendererType;
252
+ },
253
+ /**
254
+ * #method
255
+ */
256
+ contextMenuItems() {
257
+ const feat = self.contextMenuFeature;
258
+ return feat
259
+ ? [
260
+ {
261
+ label: 'Open feature details',
262
+ icon: MenuOpenIcon,
263
+ onClick: () => {
264
+ self.clearFeatureSelection();
265
+ if (feat) {
266
+ self.selectFeature(feat);
267
+ }
268
+ },
269
+ },
270
+ {
271
+ label: 'Copy info to clipboard',
272
+ icon: ContentCopyIcon,
273
+ onClick: () => {
274
+ if (feat) {
275
+ self.copyFeatureToClipboard(feat);
276
+ }
277
+ },
278
+ },
279
+ ]
280
+ : [];
281
+ },
282
+ /**
283
+ * #getter
284
+ */
285
+ get DisplayBlurb() {
286
+ return LinearPileupDisplayBlurb;
287
+ },
288
+ /**
289
+ * #method
290
+ */
291
+ renderPropsPre() {
292
+ const { colorTagMap, colorBy, filterBy, rpcDriverName } = self;
293
+ const superProps = superRenderProps();
294
+ return {
295
+ ...superProps,
296
+ notReady: superProps.notReady || !self.renderReady(),
297
+ rpcDriverName,
298
+ displayModel: self,
299
+ colorBy: colorBy ? getSnapshot(colorBy) : undefined,
300
+ filterBy: JSON.parse(JSON.stringify(filterBy)),
301
+ filters: self.filters,
302
+ colorTagMap: Object.fromEntries(colorTagMap.toJSON()),
303
+ config: self.rendererConfig,
304
+ async onFeatureClick(_, featureId) {
305
+ const session = getSession(self);
306
+ const { rpcManager } = session;
307
+ try {
308
+ const f = featureId || self.featureIdUnderMouse;
309
+ if (!f) {
310
+ self.clearFeatureSelection();
311
+ }
312
+ else {
313
+ const sessionId = getRpcSessionId(self);
314
+ const { feature } = (await rpcManager.call(sessionId, 'CoreGetFeatureDetails', {
315
+ featureId: f,
316
+ sessionId,
317
+ layoutId: getContainingView(self).id,
318
+ rendererType: 'PileupRenderer',
319
+ }));
320
+ if (feature) {
321
+ self.selectFeature(new SimpleFeature(feature));
322
+ }
323
+ }
324
+ }
325
+ catch (e) {
326
+ console.error(e);
327
+ session.notify(`${e}`);
328
+ }
329
+ },
330
+ onClick() {
331
+ self.clearFeatureSelection();
332
+ },
333
+ // similar to click but opens a menu with further options
334
+ async onFeatureContextMenu(_, featureId) {
335
+ const session = getSession(self);
336
+ const { rpcManager } = session;
337
+ try {
338
+ const f = featureId || self.featureIdUnderMouse;
339
+ if (!f) {
340
+ self.clearFeatureSelection();
341
+ }
342
+ else {
343
+ const sessionId = getRpcSessionId(self);
344
+ const { feature } = (await rpcManager.call(sessionId, 'CoreGetFeatureDetails', {
345
+ featureId: f,
346
+ sessionId,
347
+ layoutId: getContainingView(self).id,
348
+ rendererType: 'PileupRenderer',
349
+ }));
350
+ if (feature) {
351
+ self.setContextMenuFeature(new SimpleFeature(feature));
352
+ }
353
+ }
354
+ }
355
+ catch (e) {
356
+ console.error(e);
357
+ session.notify(`${e}`);
358
+ }
359
+ },
360
+ };
361
+ },
362
+ /**
363
+ * #method
364
+ */
365
+ colorSchemeSubMenuItems() {
366
+ return [
367
+ {
368
+ label: 'Normal',
369
+ onClick: () => self.setColorScheme({ type: 'normal' }),
370
+ },
371
+ {
372
+ label: 'Mapping quality',
373
+ onClick: () => self.setColorScheme({ type: 'mappingQuality' }),
374
+ },
375
+ {
376
+ label: 'Strand',
377
+ onClick: () => self.setColorScheme({ type: 'strand' }),
378
+ },
379
+ {
380
+ label: 'Per-base quality',
381
+ onClick: () => self.setColorScheme({ type: 'perBaseQuality' }),
382
+ },
383
+ {
384
+ label: 'Per-base lettering',
385
+ onClick: () => self.setColorScheme({ type: 'perBaseLettering' }),
386
+ },
387
+ {
388
+ label: 'First-of-pair strand',
389
+ onClick: () => self.setColorScheme({ type: 'stranded' }),
390
+ },
391
+ {
392
+ label: 'Color by tag...',
393
+ onClick: () => {
394
+ getSession(self).queueDialog(doneCallback => [
395
+ ColorByTagDlg,
396
+ { model: self, handleClose: doneCallback },
397
+ ]);
398
+ },
399
+ },
400
+ ];
401
+ },
402
+ /**
403
+ * #method
404
+ */
405
+ trackMenuItems() {
406
+ return [
407
+ ...superTrackMenuItems(),
408
+ {
409
+ label: 'Filter by',
410
+ icon: FilterListIcon,
411
+ onClick: () => {
412
+ getSession(self).queueDialog(doneCallback => [
413
+ FilterByTagDlg,
414
+ { model: self, handleClose: doneCallback },
415
+ ]);
416
+ },
417
+ },
418
+ {
419
+ label: 'Set feature height',
420
+ subMenu: [
421
+ {
422
+ label: 'Normal',
423
+ onClick: () => {
424
+ self.setFeatureHeight(7);
425
+ self.setNoSpacing(false);
426
+ },
427
+ },
428
+ {
429
+ label: 'Compact',
430
+ onClick: () => {
431
+ self.setFeatureHeight(2);
432
+ self.setNoSpacing(true);
433
+ },
434
+ },
435
+ {
436
+ label: 'Manually set height',
437
+ onClick: () => {
438
+ getSession(self).queueDialog(doneCallback => [
439
+ SetFeatureHeightDlg,
440
+ { model: self, handleClose: doneCallback },
441
+ ]);
442
+ },
443
+ },
444
+ ],
445
+ },
446
+ {
447
+ label: 'Set max height...',
448
+ onClick: () => {
449
+ getSession(self).queueDialog(doneCallback => [
450
+ SetMaxHeightDlg,
451
+ { model: self, handleClose: doneCallback },
452
+ ]);
453
+ },
454
+ },
455
+ ];
456
+ },
457
+ };
458
+ })
459
+ .views(self => ({
460
+ renderProps() {
461
+ return self.renderPropsPre();
462
+ },
463
+ }))
464
+ .actions(self => ({
465
+ afterAttach() {
466
+ createAutorun(self, async () => {
467
+ const view = getContainingView(self);
468
+ if (!self.autorunReady) {
469
+ return;
470
+ }
471
+ const { colorBy, tagsReady } = self;
472
+ const { staticBlocks } = view;
473
+ if ((colorBy === null || colorBy === void 0 ? void 0 : colorBy.tag) && !tagsReady) {
474
+ const vals = await getUniqueTagValues(self, colorBy, staticBlocks);
475
+ self.updateColorTagMap(vals);
476
+ }
477
+ self.setTagsReady(true);
478
+ }, { delay: 1000 });
479
+ // autorun synchronizes featureUnderMouse with featureIdUnderMouse
480
+ // asynchronously. this is needed due to how we do not serialize all
481
+ // features from the BAM/CRAM over the rpc
482
+ addDisposer(self, autorun(async () => {
483
+ var _a;
484
+ const session = getSession(self);
485
+ try {
486
+ const featureId = self.featureIdUnderMouse;
487
+ if (((_a = self.featureUnderMouse) === null || _a === void 0 ? void 0 : _a.id()) !== featureId) {
488
+ if (!featureId) {
489
+ self.setFeatureUnderMouse(undefined);
490
+ }
491
+ else {
492
+ const sessionId = getRpcSessionId(self);
493
+ const view = getContainingView(self);
494
+ const { feature } = (await session.rpcManager.call(sessionId, 'CoreGetFeatureDetails', {
495
+ featureId,
496
+ sessionId,
497
+ layoutId: view.id,
498
+ rendererType: 'PileupRenderer',
499
+ }));
500
+ // check featureIdUnderMouse is still the same as the
501
+ // feature.id that was returned e.g. that the user hasn't
502
+ // moused over to a new position during the async operation
503
+ // above
504
+ if (self.featureIdUnderMouse === feature.uniqueId) {
505
+ self.setFeatureUnderMouse(new SimpleFeature(feature));
506
+ }
507
+ }
508
+ }
509
+ }
510
+ catch (e) {
511
+ console.error(e);
512
+ session.notify(`${e}`, 'error');
513
+ }
514
+ }));
515
+ },
516
+ }));
517
+ }
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { ObservableMap } from 'mobx';
3
- declare function ColorByTagDlg(props: {
3
+ declare const ColorByModificationsDialog: ({ model, handleClose, }: {
4
4
  model: {
5
5
  setColorScheme: (arg: {
6
6
  type: string;
@@ -8,9 +8,8 @@ declare function ColorByTagDlg(props: {
8
8
  modificationTagMap: ObservableMap<string, string>;
9
9
  colorBy?: {
10
10
  type: string;
11
- };
11
+ } | undefined;
12
12
  };
13
13
  handleClose: () => void;
14
- }): React.JSX.Element;
15
- declare const _default: typeof ColorByTagDlg;
16
- export default _default;
14
+ }) => React.JSX.Element;
15
+ export default ColorByModificationsDialog;
@@ -3,8 +3,7 @@ import { observer } from 'mobx-react';
3
3
  import { Button, CircularProgress, DialogActions, DialogContent, Typography, } from '@mui/material';
4
4
  import { Dialog } from '@jbrowse/core/ui';
5
5
  import ModificationTable from './ModificationsTable';
6
- function ColorByTagDlg(props) {
7
- const { model, handleClose } = props;
6
+ const ColorByModificationsDialog = observer(function ({ model, handleClose, }) {
8
7
  const { colorBy, modificationTagMap } = model;
9
8
  const modifications = [...modificationTagMap.entries()];
10
9
  return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Color by modifications" },
@@ -31,5 +30,5 @@ function ColorByTagDlg(props) {
31
30
  handleClose();
32
31
  } }, "Methylation"),
33
32
  React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel")))));
34
- }
35
- export default observer(ColorByTagDlg);
33
+ });
34
+ export default ColorByModificationsDialog;
@@ -1,9 +1,11 @@
1
1
  import React from 'react';
2
- declare function ColorByTagDlg(props: {
2
+ declare const ColorByTagDialog: ({ model, handleClose, }: {
3
3
  model: {
4
- setColorScheme: Function;
4
+ setColorScheme: (arg: {
5
+ type: string;
6
+ tag: string;
7
+ }) => void;
5
8
  };
6
9
  handleClose: () => void;
7
- }): React.JSX.Element;
8
- declare const _default: typeof ColorByTagDlg;
9
- export default _default;
10
+ }) => React.JSX.Element;
11
+ export default ColorByTagDialog;
@@ -2,22 +2,19 @@ import React, { useState } from 'react';
2
2
  import { observer } from 'mobx-react';
3
3
  import { Button, DialogContent, DialogActions, TextField, Typography, } from '@mui/material';
4
4
  import { Dialog } from '@jbrowse/core/ui';
5
- function ColorByTagDlg(props) {
6
- const { model, handleClose } = props;
5
+ const ColorByTagDialog = observer(function ({ model, handleClose, }) {
7
6
  const [tag, setTag] = useState('');
8
7
  const validTag = tag.match(/^[A-Za-z][A-Za-z0-9]$/);
9
8
  return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Color by tag" },
10
9
  React.createElement(DialogContent, { style: { overflowX: 'hidden' } },
11
10
  React.createElement(Typography, null, "Enter tag to color by: "),
12
11
  React.createElement(Typography, { color: "textSecondary" }, "Examples: XS or TS for RNA-seq inferred read strand, ts (lower-case) for minimap2 read strand, HP for haplotype, RG for read group, etc."),
13
- React.createElement(TextField, { value: tag, onChange: event => setTag(event.target.value), placeholder: "Enter tag name", inputProps: {
14
- maxLength: 2,
15
- }, error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '', autoComplete: "off" }),
12
+ React.createElement(TextField, { value: tag, onChange: event => setTag(event.target.value), placeholder: "Enter tag name", inputProps: { maxLength: 2 }, error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '', autoComplete: "off" }),
16
13
  React.createElement(DialogActions, null,
17
14
  React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
18
15
  model.setColorScheme({ type: 'tag', tag });
19
16
  handleClose();
20
17
  }, disabled: !validTag }, "Submit"),
21
18
  React.createElement(Button, { variant: "contained", color: "secondary", onClick: handleClose }, "Cancel")))));
22
- }
23
- export default observer(ColorByTagDlg);
19
+ });
20
+ export default ColorByTagDialog;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- export interface LinearPileupDisplayBlurbProps {
2
+ declare const LinearPileupDisplayBlurb: ({ model, }: {
3
3
  model: {
4
4
  sortedBy?: {
5
5
  pos: number;
@@ -8,6 +8,5 @@ export interface LinearPileupDisplayBlurbProps {
8
8
  tag?: string;
9
9
  };
10
10
  };
11
- }
12
- declare const _default: (props: LinearPileupDisplayBlurbProps) => React.JSX.Element | null;
13
- export default _default;
11
+ }) => React.JSX.Element | null;
12
+ export default LinearPileupDisplayBlurb;
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  import { observer } from 'mobx-react';
3
3
  import { Typography } from '@mui/material';
4
- export default observer(function LinearPileupDisplayBlurb(props) {
4
+ const LinearPileupDisplayBlurb = observer(function ({ model, }) {
5
5
  var _a;
6
- const { model } = props;
7
6
  const { sortedBy } = model;
8
7
  return sortedBy ? (React.createElement("div", { "data-testid": `blurb-${sortedBy}` },
9
8
  React.createElement(Typography, { color: "secondary", variant: "caption" }, sortedBy
10
9
  ? `Sorted by ${(_a = sortedBy.tag) !== null && _a !== void 0 ? _a : sortedBy.type} at ${sortedBy.refName}:${sortedBy.pos}`
11
10
  : null))) : null;
12
11
  });
12
+ export default LinearPileupDisplayBlurb;
@@ -1,12 +1,11 @@
1
1
  import React from 'react';
2
- declare function SetFeatureHeightDlg(props: {
2
+ declare const SetFeatureHeightDialog: (props: {
3
3
  model: {
4
4
  setFeatureHeight: (arg?: number) => void;
5
5
  setNoSpacing: (arg?: boolean) => void;
6
6
  featureHeightSetting: number;
7
- noSpacing?: boolean;
7
+ noSpacing?: boolean | undefined;
8
8
  };
9
9
  handleClose: () => void;
10
- }): React.JSX.Element;
11
- declare const _default: typeof SetFeatureHeightDlg;
12
- export default _default;
10
+ }) => React.JSX.Element;
11
+ export default SetFeatureHeightDialog;
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
2
2
  import { observer } from 'mobx-react';
3
3
  import { Button, Checkbox, DialogActions, DialogContent, FormControlLabel, TextField, Typography, } from '@mui/material';
4
4
  import { Dialog } from '@jbrowse/core/ui';
5
- function SetFeatureHeightDlg(props) {
5
+ const SetFeatureHeightDialog = observer(function (props) {
6
6
  const { model, handleClose } = props;
7
7
  const { featureHeightSetting, noSpacing: noSpacingSetting } = model;
8
8
  const [height, setHeight] = useState(`${featureHeightSetting}`);
@@ -20,5 +20,5 @@ function SetFeatureHeightDlg(props) {
20
20
  handleClose();
21
21
  } }, "Submit"),
22
22
  React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => handleClose() }, "Cancel")))));
23
- }
24
- export default observer(SetFeatureHeightDlg);
23
+ });
24
+ export default SetFeatureHeightDialog;
@@ -1,10 +1,9 @@
1
1
  import React from 'react';
2
- declare function SetMaxHeightDlg(props: {
2
+ declare const SetMaxHeightDialog: (props: {
3
3
  model: {
4
4
  maxHeight?: number;
5
5
  setMaxHeight: Function;
6
6
  };
7
7
  handleClose: () => void;
8
- }): React.JSX.Element;
9
- declare const _default: typeof SetMaxHeightDlg;
10
- export default _default;
8
+ }) => React.JSX.Element;
9
+ export default SetMaxHeightDialog;