@jbrowse/plugin-variants 4.0.4 → 4.1.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 (128) hide show
  1. package/esm/LDDisplay/SharedLDConfigSchema.d.ts +102 -0
  2. package/esm/LDDisplay/SharedLDConfigSchema.js +83 -0
  3. package/esm/LDDisplay/afterAttach.d.ts +2 -0
  4. package/esm/LDDisplay/afterAttach.js +123 -0
  5. package/esm/LDDisplay/components/BaseDisplayComponent.d.ts +15 -0
  6. package/esm/LDDisplay/components/BaseDisplayComponent.js +39 -0
  7. package/esm/LDDisplay/components/LDColorLegend.d.ts +15 -0
  8. package/esm/LDDisplay/components/LDColorLegend.js +75 -0
  9. package/esm/LDDisplay/components/LDDisplayComponent.d.ts +5 -0
  10. package/esm/LDDisplay/components/LDDisplayComponent.js +203 -0
  11. package/esm/LDDisplay/components/LinesConnectingMatrixToGenomicPosition.d.ts +16 -0
  12. package/esm/LDDisplay/components/LinesConnectingMatrixToGenomicPosition.js +109 -0
  13. package/esm/LDDisplay/configSchema1.d.ts +115 -0
  14. package/esm/LDDisplay/configSchema1.js +16 -0
  15. package/esm/LDDisplay/configSchema2.d.ts +115 -0
  16. package/esm/LDDisplay/configSchema2.js +16 -0
  17. package/esm/LDDisplay/index.d.ts +2 -0
  18. package/esm/LDDisplay/index.js +35 -0
  19. package/esm/LDDisplay/renderSvg.d.ts +3 -0
  20. package/esm/LDDisplay/renderSvg.js +36 -0
  21. package/esm/LDDisplay/shared.d.ts +367 -0
  22. package/esm/LDDisplay/shared.js +467 -0
  23. package/esm/LDDisplay/stateModel1.d.ts +365 -0
  24. package/esm/LDDisplay/stateModel1.js +10 -0
  25. package/esm/LDDisplay/stateModel2.d.ts +365 -0
  26. package/esm/LDDisplay/stateModel2.js +10 -0
  27. package/esm/LDRenderer/LDRenderer.d.ts +30 -0
  28. package/esm/LDRenderer/LDRenderer.js +109 -0
  29. package/esm/LDRenderer/components/LDRendering.d.ts +2 -0
  30. package/esm/LDRenderer/components/LDRendering.js +4 -0
  31. package/esm/LDRenderer/configSchema.d.ts +8 -0
  32. package/esm/LDRenderer/configSchema.js +10 -0
  33. package/esm/LDRenderer/index.d.ts +2 -0
  34. package/esm/LDRenderer/index.js +11 -0
  35. package/esm/LDRenderer/makeImageData.d.ts +20 -0
  36. package/esm/LDRenderer/makeImageData.js +157 -0
  37. package/esm/LDRenderer/types.d.ts +8 -0
  38. package/esm/LDRenderer/types.js +1 -0
  39. package/esm/LDTrack/configSchema.d.ts +85 -0
  40. package/esm/LDTrack/configSchema.js +7 -0
  41. package/esm/LDTrack/index.d.ts +2 -0
  42. package/esm/LDTrack/index.js +14 -0
  43. package/esm/LinearVariantDisplay/model.d.ts +126 -42
  44. package/esm/LinearVariantDisplay/model.js +46 -8
  45. package/esm/MultiLinearVariantDisplay/configSchema.d.ts +27 -1
  46. package/esm/MultiLinearVariantDisplay/model.d.ts +2635 -31
  47. package/esm/MultiLinearVariantDisplay/model.js +6 -0
  48. package/esm/MultiLinearVariantDisplay/renderSvg.d.ts +10 -2
  49. package/esm/MultiLinearVariantMatrixDisplay/configSchema.d.ts +25 -0
  50. package/esm/MultiLinearVariantMatrixDisplay/configSchema.js +26 -0
  51. package/esm/MultiLinearVariantMatrixDisplay/model.d.ts +2636 -32
  52. package/esm/MultiLinearVariantMatrixDisplay/model.js +6 -0
  53. package/esm/MultiLinearVariantMatrixRenderer/MultiLinearVariantMatrixRenderer.d.ts +2 -2
  54. package/esm/MultiLinearVariantMatrixRenderer/MultiLinearVariantMatrixRenderer.js +11 -9
  55. package/esm/MultiLinearVariantMatrixRenderer/components/MultiLinearVariantMatrixRendering.d.ts +8 -0
  56. package/esm/MultiLinearVariantMatrixRenderer/components/MultiLinearVariantMatrixRendering.js +14 -2
  57. package/esm/MultiLinearVariantMatrixRenderer/makeImageData.js +8 -11
  58. package/esm/MultiLinearVariantRenderer/MultiVariantRenderer.d.ts +2 -2
  59. package/esm/MultiLinearVariantRenderer/MultiVariantRenderer.js +4 -3
  60. package/esm/MultiLinearVariantRenderer/components/MultiLinearVariantRendering.d.ts +4 -0
  61. package/esm/MultiLinearVariantRenderer/components/MultiLinearVariantRendering.js +23 -2
  62. package/esm/MultiLinearVariantRenderer/makeImageData.js +12 -12
  63. package/esm/PlinkLDAdapter/PlinkLDAdapter.d.ts +25 -0
  64. package/esm/PlinkLDAdapter/PlinkLDAdapter.js +147 -0
  65. package/esm/PlinkLDAdapter/PlinkLDTabixAdapter.d.ts +24 -0
  66. package/esm/PlinkLDAdapter/PlinkLDTabixAdapter.js +156 -0
  67. package/esm/PlinkLDAdapter/configSchema.d.ts +10 -0
  68. package/esm/PlinkLDAdapter/configSchema.js +25 -0
  69. package/esm/PlinkLDAdapter/configSchemaTabix.d.ts +24 -0
  70. package/esm/PlinkLDAdapter/configSchemaTabix.js +46 -0
  71. package/esm/PlinkLDAdapter/index.d.ts +2 -0
  72. package/esm/PlinkLDAdapter/index.js +25 -0
  73. package/esm/PlinkLDAdapter/types.d.ts +29 -0
  74. package/esm/PlinkLDAdapter/types.js +1 -0
  75. package/esm/VariantFeatureWidget/VariantSampleGrid/VariantSampleGrid.js +1 -1
  76. package/esm/VariantRPC/MultiVariantGetFeatureDetails.d.ts +14 -0
  77. package/esm/VariantRPC/MultiVariantGetFeatureDetails.js +15 -0
  78. package/esm/VariantRPC/MultiVariantGetGenotypeMatrix.js +4 -1
  79. package/esm/VariantRPC/MultiVariantGetSimplifiedFeatures.js +3 -3
  80. package/esm/VariantRPC/executeClusterGenotypeMatrix.js +6 -3
  81. package/esm/VariantRPC/getGenotypeMatrix.d.ts +2 -3
  82. package/esm/VariantRPC/getGenotypeMatrix.js +4 -5
  83. package/esm/VariantRPC/getLDMatrix.d.ts +47 -0
  84. package/esm/VariantRPC/getLDMatrix.js +387 -0
  85. package/esm/VariantRPC/getLDMatrixFromPlink.d.ts +16 -0
  86. package/esm/VariantRPC/getLDMatrixFromPlink.js +105 -0
  87. package/esm/VariantRPC/getPhasedGenotypeMatrix.d.ts +2 -3
  88. package/esm/VariantRPC/getPhasedGenotypeMatrix.js +4 -5
  89. package/esm/VariantRPC/types.d.ts +3 -0
  90. package/esm/VcfAdapter/VcfAdapter.d.ts +1 -1
  91. package/esm/VcfAdapter/VcfAdapter.js +1 -2
  92. package/esm/VcfExtensionPoints/index.js +29 -3
  93. package/esm/VcfFeature/index.d.ts +2 -1
  94. package/esm/VcfFeature/index.js +4 -2
  95. package/esm/index.d.ts +1 -0
  96. package/esm/index.js +23 -0
  97. package/esm/shared/MultiVariantBaseModel.d.ts +2626 -26
  98. package/esm/shared/MultiVariantBaseModel.js +88 -39
  99. package/esm/shared/SharedVariantConfigSchema.d.ts +27 -1
  100. package/esm/shared/SharedVariantConfigSchema.js +28 -1
  101. package/esm/shared/VariantFeatureCache.d.ts +27 -0
  102. package/esm/shared/VariantFeatureCache.js +48 -0
  103. package/esm/shared/VariantRendererType.d.ts +23 -0
  104. package/esm/shared/VariantRendererType.js +15 -0
  105. package/esm/shared/applyColorPalette.d.ts +9 -0
  106. package/esm/shared/applyColorPalette.js +23 -0
  107. package/esm/shared/colorByAutorun.d.ts +10 -0
  108. package/esm/shared/colorByAutorun.js +39 -0
  109. package/esm/shared/components/AddFiltersDialog.d.ts +3 -3
  110. package/esm/shared/components/AddFiltersDialog.js +29 -22
  111. package/esm/shared/components/LDFilterDialog.d.ts +13 -0
  112. package/esm/shared/components/LDFilterDialog.js +102 -0
  113. package/esm/shared/components/MAFFilterDialog.js +23 -16
  114. package/esm/shared/components/RecombinationTrack.d.ts +21 -0
  115. package/esm/shared/components/RecombinationTrack.js +54 -0
  116. package/esm/shared/components/RecombinationYScaleBar.d.ts +7 -0
  117. package/esm/shared/components/RecombinationYScaleBar.js +34 -0
  118. package/esm/shared/components/SetColorDialogRowPalettizer.d.ts +3 -8
  119. package/esm/shared/components/SetColorDialogRowPalettizer.js +2 -14
  120. package/esm/shared/drawAlleleCount.js +9 -0
  121. package/esm/shared/drawPhased.d.ts +1 -1
  122. package/esm/shared/drawPhased.js +31 -2
  123. package/esm/shared/mafFilterUtils.d.ts +5 -0
  124. package/esm/shared/mafFilterUtils.js +17 -0
  125. package/esm/shared/minorAlleleFrequencyUtils.d.ts +4 -2
  126. package/esm/shared/minorAlleleFrequencyUtils.js +261 -19
  127. package/esm/shared/setupMultiVariantAutoruns.js +2 -0
  128. package/package.json +11 -10
@@ -3,12 +3,13 @@ import { fromNewick } from '@gmod/hclust';
3
3
  import { ConfigurationReference, getConf } from '@jbrowse/core/configuration';
4
4
  import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
5
5
  import { set1 } from '@jbrowse/core/ui/colors';
6
- import { getSession } from '@jbrowse/core/util';
6
+ import { SimpleFeature, getContainingTrack, getSession, } from '@jbrowse/core/util';
7
7
  import { stopStopToken } from '@jbrowse/core/util/stopToken';
8
+ import { getRpcSessionId } from '@jbrowse/core/util/tracks';
8
9
  import { cast, isAlive, types } from '@jbrowse/mobx-state-tree';
9
10
  import { linearBareDisplayStateModelFactory } from '@jbrowse/plugin-linear-genome-view';
10
11
  import CategoryIcon from '@mui/icons-material/Category';
11
- import FilterListIcon from '@mui/icons-material/FilterList';
12
+ import ClearAllIcon from '@mui/icons-material/ClearAll';
12
13
  import HeightIcon from '@mui/icons-material/Height';
13
14
  import SplitscreenIcon from '@mui/icons-material/Splitscreen';
14
15
  import VisibilityIcon from '@mui/icons-material/Visibility';
@@ -16,10 +17,10 @@ import { ascending } from '@mui/x-charts-vendor/d3-array';
16
17
  import deepEqual from 'fast-deep-equal';
17
18
  import { NO_CALL_COLOR, OTHER_ALT_COLOR, REFERENCE_COLOR, UNPHASED_COLOR, getAltColorForDosage, } from "./constants.js";
18
19
  import { getSources } from "./getSources.js";
20
+ import { createMAFFilterMenuItem } from "./mafFilterUtils.js";
19
21
  import { cluster, hierarchy } from "../d3-hierarchy2/index.js";
20
- const SetColorDialog = lazy(() => import("./components/SetColorDialog.js"));
21
- const MAFFilterDialog = lazy(() => import("./components/MAFFilterDialog.js"));
22
22
  const AddFiltersDialog = lazy(() => import("./components/AddFiltersDialog.js"));
23
+ const SetColorDialog = lazy(() => import("./components/SetColorDialog.js"));
23
24
  const ClusterDialog = lazy(() => import("./components/MultiVariantClusterDialog/ClusterDialog.js"));
24
25
  const SetRowHeightDialog = lazy(() => import("./components/SetRowHeightDialog.js"));
25
26
  export default function MultiVariantBaseModelF(configSchema) {
@@ -28,14 +29,14 @@ export default function MultiVariantBaseModelF(configSchema) {
28
29
  type: types.literal('LinearVariantMatrixDisplay'),
29
30
  layout: types.optional(types.frozen(), []),
30
31
  configuration: ConfigurationReference(configSchema),
31
- minorAlleleFrequencyFilter: types.optional(types.number, 0),
32
- showSidebarLabelsSetting: types.optional(types.boolean, true),
33
- showTree: types.optional(types.boolean, true),
34
- renderingMode: types.optional(types.string, 'alleleCount'),
32
+ minorAlleleFrequencyFilterSetting: types.maybe(types.number),
33
+ showSidebarLabelsSetting: types.maybe(types.boolean),
34
+ showTreeSetting: types.maybe(types.boolean),
35
+ renderingModeSetting: types.maybe(types.string),
35
36
  rowHeightMode: types.optional(types.union(types.literal('auto'), types.number), 'auto'),
36
37
  lengthCutoffFilter: types.optional(types.number, Number.MAX_SAFE_INTEGER),
37
38
  jexlFilters: types.maybe(types.array(types.string)),
38
- referenceDrawingMode: types.optional(types.string, 'skip'),
39
+ referenceDrawingModeSetting: types.maybe(types.string),
39
40
  clusterTree: types.maybe(types.string),
40
41
  treeAreaWidth: types.optional(types.number, 80),
41
42
  lineZoneHeight: types.optional(types.number, 0),
@@ -45,6 +46,7 @@ export default function MultiVariantBaseModelF(configSchema) {
45
46
  simplifiedFeaturesStopToken: undefined,
46
47
  featureUnderMouseVolatile: undefined,
47
48
  sourcesVolatile: undefined,
49
+ colorByApplied: false,
48
50
  featuresVolatile: undefined,
49
51
  hasPhased: false,
50
52
  sampleInfo: undefined,
@@ -52,6 +54,11 @@ export default function MultiVariantBaseModelF(configSchema) {
52
54
  hoveredTreeNode: undefined,
53
55
  treeCanvas: undefined,
54
56
  mouseoverCanvas: undefined,
57
+ }))
58
+ .views(self => ({
59
+ get renderingMode() {
60
+ return (self.renderingModeSetting ?? getConf(self, 'renderingMode'));
61
+ },
55
62
  }))
56
63
  .actions(self => ({
57
64
  setJexlFilters(f) {
@@ -78,6 +85,9 @@ export default function MultiVariantBaseModelF(configSchema) {
78
85
  setFeatures(f) {
79
86
  self.featuresVolatile = f;
80
87
  },
88
+ setColorByApplied(value) {
89
+ self.colorByApplied = value;
90
+ },
81
91
  setLayout(layout, clearTree = true) {
82
92
  const orderChanged = clearTree &&
83
93
  self.clusterTree &&
@@ -113,20 +123,21 @@ export default function MultiVariantBaseModelF(configSchema) {
113
123
  }
114
124
  },
115
125
  setMafFilter(arg) {
116
- self.minorAlleleFrequencyFilter = arg;
126
+ self.minorAlleleFrequencyFilterSetting = arg;
117
127
  },
118
128
  setShowSidebarLabels(arg) {
119
129
  self.showSidebarLabelsSetting = arg;
120
130
  },
121
131
  setShowTree(arg) {
122
- self.showTree = arg;
132
+ self.showTreeSetting = arg;
123
133
  },
124
134
  setPhasedMode(arg) {
125
- if (self.renderingMode !== arg) {
135
+ const currentMode = self.renderingModeSetting ?? getConf(self, 'renderingMode');
136
+ if (currentMode !== arg) {
126
137
  self.layout = [];
127
138
  self.clusterTree = undefined;
128
139
  }
129
- self.renderingMode = arg;
140
+ self.renderingModeSetting = arg;
130
141
  },
131
142
  setAutoHeight(auto) {
132
143
  self.rowHeightMode = auto ? 'auto' : 10;
@@ -140,14 +151,31 @@ export default function MultiVariantBaseModelF(configSchema) {
140
151
  }
141
152
  },
142
153
  setReferenceDrawingMode(arg) {
143
- self.referenceDrawingMode = arg;
154
+ self.referenceDrawingModeSetting = arg;
144
155
  },
145
156
  }))
146
157
  .views(self => ({
147
158
  get autoHeight() {
148
159
  return self.rowHeightMode === 'auto';
149
160
  },
150
- get activeFilters() {
161
+ get minorAlleleFrequencyFilter() {
162
+ return (self.minorAlleleFrequencyFilterSetting ??
163
+ getConf(self, 'minorAlleleFrequencyFilter'));
164
+ },
165
+ get showSidebarLabels() {
166
+ return (self.showSidebarLabelsSetting ?? getConf(self, 'showSidebarLabels'));
167
+ },
168
+ get showTree() {
169
+ return self.showTreeSetting ?? getConf(self, 'showTree');
170
+ },
171
+ get referenceDrawingMode() {
172
+ if (self.referenceDrawingModeSetting !== undefined) {
173
+ return self.referenceDrawingModeSetting;
174
+ }
175
+ const showRef = getConf(self, 'showReferenceAlleles');
176
+ return showRef ? 'draw' : 'skip';
177
+ },
178
+ activeFilters() {
151
179
  return (self.jexlFilters ??
152
180
  getConf(self, 'jexlFilters').map((r) => `jexl:${r}`));
153
181
  },
@@ -186,7 +214,7 @@ export default function MultiVariantBaseModelF(configSchema) {
186
214
  return {
187
215
  get sourceMap() {
188
216
  return self.sources
189
- ? Object.fromEntries(self.sources.map(source => [source.name, source]))
217
+ ? Object.fromEntries(self.sources.map((source) => [source.name, source]))
190
218
  : undefined;
191
219
  },
192
220
  get availableHeight() {
@@ -233,9 +261,9 @@ export default function MultiVariantBaseModelF(configSchema) {
233
261
  {
234
262
  label: 'Show sidebar labels',
235
263
  type: 'checkbox',
236
- checked: self.showSidebarLabelsSetting,
264
+ checked: self.showSidebarLabels,
237
265
  onClick: () => {
238
- self.setShowSidebarLabels(!self.showSidebarLabelsSetting);
266
+ self.setShowSidebarLabels(!self.showSidebarLabels);
239
267
  },
240
268
  },
241
269
  {
@@ -324,20 +352,9 @@ export default function MultiVariantBaseModelF(configSchema) {
324
352
  },
325
353
  {
326
354
  label: 'Filter by',
327
- icon: FilterListIcon,
355
+ icon: ClearAllIcon,
328
356
  subMenu: [
329
- {
330
- label: 'Minor allele frequency',
331
- onClick: () => {
332
- getSession(self).queueDialog(handleClose => [
333
- MAFFilterDialog,
334
- {
335
- model: self,
336
- handleClose,
337
- },
338
- ]);
339
- },
340
- },
357
+ createMAFFilterMenuItem(self),
341
358
  {
342
359
  label: 'Edit filters',
343
360
  onClick: () => {
@@ -383,7 +400,7 @@ export default function MultiVariantBaseModelF(configSchema) {
383
400
  })
384
401
  .views(self => ({
385
402
  get canDisplayLabels() {
386
- return self.rowHeight >= 6 && self.showSidebarLabelsSetting;
403
+ return self.rowHeight >= 6 && self.showSidebarLabels;
387
404
  },
388
405
  get totalHeight() {
389
406
  return self.rowHeight * (self.sources?.length || 1);
@@ -423,10 +440,36 @@ export default function MultiVariantBaseModelF(configSchema) {
423
440
  scrollTop: self.scrollTop,
424
441
  referenceDrawingMode: self.referenceDrawingMode,
425
442
  filters: new SerializableFilterChain({
426
- filters: self.activeFilters,
443
+ filters: self.activeFilters(),
427
444
  }),
428
445
  };
429
446
  },
447
+ renderingProps() {
448
+ return {
449
+ displayModel: self,
450
+ async onFeatureClick(_, featureId) {
451
+ const session = getSession(self);
452
+ const { rpcManager } = session;
453
+ try {
454
+ const sessionId = getRpcSessionId(self);
455
+ const track = getContainingTrack(self);
456
+ const { feature } = (await rpcManager.call(sessionId, 'MultiVariantGetFeatureDetails', {
457
+ featureId,
458
+ sessionId,
459
+ trackInstanceId: track.id,
460
+ rendererType: self.rendererTypeName,
461
+ }));
462
+ if (isAlive(self) && feature) {
463
+ self.selectFeature(new SimpleFeature(feature));
464
+ }
465
+ }
466
+ catch (e) {
467
+ console.error(e);
468
+ session.notifyError(`${e}`, e);
469
+ }
470
+ },
471
+ };
472
+ },
430
473
  legendItems() {
431
474
  if (self.renderingMode === 'phased') {
432
475
  let maxAltAlleles = 1;
@@ -482,20 +525,26 @@ export default function MultiVariantBaseModelF(configSchema) {
482
525
  if (!snap) {
483
526
  return snap;
484
527
  }
485
- const { layout, minorAlleleFrequencyFilter, showSidebarLabelsSetting, showTree, renderingMode, rowHeightMode, lengthCutoffFilter, jexlFilters, referenceDrawingMode, clusterTree, treeAreaWidth, lineZoneHeight, ...rest } = snap;
528
+ const { layout, minorAlleleFrequencyFilterSetting, showSidebarLabelsSetting, showTreeSetting, renderingModeSetting, rowHeightMode, lengthCutoffFilter, jexlFilters, referenceDrawingModeSetting, clusterTree, treeAreaWidth, lineZoneHeight, ...rest } = snap;
486
529
  return {
487
530
  ...rest,
488
531
  ...(layout.length ? { layout } : {}),
489
- ...(minorAlleleFrequencyFilter ? { minorAlleleFrequencyFilter } : {}),
490
- ...(!showSidebarLabelsSetting ? { showSidebarLabelsSetting } : {}),
491
- ...(!showTree ? { showTree } : {}),
492
- ...(renderingMode !== 'alleleCount' ? { renderingMode } : {}),
532
+ ...(minorAlleleFrequencyFilterSetting !== undefined
533
+ ? { minorAlleleFrequencyFilterSetting }
534
+ : {}),
535
+ ...(showSidebarLabelsSetting !== undefined
536
+ ? { showSidebarLabelsSetting }
537
+ : {}),
538
+ ...(showTreeSetting !== undefined ? { showTreeSetting } : {}),
539
+ ...(renderingModeSetting !== undefined ? { renderingModeSetting } : {}),
493
540
  ...(rowHeightMode !== 'auto' ? { rowHeightMode } : {}),
494
541
  ...(lengthCutoffFilter !== Number.MAX_SAFE_INTEGER
495
542
  ? { lengthCutoffFilter }
496
543
  : {}),
497
544
  ...(jexlFilters?.length ? { jexlFilters } : {}),
498
- ...(referenceDrawingMode !== 'skip' ? { referenceDrawingMode } : {}),
545
+ ...(referenceDrawingModeSetting !== undefined
546
+ ? { referenceDrawingModeSetting }
547
+ : {}),
499
548
  ...(clusterTree !== undefined ? { clusterTree } : {}),
500
549
  ...(treeAreaWidth !== 80 ? { treeAreaWidth } : {}),
501
550
  ...(lineZoneHeight ? { lineZoneHeight } : {}),
@@ -1,4 +1,30 @@
1
- export default function sharedVariantConfigFactory(): import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{}, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
1
+ export default function sharedVariantConfigFactory(): import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
2
+ showReferenceAlleles: {
3
+ type: string;
4
+ defaultValue: boolean;
5
+ };
6
+ showSidebarLabels: {
7
+ type: string;
8
+ defaultValue: boolean;
9
+ };
10
+ showTree: {
11
+ type: string;
12
+ defaultValue: boolean;
13
+ };
14
+ renderingMode: {
15
+ type: string;
16
+ model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
17
+ defaultValue: string;
18
+ };
19
+ minorAlleleFrequencyFilter: {
20
+ type: string;
21
+ defaultValue: number;
22
+ };
23
+ colorBy: {
24
+ type: string;
25
+ defaultValue: string;
26
+ };
27
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
2
28
  maxFeatureScreenDensity: {
3
29
  type: string;
4
30
  description: string;
@@ -1,7 +1,34 @@
1
1
  import { ConfigurationSchema } from '@jbrowse/core/configuration';
2
+ import { types } from '@jbrowse/mobx-state-tree';
2
3
  import { baseLinearDisplayConfigSchema } from '@jbrowse/plugin-linear-genome-view';
3
4
  export default function sharedVariantConfigFactory() {
4
- return ConfigurationSchema('SharedVariantDisplay', {}, {
5
+ return ConfigurationSchema('SharedVariantDisplay', {
6
+ showReferenceAlleles: {
7
+ type: 'boolean',
8
+ defaultValue: false,
9
+ },
10
+ showSidebarLabels: {
11
+ type: 'boolean',
12
+ defaultValue: true,
13
+ },
14
+ showTree: {
15
+ type: 'boolean',
16
+ defaultValue: true,
17
+ },
18
+ renderingMode: {
19
+ type: 'stringEnum',
20
+ model: types.enumeration('RenderingMode', ['alleleCount', 'phased']),
21
+ defaultValue: 'alleleCount',
22
+ },
23
+ minorAlleleFrequencyFilter: {
24
+ type: 'number',
25
+ defaultValue: 0,
26
+ },
27
+ colorBy: {
28
+ type: 'string',
29
+ defaultValue: '',
30
+ },
31
+ }, {
5
32
  baseConfiguration: baseLinearDisplayConfigSchema,
6
33
  explicitlyTyped: true,
7
34
  });
@@ -0,0 +1,27 @@
1
+ import type { Feature } from '@jbrowse/core/util';
2
+ export declare class VariantFeatureSession {
3
+ private features;
4
+ addFeatures(refName: string, features: Map<string, Feature>): void;
5
+ getDataByID(id: string): Feature | undefined;
6
+ discardRange(refName: string, start: number, end: number): void;
7
+ }
8
+ export declare class VariantFeatureCacheManager {
9
+ private sessions;
10
+ getSession(args: {
11
+ sessionId: string;
12
+ trackInstanceId: string;
13
+ }): VariantFeatureSession;
14
+ freeResources(args: {
15
+ sessionId: string;
16
+ trackInstanceId: string;
17
+ regions: {
18
+ refName: string;
19
+ start: number;
20
+ end: number;
21
+ }[];
22
+ }): void;
23
+ deleteSession(args: {
24
+ sessionId: string;
25
+ trackInstanceId: string;
26
+ }): void;
27
+ }
@@ -0,0 +1,48 @@
1
+ export class VariantFeatureSession {
2
+ features = new Map();
3
+ addFeatures(refName, features) {
4
+ for (const [id, feature] of features) {
5
+ this.features.set(id, feature);
6
+ }
7
+ }
8
+ getDataByID(id) {
9
+ return this.features.get(id);
10
+ }
11
+ discardRange(refName, start, end) {
12
+ for (const [id, feature] of this.features) {
13
+ const fRefName = feature.get('refName');
14
+ const fStart = feature.get('start');
15
+ const fEnd = feature.get('end');
16
+ if (fRefName === refName && fStart < end && fEnd > start) {
17
+ this.features.delete(id);
18
+ }
19
+ }
20
+ }
21
+ }
22
+ function getLayoutId(args) {
23
+ return `${args.sessionId}-${args.trackInstanceId}`;
24
+ }
25
+ export class VariantFeatureCacheManager {
26
+ sessions = {};
27
+ getSession(args) {
28
+ const key = getLayoutId(args);
29
+ if (!this.sessions[key]) {
30
+ this.sessions[key] = new VariantFeatureSession();
31
+ }
32
+ return this.sessions[key];
33
+ }
34
+ freeResources(args) {
35
+ const key = getLayoutId(args);
36
+ const session = this.sessions[key];
37
+ if (session) {
38
+ const region = args.regions[0];
39
+ if (region) {
40
+ session.discardRange(region.refName, region.start, region.end);
41
+ }
42
+ }
43
+ }
44
+ deleteSession(args) {
45
+ const key = getLayoutId(args);
46
+ delete this.sessions[key];
47
+ }
48
+ }
@@ -0,0 +1,23 @@
1
+ import FeatureRendererType from '@jbrowse/core/pluggableElementTypes/renderers/FeatureRendererType';
2
+ import { VariantFeatureCacheManager } from './VariantFeatureCache.ts';
3
+ import type { Feature } from '@jbrowse/core/util';
4
+ export default class VariantRendererType extends FeatureRendererType {
5
+ featureCacheManager: VariantFeatureCacheManager;
6
+ getFeatureById(featureId: string, args: {
7
+ sessionId: string;
8
+ trackInstanceId: string;
9
+ }): Feature | undefined;
10
+ freeResources(args: {
11
+ sessionId: string;
12
+ trackInstanceId: string;
13
+ regions: {
14
+ refName: string;
15
+ start: number;
16
+ end: number;
17
+ }[];
18
+ }): void;
19
+ protected cacheFeatures(args: {
20
+ sessionId: string;
21
+ trackInstanceId: string;
22
+ }, refName: string, features: Map<string, Feature>): void;
23
+ }
@@ -0,0 +1,15 @@
1
+ import FeatureRendererType from '@jbrowse/core/pluggableElementTypes/renderers/FeatureRendererType';
2
+ import { VariantFeatureCacheManager } from "./VariantFeatureCache.js";
3
+ export default class VariantRendererType extends FeatureRendererType {
4
+ featureCacheManager = new VariantFeatureCacheManager();
5
+ getFeatureById(featureId, args) {
6
+ return this.featureCacheManager.getSession(args).getDataByID(featureId);
7
+ }
8
+ freeResources(args) {
9
+ this.featureCacheManager.freeResources(args);
10
+ }
11
+ cacheFeatures(args, refName, features) {
12
+ const session = this.featureCacheManager.getSession(args);
13
+ session.addFeatures(refName, features);
14
+ }
15
+ }
@@ -0,0 +1,9 @@
1
+ import type { Source } from './types.ts';
2
+ export declare function applyColorPalette(sources: Source[], attribute: string): Source[] | {
3
+ color: string | undefined;
4
+ baseUri?: string;
5
+ name: string;
6
+ baseName?: string;
7
+ group?: string;
8
+ HP?: number;
9
+ }[];
@@ -0,0 +1,23 @@
1
+ import { set1 } from '@jbrowse/core/ui/colors';
2
+ import { randomColor } from '@jbrowse/core/util/color';
3
+ export function applyColorPalette(sources, attribute) {
4
+ if (!attribute || sources.length === 0) {
5
+ return sources;
6
+ }
7
+ const hasAttribute = sources.some(source => attribute in source);
8
+ if (!hasAttribute) {
9
+ return sources;
10
+ }
11
+ const counts = new Map();
12
+ for (const source of sources) {
13
+ const key = String(source[attribute] ?? '');
14
+ counts.set(key, (counts.get(key) || 0) + 1);
15
+ }
16
+ const colorMap = Object.fromEntries([...counts.entries()]
17
+ .sort((a, b) => a[1] - b[1])
18
+ .map(([key], idx) => [key, set1[idx] || randomColor(key)]));
19
+ return sources.map(source => ({
20
+ ...source,
21
+ color: colorMap[String(source[attribute] ?? '')],
22
+ }));
23
+ }
@@ -0,0 +1,10 @@
1
+ import type { Source } from './types.ts';
2
+ import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
+ export declare function setupColorByAutorun(self: {
4
+ configuration: AnyConfigurationModel;
5
+ sourcesVolatile: Source[] | undefined;
6
+ layout: Source[];
7
+ colorByApplied: boolean;
8
+ setLayout: (layout: Source[], clearTree?: boolean) => void;
9
+ setColorByApplied: (value: boolean) => void;
10
+ }): void;
@@ -0,0 +1,39 @@
1
+ import { getConf } from '@jbrowse/core/configuration';
2
+ import { addDisposer, isAlive } from '@jbrowse/mobx-state-tree';
3
+ import { autorun } from 'mobx';
4
+ import { applyColorPalette } from "./applyColorPalette.js";
5
+ export function setupColorByAutorun(self) {
6
+ addDisposer(self, autorun(() => {
7
+ if (!isAlive(self)) {
8
+ return;
9
+ }
10
+ if (self.colorByApplied) {
11
+ return;
12
+ }
13
+ const sources = self.sourcesVolatile;
14
+ if (!sources || sources.length === 0) {
15
+ return;
16
+ }
17
+ if (self.layout.length > 0) {
18
+ self.setColorByApplied(true);
19
+ return;
20
+ }
21
+ const colorBy = getConf(self, 'colorBy');
22
+ if (!colorBy) {
23
+ self.setColorByApplied(true);
24
+ return;
25
+ }
26
+ const hasAttribute = sources.some(source => colorBy in source);
27
+ if (!hasAttribute) {
28
+ console.warn(`colorBy attribute "${colorBy}" not found in sample metadata. ` +
29
+ `Available attributes: ${Object.keys(sources[0] || {}).join(', ')}`);
30
+ self.setColorByApplied(true);
31
+ return;
32
+ }
33
+ const coloredSources = applyColorPalette(sources, colorBy);
34
+ self.setLayout(coloredSources, false);
35
+ self.setColorByApplied(true);
36
+ }, {
37
+ name: 'ColorByAutorun',
38
+ }));
39
+ }
@@ -1,8 +1,8 @@
1
- export default function AddFiltersDialog({ model, handleClose, }: {
1
+ declare const AddFiltersDialog: ({ model, handleClose, }: {
2
2
  model: {
3
3
  jexlFilters?: string[];
4
- activeFilters: string[];
5
4
  setJexlFilters: (arg?: string[]) => void;
6
5
  };
7
6
  handleClose: () => void;
8
- }): import("react/jsx-runtime").JSX.Element;
7
+ }) => import("react/jsx-runtime").JSX.Element;
8
+ export default AddFiltersDialog;
@@ -1,9 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useMemo, useState } from 'react';
2
+ import { useEffect, useState } from 'react';
3
3
  import { Dialog } from '@jbrowse/core/ui';
4
4
  import { stringToJexlExpression } from '@jbrowse/core/util/jexlStrings';
5
5
  import { makeStyles } from '@jbrowse/core/util/tss-react';
6
6
  import { Button, DialogActions, DialogContent, TextField } from '@mui/material';
7
+ import { observer } from 'mobx-react';
7
8
  const useStyles = makeStyles()({
8
9
  dialogContent: {
9
10
  width: '80em',
@@ -16,27 +17,30 @@ const useStyles = makeStyles()({
16
17
  fontSize: '0.8em',
17
18
  },
18
19
  });
19
- function validateJexl(data) {
20
- try {
21
- for (const line of data
22
- .split('\n')
23
- .map(l => l.trim())
24
- .filter(Boolean)) {
25
- stringToJexlExpression(line);
26
- }
27
- return undefined;
28
- }
29
- catch (e) {
30
- console.error(e);
31
- return e;
32
- }
20
+ function checkJexl(code) {
21
+ stringToJexlExpression(code);
33
22
  }
34
- export default function AddFiltersDialog({ model, handleClose, }) {
23
+ const AddFiltersDialog = observer(function AddFiltersDialog({ model, handleClose, }) {
35
24
  const { classes } = useStyles();
36
- const { activeFilters } = model;
37
- const [data, setData] = useState(activeFilters.join('\n'));
38
- const error = useMemo(() => validateJexl(data), [data]);
39
- return (_jsxs(Dialog, { maxWidth: "xl", open: true, onClose: handleClose, title: "Add track filters", children: [_jsxs(DialogContent, { children: [_jsxs("div", { children: ["Add filters, in jexl format, one per line, starting with the string jexl:. Examples:", ' ', _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("code", { children: "jexl:get(feature,'name')=='BRCA1'" }), " - show only feature where the name attribute is BRCA1"] }), _jsxs("li", { children: [_jsx("code", { children: "jexl:get(feature,'type')=='gene'" }), " - show only gene type features in a GFF that has many other feature types"] }), _jsxs("li", { children: [_jsx("code", { children: "jexl:get(feature,'score') > 400" }), " - show only features that have a score greater than 400"] }), _jsxs("li", { children: [_jsx("code", { children: "jexl:get(feature,'end') - get(feature,'start') < 1000000" }), ' ', "- show only features with length less than 1Mbp"] })] })] }), error ? _jsx("p", { className: classes.error, children: `${error}` }) : null, _jsx(TextField, { variant: "outlined", multiline: true, minRows: 5, maxRows: 10, className: classes.dialogContent, fullWidth: true, value: data, onChange: event => {
25
+ const { jexlFilters } = model;
26
+ const [data, setData] = useState((jexlFilters ?? []).join('\n'));
27
+ const [error, setError] = useState();
28
+ useEffect(() => {
29
+ try {
30
+ for (const line of data
31
+ .split('\n')
32
+ .map(line => line.trim())
33
+ .filter(line => !!line)) {
34
+ checkJexl(line);
35
+ }
36
+ setError(undefined);
37
+ }
38
+ catch (e) {
39
+ console.error(e);
40
+ setError(e);
41
+ }
42
+ }, [data]);
43
+ return (_jsxs(Dialog, { maxWidth: "xl", open: true, onClose: handleClose, title: "Add track filters", children: [_jsxs(DialogContent, { children: [_jsxs("div", { children: ["Add filters, in jexl format, one per line, starting with the string jexl:. Examples:", ' ', _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("code", { children: "jexl:get(feature,'name')=='BRCA1'" }), " - show only feature where the name attribute is BRCA1"] }), _jsxs("li", { children: [_jsx("code", { children: "jexl:startsWith(get(feature,'name'),'PREFIX')" }), " - show only feature where the string 'PREFIX' is the prefix of feature name. endsWith also works"] }), _jsxs("li", { children: [_jsx("code", { children: "jexl:includes(get(feature,'name'),'PREFIX')" }), " - show only feature where the string 'PREFIX' is the prefix of feature name"] }), _jsxs("li", { children: [_jsx("code", { children: "jexl:get(feature,'type')=='gene'" }), " - show only gene type features in a GFF that has many other feature types"] }), _jsxs("li", { children: [_jsx("code", { children: "jexl:get(feature,'score') > 400" }), " - show only features that have a score greater than 400"] }), _jsxs("li", { children: [_jsx("code", { children: "jexl:get(feature,'end') - get(feature,'start') < 1000000" }), ' ', "- show only features with length less than 1Mbp"] })] }), _jsxs("p", { children: ["Please see", ' ', _jsx("a", { href: "https://jbrowse.org/jb2/docs/config_guides/jexl/", children: "Jexl" }), ' ', "documentation for more information"] })] }), error ? _jsx("p", { className: classes.error, children: `${error}` }) : null, _jsx(TextField, { variant: "outlined", multiline: true, minRows: 5, maxRows: 10, className: classes.dialogContent, fullWidth: true, value: data, onChange: event => {
40
44
  setData(event.target.value);
41
45
  }, slotProps: {
42
46
  input: {
@@ -47,5 +51,8 @@ export default function AddFiltersDialog({ model, handleClose, }) {
47
51
  } })] }), _jsxs(DialogActions, { children: [_jsx(Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, disabled: !!error, onClick: () => {
48
52
  model.setJexlFilters(data.split('\n'));
49
53
  handleClose();
50
- }, children: "Submit" }), _jsx(Button, { variant: "contained", color: "secondary", onClick: handleClose, children: "Cancel" })] })] }));
51
- }
54
+ }, children: "Submit" }), _jsx(Button, { variant: "contained", color: "secondary", onClick: () => {
55
+ handleClose();
56
+ }, children: "Cancel" })] })] }));
57
+ });
58
+ export default AddFiltersDialog;
@@ -0,0 +1,13 @@
1
+ import type { FilterStats } from '../../VariantRPC/getLDMatrix.ts';
2
+ export default function LDFilterDialog({ model, handleClose, }: {
3
+ model: {
4
+ minorAlleleFrequencyFilter: number;
5
+ hweFilterThreshold: number;
6
+ callRateFilter: number;
7
+ filterStats?: FilterStats;
8
+ setMafFilter: (arg: number) => void;
9
+ setHweFilter: (arg: number) => void;
10
+ setCallRateFilter: (arg: number) => void;
11
+ };
12
+ handleClose: () => void;
13
+ }): import("react/jsx-runtime").JSX.Element;