@jbrowse/plugin-variants 4.0.3 → 4.1.1

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 (144) hide show
  1. package/esm/ChordVariantDisplay/models/stateModelFactory.d.ts +9 -0
  2. package/esm/LDDisplay/SharedLDConfigSchema.d.ts +102 -0
  3. package/esm/LDDisplay/SharedLDConfigSchema.js +83 -0
  4. package/esm/LDDisplay/afterAttach.d.ts +2 -0
  5. package/esm/LDDisplay/afterAttach.js +123 -0
  6. package/esm/LDDisplay/components/BaseDisplayComponent.d.ts +15 -0
  7. package/esm/LDDisplay/components/BaseDisplayComponent.js +39 -0
  8. package/esm/LDDisplay/components/LDColorLegend.d.ts +15 -0
  9. package/esm/LDDisplay/components/LDColorLegend.js +75 -0
  10. package/esm/LDDisplay/components/LDDisplayComponent.d.ts +5 -0
  11. package/esm/LDDisplay/components/LDDisplayComponent.js +203 -0
  12. package/esm/LDDisplay/components/LinesConnectingMatrixToGenomicPosition.d.ts +16 -0
  13. package/esm/LDDisplay/components/LinesConnectingMatrixToGenomicPosition.js +109 -0
  14. package/esm/LDDisplay/configSchema1.d.ts +115 -0
  15. package/esm/LDDisplay/configSchema1.js +16 -0
  16. package/esm/LDDisplay/configSchema2.d.ts +115 -0
  17. package/esm/LDDisplay/configSchema2.js +16 -0
  18. package/esm/LDDisplay/index.d.ts +2 -0
  19. package/esm/LDDisplay/index.js +35 -0
  20. package/esm/LDDisplay/renderSvg.d.ts +3 -0
  21. package/esm/LDDisplay/renderSvg.js +36 -0
  22. package/esm/LDDisplay/shared.d.ts +367 -0
  23. package/esm/LDDisplay/shared.js +467 -0
  24. package/esm/LDDisplay/stateModel1.d.ts +365 -0
  25. package/esm/LDDisplay/stateModel1.js +10 -0
  26. package/esm/LDDisplay/stateModel2.d.ts +365 -0
  27. package/esm/LDDisplay/stateModel2.js +10 -0
  28. package/esm/LDRenderer/LDRenderer.d.ts +30 -0
  29. package/esm/LDRenderer/LDRenderer.js +109 -0
  30. package/esm/LDRenderer/components/LDRendering.d.ts +2 -0
  31. package/esm/LDRenderer/components/LDRendering.js +4 -0
  32. package/esm/LDRenderer/configSchema.d.ts +8 -0
  33. package/esm/LDRenderer/configSchema.js +10 -0
  34. package/esm/LDRenderer/index.d.ts +2 -0
  35. package/esm/LDRenderer/index.js +11 -0
  36. package/esm/LDRenderer/makeImageData.d.ts +20 -0
  37. package/esm/LDRenderer/makeImageData.js +158 -0
  38. package/esm/LDRenderer/types.d.ts +8 -0
  39. package/esm/LDRenderer/types.js +1 -0
  40. package/esm/LDTrack/configSchema.d.ts +85 -0
  41. package/esm/LDTrack/configSchema.js +7 -0
  42. package/esm/LDTrack/index.d.ts +2 -0
  43. package/esm/LDTrack/index.js +14 -0
  44. package/esm/LinearVariantDisplay/model.d.ts +139 -42
  45. package/esm/LinearVariantDisplay/model.js +46 -8
  46. package/esm/MultiLinearVariantDisplay/configSchema.d.ts +27 -1
  47. package/esm/MultiLinearVariantDisplay/model.d.ts +2647 -58
  48. package/esm/MultiLinearVariantDisplay/model.js +6 -0
  49. package/esm/MultiLinearVariantDisplay/renderSvg.d.ts +10 -2
  50. package/esm/MultiLinearVariantMatrixDisplay/configSchema.d.ts +25 -0
  51. package/esm/MultiLinearVariantMatrixDisplay/configSchema.js +26 -0
  52. package/esm/MultiLinearVariantMatrixDisplay/model.d.ts +2648 -59
  53. package/esm/MultiLinearVariantMatrixDisplay/model.js +6 -0
  54. package/esm/MultiLinearVariantMatrixRenderer/MultiLinearVariantMatrixRenderer.d.ts +2 -2
  55. package/esm/MultiLinearVariantMatrixRenderer/MultiLinearVariantMatrixRenderer.js +11 -9
  56. package/esm/MultiLinearVariantMatrixRenderer/components/MultiLinearVariantMatrixRendering.d.ts +8 -0
  57. package/esm/MultiLinearVariantMatrixRenderer/components/MultiLinearVariantMatrixRendering.js +14 -2
  58. package/esm/MultiLinearVariantMatrixRenderer/makeImageData.js +14 -8
  59. package/esm/MultiLinearVariantRenderer/MultiVariantRenderer.d.ts +2 -2
  60. package/esm/MultiLinearVariantRenderer/MultiVariantRenderer.js +4 -3
  61. package/esm/MultiLinearVariantRenderer/components/MultiLinearVariantRendering.d.ts +4 -0
  62. package/esm/MultiLinearVariantRenderer/components/MultiLinearVariantRendering.js +23 -2
  63. package/esm/MultiLinearVariantRenderer/makeImageData.js +8 -3
  64. package/esm/PlinkLDAdapter/PlinkLDAdapter.d.ts +25 -0
  65. package/esm/PlinkLDAdapter/PlinkLDAdapter.js +147 -0
  66. package/esm/PlinkLDAdapter/PlinkLDTabixAdapter.d.ts +24 -0
  67. package/esm/PlinkLDAdapter/PlinkLDTabixAdapter.js +156 -0
  68. package/esm/PlinkLDAdapter/configSchema.d.ts +10 -0
  69. package/esm/PlinkLDAdapter/configSchema.js +25 -0
  70. package/esm/PlinkLDAdapter/configSchemaTabix.d.ts +24 -0
  71. package/esm/PlinkLDAdapter/configSchemaTabix.js +46 -0
  72. package/esm/PlinkLDAdapter/index.d.ts +2 -0
  73. package/esm/PlinkLDAdapter/index.js +25 -0
  74. package/esm/PlinkLDAdapter/types.d.ts +29 -0
  75. package/esm/PlinkLDAdapter/types.js +1 -0
  76. package/esm/VariantFeatureWidget/VariantSampleGrid/VariantSampleGrid.js +1 -1
  77. package/esm/VariantRPC/MultiVariantGetFeatureDetails.d.ts +14 -0
  78. package/esm/VariantRPC/MultiVariantGetFeatureDetails.js +15 -0
  79. package/esm/VariantRPC/executeClusterGenotypeMatrix.d.ts +3 -1
  80. package/esm/VariantRPC/executeClusterGenotypeMatrix.js +8 -4
  81. package/esm/VariantRPC/getLDMatrix.d.ts +48 -0
  82. package/esm/VariantRPC/getLDMatrix.js +388 -0
  83. package/esm/VariantRPC/getLDMatrixFromPlink.d.ts +16 -0
  84. package/esm/VariantRPC/getLDMatrixFromPlink.js +105 -0
  85. package/esm/VariantRPC/getPhasedGenotypeMatrix.d.ts +20 -0
  86. package/esm/VariantRPC/getPhasedGenotypeMatrix.js +50 -0
  87. package/esm/VariantRPC/types.d.ts +3 -0
  88. package/esm/VcfAdapter/VcfAdapter.d.ts +1 -1
  89. package/esm/VcfAdapter/VcfAdapter.js +1 -2
  90. package/esm/VcfExtensionPoints/index.js +29 -3
  91. package/esm/VcfFeature/index.d.ts +2 -1
  92. package/esm/VcfFeature/index.js +4 -2
  93. package/esm/index.d.ts +1 -0
  94. package/esm/index.js +23 -0
  95. package/esm/shared/MultiVariantBaseModel.d.ts +2638 -53
  96. package/esm/shared/MultiVariantBaseModel.js +100 -47
  97. package/esm/shared/SharedVariantConfigSchema.d.ts +27 -1
  98. package/esm/shared/SharedVariantConfigSchema.js +28 -1
  99. package/esm/shared/VariantFeatureCache.d.ts +27 -0
  100. package/esm/shared/VariantFeatureCache.js +48 -0
  101. package/esm/shared/VariantRendererType.d.ts +23 -0
  102. package/esm/shared/VariantRendererType.js +15 -0
  103. package/esm/shared/applyColorPalette.d.ts +9 -0
  104. package/esm/shared/applyColorPalette.js +23 -0
  105. package/esm/shared/colorByAutorun.d.ts +10 -0
  106. package/esm/shared/colorByAutorun.js +39 -0
  107. package/esm/shared/components/AddFiltersDialog.d.ts +3 -3
  108. package/esm/shared/components/AddFiltersDialog.js +29 -22
  109. package/esm/shared/components/LDFilterDialog.d.ts +13 -0
  110. package/esm/shared/components/LDFilterDialog.js +102 -0
  111. package/esm/shared/components/MAFFilterDialog.js +23 -16
  112. package/esm/shared/components/MultiVariantClusterDialog/ClusterDialogAuto.js +19 -6
  113. package/esm/shared/components/MultiVariantClusterDialog/types.d.ts +4 -1
  114. package/esm/shared/components/MultiVariantColorLegend.js +4 -4
  115. package/esm/shared/components/MultiVariantLegendBar.js +1 -1
  116. package/esm/shared/components/MultiVariantTooltip.d.ts +1 -0
  117. package/esm/shared/components/MultiVariantTooltip.js +2 -2
  118. package/esm/shared/components/RecombinationTrack.d.ts +21 -0
  119. package/esm/shared/components/RecombinationTrack.js +54 -0
  120. package/esm/shared/components/RecombinationYScaleBar.d.ts +7 -0
  121. package/esm/shared/components/RecombinationYScaleBar.js +34 -0
  122. package/esm/shared/components/RectBg.js +1 -1
  123. package/esm/shared/components/SetColorDialogRowPalettizer.d.ts +3 -8
  124. package/esm/shared/components/SetColorDialogRowPalettizer.js +2 -14
  125. package/esm/shared/components/SourcesDataGrid.js +4 -4
  126. package/esm/shared/components/TreeSidebar.js +11 -1
  127. package/esm/shared/drawAlleleCount.js +9 -0
  128. package/esm/shared/drawPhased.d.ts +1 -1
  129. package/esm/shared/drawPhased.js +31 -2
  130. package/esm/shared/getMultiVariantFeaturesAutorun.d.ts +1 -0
  131. package/esm/shared/getMultiVariantFeaturesAutorun.js +3 -0
  132. package/esm/shared/getMultiVariantSourcesAutorun.d.ts +1 -0
  133. package/esm/shared/getMultiVariantSourcesAutorun.js +3 -0
  134. package/esm/shared/getSources.d.ts +5 -9
  135. package/esm/shared/getSources.js +30 -25
  136. package/esm/shared/mafFilterUtils.d.ts +5 -0
  137. package/esm/shared/mafFilterUtils.js +17 -0
  138. package/esm/shared/minorAlleleFrequencyUtils.d.ts +2 -0
  139. package/esm/shared/minorAlleleFrequencyUtils.js +259 -17
  140. package/esm/shared/setupMultiVariantAutoruns.js +2 -0
  141. package/esm/shared/treeDrawingAutorun.d.ts +1 -0
  142. package/esm/shared/treeDrawingAutorun.js +7 -1
  143. package/esm/shared/types.d.ts +1 -2
  144. package/package.json +12 -11
@@ -0,0 +1,203 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
+ import BaseTooltip from '@jbrowse/core/ui/BaseTooltip';
4
+ import { getContainingView } from '@jbrowse/core/util';
5
+ import Flatbush from '@jbrowse/core/util/flatbush';
6
+ import { observer } from 'mobx-react';
7
+ import BaseDisplayComponent from "./BaseDisplayComponent.js";
8
+ import LDColorLegend from "./LDColorLegend.js";
9
+ import LinesConnectingMatrixToGenomicPosition, { VariantLabels, Wrapper, } from "./LinesConnectingMatrixToGenomicPosition.js";
10
+ import RecombinationTrack from "../../shared/components/RecombinationTrack.js";
11
+ import RecombinationYScaleBar from "../../shared/components/RecombinationYScaleBar.js";
12
+ const SQRT2 = Math.sqrt(2);
13
+ function LDTooltip({ item, x, y, ldMetric, signedLD, }) {
14
+ let metricLabel;
15
+ if (ldMetric === 'dprime') {
16
+ metricLabel = "D'";
17
+ }
18
+ else {
19
+ metricLabel = signedLD ? 'R' : 'R²';
20
+ }
21
+ return (_jsxs(BaseTooltip, { clientPoint: { x: x + 15, y }, children: [_jsx("div", { children: item.snp1.id }), _jsx("div", { children: item.snp2.id }), _jsxs("div", { children: [metricLabel, ": ", item.ldValue.toFixed(3)] })] }));
22
+ }
23
+ function Crosshairs({ hoveredItem, cellWidth, genomicX1, genomicX2, yScalar, lineZoneHeight, tickHeight, width, height, useGenomicPositions, snps, regionStart, bpPerPx, canvasOffset, }) {
24
+ const { i, j } = hoveredItem;
25
+ const toScreen = (x, y) => {
26
+ const rx = (x + y) / SQRT2;
27
+ const ry = (y - x) / SQRT2;
28
+ return { x: rx, y: ry * yScalar + lineZoneHeight };
29
+ };
30
+ let hoveredCenter;
31
+ let snpJPos;
32
+ let snpIPos;
33
+ if (useGenomicPositions && snps.length > 0) {
34
+ const getBoundary = (idx) => {
35
+ const snpPos = snps[idx].start;
36
+ const prevPos = idx > 0 ? snps[idx - 1].start : regionStart;
37
+ const boundaryPos = (prevPos + snpPos) / 2;
38
+ return (boundaryPos - regionStart) / bpPerPx / SQRT2;
39
+ };
40
+ const getNextBoundary = (idx) => {
41
+ if (idx + 1 < snps.length) {
42
+ const snpPos = snps[idx].start;
43
+ const nextPos = snps[idx + 1].start;
44
+ return ((snpPos + nextPos) / 2 - regionStart) / bpPerPx / SQRT2;
45
+ }
46
+ const lastSnpPos = snps[snps.length - 1].start;
47
+ return (lastSnpPos + 50 * bpPerPx - regionStart) / bpPerPx / SQRT2;
48
+ };
49
+ const jBoundary = getBoundary(j);
50
+ const iBoundary = getBoundary(i);
51
+ const jNextBoundary = getNextBoundary(j);
52
+ const iNextBoundary = getNextBoundary(i);
53
+ const cellCenterX = (jBoundary + jNextBoundary) / 2;
54
+ const cellCenterY = (iBoundary + iNextBoundary) / 2;
55
+ hoveredCenter = toScreen(cellCenterX, cellCenterY);
56
+ snpJPos = { x: genomicX1, y: lineZoneHeight };
57
+ snpIPos = { x: genomicX2, y: lineZoneHeight };
58
+ }
59
+ else {
60
+ const w = cellWidth;
61
+ hoveredCenter = toScreen((j + 0.5) * w, (i + 0.5) * w);
62
+ snpJPos = toScreen((j + 0.5) * w, (j + 0.5) * w);
63
+ snpIPos = toScreen((i + 0.5) * w, (i + 0.5) * w);
64
+ }
65
+ return (_jsxs("svg", { style: {
66
+ position: 'absolute',
67
+ left: canvasOffset,
68
+ top: 0,
69
+ width,
70
+ height,
71
+ pointerEvents: 'none',
72
+ }, children: [_jsx("path", { stroke: "rgba(0, 0, 0, 0.6)", strokeWidth: 1, fill: "none", d: `M ${snpJPos.x} ${snpJPos.y} L ${hoveredCenter.x} ${hoveredCenter.y} L ${snpIPos.x} ${snpIPos.y}` }), _jsxs("g", { stroke: "#e00", strokeWidth: "1.5", fill: "none", children: [!useGenomicPositions ? (_jsxs(_Fragment, { children: [_jsx("path", { d: `M ${snpJPos.x} ${snpJPos.y} L ${genomicX1} ${tickHeight}` }), _jsx("path", { d: `M ${snpIPos.x} ${snpIPos.y} L ${genomicX2} ${tickHeight}` })] })) : null, _jsx("path", { d: `M ${genomicX1} 0 L ${genomicX1} ${tickHeight}` }), _jsx("path", { d: `M ${genomicX2} 0 L ${genomicX2} ${tickHeight}` })] })] }));
73
+ }
74
+ function screenToUnrotated(screenX, screenY, yScalar, lineZoneHeight) {
75
+ const matrixY = screenY - lineZoneHeight;
76
+ const scaledY = matrixY / yScalar;
77
+ const x = (screenX - scaledY) / SQRT2;
78
+ const y = (screenX + scaledY) / SQRT2;
79
+ return { x, y };
80
+ }
81
+ const LDCanvas = observer(function LDCanvas({ model, }) {
82
+ const view = getContainingView(model);
83
+ const width = Math.round(view.dynamicBlocks.totalWidthPx);
84
+ const { fullyDrawn, flatbush, flatbushItems, yScalar, cellWidth, showLegend, ldMetric, lineZoneHeight, fitToHeight, ldCanvasHeight, useGenomicPositions, snps, lastDrawnOffsetPx, signedLD, } = model;
85
+ const triangleHeight = width / 2;
86
+ const canvasOnlyHeight = fitToHeight ? ldCanvasHeight : triangleHeight;
87
+ const containerHeight = canvasOnlyHeight + lineZoneHeight;
88
+ const [hoveredItem, setHoveredItem] = useState();
89
+ const [mousePosition, setMousePosition] = useState();
90
+ const containerRef = useRef(null);
91
+ const region = view.dynamicBlocks.contentBlocks[0];
92
+ const bpPerPx = view.bpPerPx;
93
+ const genomicX1 = hoveredItem && region
94
+ ? (hoveredItem.snp2.start - region.start) / bpPerPx
95
+ : undefined;
96
+ const genomicX2 = hoveredItem && region
97
+ ? (hoveredItem.snp1.start - region.start) / bpPerPx
98
+ : undefined;
99
+ const canvasOffset = view.offsetPx >= 0
100
+ ? (lastDrawnOffsetPx ?? 0) - view.offsetPx
101
+ : Math.max(0, -view.offsetPx);
102
+ const guideOffset = canvasOffset;
103
+ useEffect(() => {
104
+ if (genomicX1 !== undefined &&
105
+ genomicX2 !== undefined &&
106
+ model.showVerticalGuides) {
107
+ view.setVolatileGuides([
108
+ { xPos: genomicX1 + guideOffset },
109
+ { xPos: genomicX2 + guideOffset },
110
+ ]);
111
+ }
112
+ else {
113
+ view.setVolatileGuides([]);
114
+ }
115
+ return () => {
116
+ view.setVolatileGuides([]);
117
+ };
118
+ }, [genomicX1, genomicX2, model.showVerticalGuides, view, guideOffset]);
119
+ const flatbushIndex = useMemo(() => (flatbush ? Flatbush.from(flatbush) : null), [flatbush]);
120
+ const cb = useCallback((ref) => {
121
+ model.setRef(ref);
122
+ }, [model, width, canvasOnlyHeight]);
123
+ const onMouseMove = useCallback((event) => {
124
+ const container = containerRef.current;
125
+ if (!container || !flatbushIndex || !flatbushItems.length) {
126
+ setHoveredItem(undefined);
127
+ setMousePosition(undefined);
128
+ return;
129
+ }
130
+ const rect = container.getBoundingClientRect();
131
+ const mouseCanvasOffset = canvasOffset;
132
+ const screenX = event.clientX - rect.left - mouseCanvasOffset;
133
+ const screenY = event.clientY - rect.top;
134
+ setMousePosition({ x: event.clientX, y: event.clientY });
135
+ if (screenY < lineZoneHeight) {
136
+ setHoveredItem(undefined);
137
+ return;
138
+ }
139
+ const { x, y } = screenToUnrotated(screenX, screenY, yScalar, lineZoneHeight);
140
+ const results = flatbushIndex.search(x - 1, y - 1, x + 1, y + 1);
141
+ if (results.length > 0) {
142
+ const item = flatbushItems[results[0]];
143
+ setHoveredItem(item);
144
+ }
145
+ else {
146
+ setHoveredItem(undefined);
147
+ }
148
+ }, [flatbushIndex, flatbushItems, yScalar, lineZoneHeight, canvasOffset]);
149
+ const onMouseLeave = useCallback(() => {
150
+ setHoveredItem(undefined);
151
+ setMousePosition(undefined);
152
+ }, []);
153
+ return (_jsxs("div", { ref: containerRef, style: {
154
+ cursor: hoveredItem && mousePosition ? 'crosshair' : undefined,
155
+ position: 'relative',
156
+ width,
157
+ height: containerHeight,
158
+ overflow: 'hidden',
159
+ }, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, children: [_jsx("canvas", { "data-testid": `ld_canvas${fullyDrawn ? '_done' : ''}`, ref: cb, style: {
160
+ width,
161
+ height: canvasOnlyHeight,
162
+ position: 'absolute',
163
+ left: canvasOffset,
164
+ top: lineZoneHeight,
165
+ }, width: width * 2, height: canvasOnlyHeight * 2 }), hoveredItem && genomicX1 !== undefined && genomicX2 !== undefined ? (_jsx(Crosshairs, { hoveredItem: hoveredItem, cellWidth: cellWidth, genomicX1: genomicX1, genomicX2: genomicX2, yScalar: yScalar, lineZoneHeight: lineZoneHeight, tickHeight: model.tickHeight, width: width, height: containerHeight, useGenomicPositions: useGenomicPositions, snps: snps, regionStart: region?.start ?? 0, bpPerPx: bpPerPx, canvasOffset: canvasOffset })) : null, hoveredItem && mousePosition ? (_jsx(LDTooltip, { item: hoveredItem, x: mousePosition.x, y: mousePosition.y, ldMetric: ldMetric, signedLD: signedLD })) : null, showLegend ? (_jsx(LDColorLegend, { ldMetric: ldMetric, signedLD: signedLD })) : null, useGenomicPositions ? (_jsx(Wrapper, { model: model, children: _jsx(VariantLabels, { model: model }) })) : (_jsx(LinesConnectingMatrixToGenomicPosition, { model: model })), model.showRecombination && model.recombination ? (_jsxs("div", { style: {
166
+ position: 'absolute',
167
+ left: canvasOffset,
168
+ top: lineZoneHeight / 2,
169
+ width,
170
+ height: lineZoneHeight / 2,
171
+ pointerEvents: 'none',
172
+ }, children: [_jsx(RecombinationTrack, { model: model, width: width, height: lineZoneHeight / 2, useGenomicPositions: useGenomicPositions, regionStart: region?.start, bpPerPx: bpPerPx }), _jsx(RecombinationYScaleBar, { height: lineZoneHeight / 2, maxValue: Math.max(...model.recombination.values, 0.1) })] })) : null] }));
173
+ });
174
+ const LDDisplayContent = observer(function LDDisplayContent({ model, }) {
175
+ const view = getContainingView(model);
176
+ const width = Math.round(view.dynamicBlocks.totalWidthPx);
177
+ const { height, showLDTriangle, showRecombination } = model;
178
+ if (view.bpPerPx > 1000) {
179
+ return (_jsx("div", { style: {
180
+ width,
181
+ height,
182
+ display: 'flex',
183
+ alignItems: 'center',
184
+ justifyContent: 'center',
185
+ color: '#666',
186
+ }, children: "Zoom in to see LD data" }));
187
+ }
188
+ if (!showLDTriangle && !showRecombination) {
189
+ return (_jsx("div", { style: {
190
+ width,
191
+ height,
192
+ display: 'flex',
193
+ alignItems: 'center',
194
+ justifyContent: 'center',
195
+ color: '#666',
196
+ }, children: "Enable LD triangle or recombination track in display settings" }));
197
+ }
198
+ return (_jsx("div", { style: { position: 'relative', width, height }, children: showLDTriangle ? _jsx(LDCanvas, { model: model }) : null }));
199
+ });
200
+ const LDDisplayComponent = observer(function LDDisplayComponent({ model, }) {
201
+ return (_jsx(BaseDisplayComponent, { model: model, children: _jsx(LDDisplayContent, { model: model }) }));
202
+ });
203
+ export default LDDisplayComponent;
@@ -0,0 +1,16 @@
1
+ import type { SharedLDModel } from '../shared.ts';
2
+ export declare const Wrapper: ({ children, model, exportSVG, yOffset, }: {
3
+ model: SharedLDModel;
4
+ children: React.ReactNode;
5
+ exportSVG?: boolean;
6
+ yOffset?: number;
7
+ }) => import("react/jsx-runtime").JSX.Element;
8
+ export declare const VariantLabels: ({ model, }: {
9
+ model: SharedLDModel;
10
+ }) => import("react/jsx-runtime").JSX.Element | null;
11
+ declare const LinesConnectingMatrixToGenomicPosition: ({ model, exportSVG, yOffset, }: {
12
+ model: SharedLDModel;
13
+ exportSVG?: boolean;
14
+ yOffset?: number;
15
+ }) => import("react/jsx-runtime").JSX.Element | null;
16
+ export default LinesConnectingMatrixToGenomicPosition;
@@ -0,0 +1,109 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, isValidElement, useState } from 'react';
3
+ import { ResizeHandle, SanitizedHTML } from '@jbrowse/core/ui';
4
+ import BaseTooltip from '@jbrowse/core/ui/BaseTooltip';
5
+ import { getContainingView, getSession, getStrokeProps, } from '@jbrowse/core/util';
6
+ import { makeStyles } from '@jbrowse/core/util/tss-react';
7
+ import { alpha, useTheme } from '@mui/material';
8
+ import { observer } from 'mobx-react';
9
+ const useStyles = makeStyles()(theme => ({
10
+ resizeHandle: {
11
+ height: 5,
12
+ boxSizing: 'border-box',
13
+ background: 'transparent',
14
+ '&:hover': {
15
+ background: theme.palette.divider,
16
+ },
17
+ },
18
+ }));
19
+ export const Wrapper = observer(function Wrapper({ children, model, exportSVG, yOffset = 0, }) {
20
+ const { height } = model;
21
+ const { width, offsetPx } = getContainingView(model);
22
+ const left = Math.max(0, -offsetPx);
23
+ return exportSVG ? (_jsx("g", { transform: `translate(${left} ${yOffset})`, children: children })) : (_jsx("svg", { style: {
24
+ position: 'absolute',
25
+ top: 0,
26
+ left,
27
+ height,
28
+ width,
29
+ }, children: children }));
30
+ });
31
+ function getGenomicX(view, assembly, snp, offsetAdjustment) {
32
+ return ((view.bpToPx({
33
+ refName: assembly.getCanonicalRefName2(snp.refName),
34
+ coord: snp.start,
35
+ })?.offsetPx || 0) - offsetAdjustment);
36
+ }
37
+ const TooltipContents = forwardRef(function TooltipContents2({ message }, ref) {
38
+ return (_jsx("div", { ref: ref, children: isValidElement(message) ? (message) : message ? (_jsx(SanitizedHTML, { html: String(message) })) : null }));
39
+ });
40
+ const LineTooltip = observer(function LineTooltip({ contents, }) {
41
+ return contents ? (_jsx(BaseTooltip, { children: _jsx(TooltipContents, { message: contents }) })) : null;
42
+ });
43
+ export const VariantLabels = observer(function VariantLabels({ model, }) {
44
+ const theme = useTheme();
45
+ const { assemblyManager } = getSession(model);
46
+ const view = getContainingView(model);
47
+ const { snps, showLabels } = model;
48
+ const { offsetPx, assemblyNames } = view;
49
+ const assembly = assemblyManager.get(assemblyNames[0]);
50
+ const offsetAdj = Math.max(offsetPx, 0);
51
+ if (!assembly || snps.length === 0 || !showLabels) {
52
+ return null;
53
+ }
54
+ return (_jsx(_Fragment, { children: snps.map((snp, i) => {
55
+ const genomicX = getGenomicX(view, assembly, snp, offsetAdj);
56
+ return (_jsx("text", { x: genomicX, y: 0, transform: `rotate(-90, ${genomicX}, 0)`, fontSize: 10, textAnchor: "end", dominantBaseline: "middle", fill: theme.palette.text.primary, style: { pointerEvents: 'none' }, children: snp.id || 'NOLABEL' }, `${snp.id}-${i}`));
57
+ }) }));
58
+ });
59
+ const AllLines = observer(function AllLines({ model, setMouseOverLine, }) {
60
+ const theme = useTheme();
61
+ const { assemblyManager } = getSession(model);
62
+ const view = getContainingView(model);
63
+ const { lineZoneHeight, snps, tickHeight } = model;
64
+ const { offsetPx, assemblyNames, dynamicBlocks } = view;
65
+ const assembly = assemblyManager.get(assemblyNames[0]);
66
+ const b0 = dynamicBlocks.contentBlocks[0]?.widthPx || 0;
67
+ const n = snps.length;
68
+ const offsetAdj = Math.max(offsetPx, 0);
69
+ const strokeProps = getStrokeProps(alpha(theme.palette.text.primary, 0.4));
70
+ if (!assembly || n === 0) {
71
+ return null;
72
+ }
73
+ return (_jsxs(_Fragment, { children: [snps.map((snp, i) => {
74
+ const genomicX = getGenomicX(view, assembly, snp, offsetAdj);
75
+ const matrixX = ((i + 0.5) * b0) / n;
76
+ return (_jsxs("g", { onMouseEnter: () => {
77
+ setMouseOverLine({ snp, idx: i, genomicX });
78
+ }, onMouseLeave: () => {
79
+ setMouseOverLine(undefined);
80
+ }, children: [_jsx("line", { ...strokeProps, strokeWidth: 1, x1: matrixX, x2: genomicX, y1: lineZoneHeight, y2: tickHeight }), _jsx("line", { ...strokeProps, strokeWidth: 1, x1: genomicX, x2: genomicX, y1: 0, y2: tickHeight })] }, `${snp.id}-${i}`));
81
+ }), _jsx(VariantLabels, { model: model })] }));
82
+ });
83
+ const LinesConnectingMatrixToGenomicPosition = observer(function LinesConnectingMatrixToGenomicPosition({ model, exportSVG, yOffset = 0, }) {
84
+ const { classes } = useStyles();
85
+ const view = getContainingView(model);
86
+ const [mouseOverLine, setMouseOverLine] = useState();
87
+ const { lineZoneHeight, snps } = model;
88
+ const { dynamicBlocks } = view;
89
+ const b0 = dynamicBlocks.contentBlocks[0]?.widthPx || 0;
90
+ const n = snps.length;
91
+ if (n === 0) {
92
+ return null;
93
+ }
94
+ const highlightMatrixX = mouseOverLine
95
+ ? ((mouseOverLine.idx + 0.5) * b0) / n
96
+ : 0;
97
+ return (_jsxs(_Fragment, { children: [_jsxs(Wrapper, { exportSVG: exportSVG, model: model, yOffset: yOffset, children: [_jsx(AllLines, { model: model, setMouseOverLine: setMouseOverLine }), mouseOverLine ? (_jsxs(_Fragment, { children: [_jsx("line", { stroke: "#f00c", strokeWidth: 2, style: {
98
+ pointerEvents: 'none',
99
+ }, x1: highlightMatrixX, x2: mouseOverLine.genomicX, y1: lineZoneHeight, y2: model.tickHeight }), _jsx("line", { stroke: "#f00c", strokeWidth: 2, style: {
100
+ pointerEvents: 'none',
101
+ }, x1: mouseOverLine.genomicX, x2: mouseOverLine.genomicX, y1: 0, y2: model.tickHeight }), _jsx(LineTooltip, { contents: mouseOverLine.snp.id })] })) : null] }), !exportSVG ? (_jsx(ResizeHandle, { style: {
102
+ position: 'absolute',
103
+ top: lineZoneHeight - 4,
104
+ }, onDrag: d => {
105
+ model.setLineZoneHeight(lineZoneHeight + d);
106
+ return undefined;
107
+ }, className: classes.resizeHandle })) : null] }));
108
+ });
109
+ export default LinesConnectingMatrixToGenomicPosition;
@@ -0,0 +1,115 @@
1
+ import type PluginManager from '@jbrowse/core/PluginManager';
2
+ export default function configSchemaF(_pluginManager: PluginManager): import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaType<{
3
+ renderer: import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaType<{
4
+ maxHeight: {
5
+ type: string;
6
+ description: string;
7
+ defaultValue: number;
8
+ };
9
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaOptions<undefined, undefined>>;
10
+ height: {
11
+ type: string;
12
+ defaultValue: number;
13
+ };
14
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaOptions<import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaType<{
15
+ minorAlleleFrequencyFilter: {
16
+ type: string;
17
+ defaultValue: number;
18
+ };
19
+ lengthCutoffFilter: {
20
+ type: string;
21
+ defaultValue: number;
22
+ };
23
+ lineZoneHeight: {
24
+ type: string;
25
+ defaultValue: number;
26
+ };
27
+ ldMetric: {
28
+ type: string;
29
+ model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
30
+ defaultValue: string;
31
+ };
32
+ colorScheme: {
33
+ type: string;
34
+ defaultValue: string;
35
+ };
36
+ showLegend: {
37
+ type: string;
38
+ defaultValue: boolean;
39
+ };
40
+ showLDTriangle: {
41
+ type: string;
42
+ defaultValue: boolean;
43
+ };
44
+ showRecombination: {
45
+ type: string;
46
+ defaultValue: boolean;
47
+ };
48
+ recombinationZoneHeight: {
49
+ type: string;
50
+ defaultValue: number;
51
+ };
52
+ fitToHeight: {
53
+ type: string;
54
+ defaultValue: boolean;
55
+ };
56
+ hweFilterThreshold: {
57
+ type: string;
58
+ defaultValue: number;
59
+ };
60
+ callRateFilter: {
61
+ type: string;
62
+ defaultValue: number;
63
+ };
64
+ showVerticalGuides: {
65
+ type: string;
66
+ defaultValue: boolean;
67
+ };
68
+ showLabels: {
69
+ type: string;
70
+ defaultValue: boolean;
71
+ };
72
+ tickHeight: {
73
+ type: string;
74
+ defaultValue: number;
75
+ };
76
+ useGenomicPositions: {
77
+ type: string;
78
+ defaultValue: boolean;
79
+ };
80
+ signedLD: {
81
+ type: string;
82
+ defaultValue: boolean;
83
+ };
84
+ jexlFilters: {
85
+ type: string;
86
+ defaultValue: never[];
87
+ };
88
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaOptions<import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaType<{
89
+ maxFeatureScreenDensity: {
90
+ type: string;
91
+ description: string;
92
+ defaultValue: number;
93
+ };
94
+ fetchSizeLimit: {
95
+ type: string;
96
+ defaultValue: number;
97
+ description: string;
98
+ };
99
+ height: {
100
+ type: string;
101
+ defaultValue: number;
102
+ description: string;
103
+ };
104
+ mouseover: {
105
+ type: string;
106
+ description: string;
107
+ defaultValue: string;
108
+ contextVariable: string[];
109
+ };
110
+ jexlFilters: {
111
+ type: string;
112
+ description: string;
113
+ defaultValue: never[];
114
+ };
115
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaOptions<undefined, "displayId">>, undefined>>, undefined>>;
@@ -0,0 +1,16 @@
1
+ import { ConfigurationSchema } from '@jbrowse/core/configuration';
2
+ import sharedLDConfigFactory from "./SharedLDConfigSchema.js";
3
+ import configSchema from "../LDRenderer/configSchema.js";
4
+ function x() { }
5
+ export default function configSchemaF(_pluginManager) {
6
+ return ConfigurationSchema('LDDisplay', {
7
+ renderer: configSchema,
8
+ height: {
9
+ type: 'number',
10
+ defaultValue: 400,
11
+ },
12
+ }, {
13
+ baseConfiguration: sharedLDConfigFactory(),
14
+ explicitlyTyped: true,
15
+ });
16
+ }
@@ -0,0 +1,115 @@
1
+ import type PluginManager from '@jbrowse/core/PluginManager';
2
+ export default function configSchemaF(_pluginManager: PluginManager): import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaType<{
3
+ renderer: import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaType<{
4
+ maxHeight: {
5
+ type: string;
6
+ description: string;
7
+ defaultValue: number;
8
+ };
9
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaOptions<undefined, undefined>>;
10
+ height: {
11
+ type: string;
12
+ defaultValue: number;
13
+ };
14
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaOptions<import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaType<{
15
+ minorAlleleFrequencyFilter: {
16
+ type: string;
17
+ defaultValue: number;
18
+ };
19
+ lengthCutoffFilter: {
20
+ type: string;
21
+ defaultValue: number;
22
+ };
23
+ lineZoneHeight: {
24
+ type: string;
25
+ defaultValue: number;
26
+ };
27
+ ldMetric: {
28
+ type: string;
29
+ model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
30
+ defaultValue: string;
31
+ };
32
+ colorScheme: {
33
+ type: string;
34
+ defaultValue: string;
35
+ };
36
+ showLegend: {
37
+ type: string;
38
+ defaultValue: boolean;
39
+ };
40
+ showLDTriangle: {
41
+ type: string;
42
+ defaultValue: boolean;
43
+ };
44
+ showRecombination: {
45
+ type: string;
46
+ defaultValue: boolean;
47
+ };
48
+ recombinationZoneHeight: {
49
+ type: string;
50
+ defaultValue: number;
51
+ };
52
+ fitToHeight: {
53
+ type: string;
54
+ defaultValue: boolean;
55
+ };
56
+ hweFilterThreshold: {
57
+ type: string;
58
+ defaultValue: number;
59
+ };
60
+ callRateFilter: {
61
+ type: string;
62
+ defaultValue: number;
63
+ };
64
+ showVerticalGuides: {
65
+ type: string;
66
+ defaultValue: boolean;
67
+ };
68
+ showLabels: {
69
+ type: string;
70
+ defaultValue: boolean;
71
+ };
72
+ tickHeight: {
73
+ type: string;
74
+ defaultValue: number;
75
+ };
76
+ useGenomicPositions: {
77
+ type: string;
78
+ defaultValue: boolean;
79
+ };
80
+ signedLD: {
81
+ type: string;
82
+ defaultValue: boolean;
83
+ };
84
+ jexlFilters: {
85
+ type: string;
86
+ defaultValue: never[];
87
+ };
88
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaOptions<import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaType<{
89
+ maxFeatureScreenDensity: {
90
+ type: string;
91
+ description: string;
92
+ defaultValue: number;
93
+ };
94
+ fetchSizeLimit: {
95
+ type: string;
96
+ defaultValue: number;
97
+ description: string;
98
+ };
99
+ height: {
100
+ type: string;
101
+ defaultValue: number;
102
+ description: string;
103
+ };
104
+ mouseover: {
105
+ type: string;
106
+ description: string;
107
+ defaultValue: string;
108
+ contextVariable: string[];
109
+ };
110
+ jexlFilters: {
111
+ type: string;
112
+ description: string;
113
+ defaultValue: never[];
114
+ };
115
+ }, import("node_modules/@jbrowse/core/src/configuration/configurationSchema.ts").ConfigurationSchemaOptions<undefined, "displayId">>, undefined>>, undefined>>;
@@ -0,0 +1,16 @@
1
+ import { ConfigurationSchema } from '@jbrowse/core/configuration';
2
+ import sharedLDConfigFactory from "./SharedLDConfigSchema.js";
3
+ import configSchema from "../LDRenderer/configSchema.js";
4
+ function x() { }
5
+ export default function configSchemaF(_pluginManager) {
6
+ return ConfigurationSchema('LDTrackDisplay', {
7
+ renderer: configSchema,
8
+ height: {
9
+ type: 'number',
10
+ defaultValue: 400,
11
+ },
12
+ }, {
13
+ baseConfiguration: sharedLDConfigFactory(),
14
+ explicitlyTyped: true,
15
+ });
16
+ }
@@ -0,0 +1,2 @@
1
+ import type PluginManager from '@jbrowse/core/PluginManager';
2
+ export default function LDDisplayF(pluginManager: PluginManager): void;
@@ -0,0 +1,35 @@
1
+ import { lazy } from 'react';
2
+ import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType';
3
+ import configSchemaF1 from "./configSchema1.js";
4
+ import configSchemaF2 from "./configSchema2.js";
5
+ import stateModelFactory1 from "./stateModel1.js";
6
+ import stateModelFactory2 from "./stateModel2.js";
7
+ const LazyLDDisplayComponent = lazy(() => import("./components/LDDisplayComponent.js"));
8
+ export default function LDDisplayF(pluginManager) {
9
+ pluginManager.addDisplayType(() => {
10
+ const configSchema = configSchemaF1(pluginManager);
11
+ return new DisplayType({
12
+ name: 'LDDisplay',
13
+ displayName: 'LD heatmap display',
14
+ helpText: 'Displays a linkage disequilibrium (LD) heatmap showing pairwise R² values between variants computed directly from VCF genotypes',
15
+ configSchema,
16
+ stateModel: stateModelFactory1(configSchema),
17
+ trackType: 'VariantTrack',
18
+ viewType: 'LinearGenomeView',
19
+ ReactComponent: LazyLDDisplayComponent,
20
+ });
21
+ });
22
+ pluginManager.addDisplayType(() => {
23
+ const configSchema = configSchemaF2(pluginManager);
24
+ return new DisplayType({
25
+ name: 'LDTrackDisplay',
26
+ displayName: 'LD heatmap display',
27
+ helpText: 'Displays a linkage disequilibrium (LD) heatmap from pre-computed LD data (e.g., PLINK --r2 output)',
28
+ configSchema,
29
+ stateModel: stateModelFactory2(configSchema),
30
+ trackType: 'LDTrack',
31
+ viewType: 'LinearGenomeView',
32
+ ReactComponent: LazyLDDisplayComponent,
33
+ });
34
+ });
35
+ }
@@ -0,0 +1,3 @@
1
+ import type { SharedLDModel } from './shared.ts';
2
+ import type { ExportSvgDisplayOptions } from '@jbrowse/plugin-linear-genome-view';
3
+ export declare function renderSvg(self: SharedLDModel, opts: ExportSvgDisplayOptions): Promise<import("react/jsx-runtime").JSX.Element | null>;