@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.
- package/esm/LDDisplay/SharedLDConfigSchema.d.ts +102 -0
- package/esm/LDDisplay/SharedLDConfigSchema.js +83 -0
- package/esm/LDDisplay/afterAttach.d.ts +2 -0
- package/esm/LDDisplay/afterAttach.js +123 -0
- package/esm/LDDisplay/components/BaseDisplayComponent.d.ts +15 -0
- package/esm/LDDisplay/components/BaseDisplayComponent.js +39 -0
- package/esm/LDDisplay/components/LDColorLegend.d.ts +15 -0
- package/esm/LDDisplay/components/LDColorLegend.js +75 -0
- package/esm/LDDisplay/components/LDDisplayComponent.d.ts +5 -0
- package/esm/LDDisplay/components/LDDisplayComponent.js +203 -0
- package/esm/LDDisplay/components/LinesConnectingMatrixToGenomicPosition.d.ts +16 -0
- package/esm/LDDisplay/components/LinesConnectingMatrixToGenomicPosition.js +109 -0
- package/esm/LDDisplay/configSchema1.d.ts +115 -0
- package/esm/LDDisplay/configSchema1.js +16 -0
- package/esm/LDDisplay/configSchema2.d.ts +115 -0
- package/esm/LDDisplay/configSchema2.js +16 -0
- package/esm/LDDisplay/index.d.ts +2 -0
- package/esm/LDDisplay/index.js +35 -0
- package/esm/LDDisplay/renderSvg.d.ts +3 -0
- package/esm/LDDisplay/renderSvg.js +36 -0
- package/esm/LDDisplay/shared.d.ts +367 -0
- package/esm/LDDisplay/shared.js +467 -0
- package/esm/LDDisplay/stateModel1.d.ts +365 -0
- package/esm/LDDisplay/stateModel1.js +10 -0
- package/esm/LDDisplay/stateModel2.d.ts +365 -0
- package/esm/LDDisplay/stateModel2.js +10 -0
- package/esm/LDRenderer/LDRenderer.d.ts +30 -0
- package/esm/LDRenderer/LDRenderer.js +109 -0
- package/esm/LDRenderer/components/LDRendering.d.ts +2 -0
- package/esm/LDRenderer/components/LDRendering.js +4 -0
- package/esm/LDRenderer/configSchema.d.ts +8 -0
- package/esm/LDRenderer/configSchema.js +10 -0
- package/esm/LDRenderer/index.d.ts +2 -0
- package/esm/LDRenderer/index.js +11 -0
- package/esm/LDRenderer/makeImageData.d.ts +20 -0
- package/esm/LDRenderer/makeImageData.js +157 -0
- package/esm/LDRenderer/types.d.ts +8 -0
- package/esm/LDRenderer/types.js +1 -0
- package/esm/LDTrack/configSchema.d.ts +85 -0
- package/esm/LDTrack/configSchema.js +7 -0
- package/esm/LDTrack/index.d.ts +2 -0
- package/esm/LDTrack/index.js +14 -0
- package/esm/LinearVariantDisplay/model.d.ts +126 -42
- package/esm/LinearVariantDisplay/model.js +46 -8
- package/esm/MultiLinearVariantDisplay/configSchema.d.ts +27 -1
- package/esm/MultiLinearVariantDisplay/model.d.ts +2635 -31
- package/esm/MultiLinearVariantDisplay/model.js +6 -0
- package/esm/MultiLinearVariantDisplay/renderSvg.d.ts +10 -2
- package/esm/MultiLinearVariantMatrixDisplay/configSchema.d.ts +25 -0
- package/esm/MultiLinearVariantMatrixDisplay/configSchema.js +26 -0
- package/esm/MultiLinearVariantMatrixDisplay/model.d.ts +2636 -32
- package/esm/MultiLinearVariantMatrixDisplay/model.js +6 -0
- package/esm/MultiLinearVariantMatrixRenderer/MultiLinearVariantMatrixRenderer.d.ts +2 -2
- package/esm/MultiLinearVariantMatrixRenderer/MultiLinearVariantMatrixRenderer.js +11 -9
- package/esm/MultiLinearVariantMatrixRenderer/components/MultiLinearVariantMatrixRendering.d.ts +8 -0
- package/esm/MultiLinearVariantMatrixRenderer/components/MultiLinearVariantMatrixRendering.js +14 -2
- package/esm/MultiLinearVariantMatrixRenderer/makeImageData.js +8 -11
- package/esm/MultiLinearVariantRenderer/MultiVariantRenderer.d.ts +2 -2
- package/esm/MultiLinearVariantRenderer/MultiVariantRenderer.js +4 -3
- package/esm/MultiLinearVariantRenderer/components/MultiLinearVariantRendering.d.ts +4 -0
- package/esm/MultiLinearVariantRenderer/components/MultiLinearVariantRendering.js +23 -2
- package/esm/MultiLinearVariantRenderer/makeImageData.js +12 -12
- package/esm/PlinkLDAdapter/PlinkLDAdapter.d.ts +25 -0
- package/esm/PlinkLDAdapter/PlinkLDAdapter.js +147 -0
- package/esm/PlinkLDAdapter/PlinkLDTabixAdapter.d.ts +24 -0
- package/esm/PlinkLDAdapter/PlinkLDTabixAdapter.js +156 -0
- package/esm/PlinkLDAdapter/configSchema.d.ts +10 -0
- package/esm/PlinkLDAdapter/configSchema.js +25 -0
- package/esm/PlinkLDAdapter/configSchemaTabix.d.ts +24 -0
- package/esm/PlinkLDAdapter/configSchemaTabix.js +46 -0
- package/esm/PlinkLDAdapter/index.d.ts +2 -0
- package/esm/PlinkLDAdapter/index.js +25 -0
- package/esm/PlinkLDAdapter/types.d.ts +29 -0
- package/esm/PlinkLDAdapter/types.js +1 -0
- package/esm/VariantFeatureWidget/VariantSampleGrid/VariantSampleGrid.js +1 -1
- package/esm/VariantRPC/MultiVariantGetFeatureDetails.d.ts +14 -0
- package/esm/VariantRPC/MultiVariantGetFeatureDetails.js +15 -0
- package/esm/VariantRPC/MultiVariantGetGenotypeMatrix.js +4 -1
- package/esm/VariantRPC/MultiVariantGetSimplifiedFeatures.js +3 -3
- package/esm/VariantRPC/executeClusterGenotypeMatrix.js +6 -3
- package/esm/VariantRPC/getGenotypeMatrix.d.ts +2 -3
- package/esm/VariantRPC/getGenotypeMatrix.js +4 -5
- package/esm/VariantRPC/getLDMatrix.d.ts +47 -0
- package/esm/VariantRPC/getLDMatrix.js +387 -0
- package/esm/VariantRPC/getLDMatrixFromPlink.d.ts +16 -0
- package/esm/VariantRPC/getLDMatrixFromPlink.js +105 -0
- package/esm/VariantRPC/getPhasedGenotypeMatrix.d.ts +2 -3
- package/esm/VariantRPC/getPhasedGenotypeMatrix.js +4 -5
- package/esm/VariantRPC/types.d.ts +3 -0
- package/esm/VcfAdapter/VcfAdapter.d.ts +1 -1
- package/esm/VcfAdapter/VcfAdapter.js +1 -2
- package/esm/VcfExtensionPoints/index.js +29 -3
- package/esm/VcfFeature/index.d.ts +2 -1
- package/esm/VcfFeature/index.js +4 -2
- package/esm/index.d.ts +1 -0
- package/esm/index.js +23 -0
- package/esm/shared/MultiVariantBaseModel.d.ts +2626 -26
- package/esm/shared/MultiVariantBaseModel.js +88 -39
- package/esm/shared/SharedVariantConfigSchema.d.ts +27 -1
- package/esm/shared/SharedVariantConfigSchema.js +28 -1
- package/esm/shared/VariantFeatureCache.d.ts +27 -0
- package/esm/shared/VariantFeatureCache.js +48 -0
- package/esm/shared/VariantRendererType.d.ts +23 -0
- package/esm/shared/VariantRendererType.js +15 -0
- package/esm/shared/applyColorPalette.d.ts +9 -0
- package/esm/shared/applyColorPalette.js +23 -0
- package/esm/shared/colorByAutorun.d.ts +10 -0
- package/esm/shared/colorByAutorun.js +39 -0
- package/esm/shared/components/AddFiltersDialog.d.ts +3 -3
- package/esm/shared/components/AddFiltersDialog.js +29 -22
- package/esm/shared/components/LDFilterDialog.d.ts +13 -0
- package/esm/shared/components/LDFilterDialog.js +102 -0
- package/esm/shared/components/MAFFilterDialog.js +23 -16
- package/esm/shared/components/RecombinationTrack.d.ts +21 -0
- package/esm/shared/components/RecombinationTrack.js +54 -0
- package/esm/shared/components/RecombinationYScaleBar.d.ts +7 -0
- package/esm/shared/components/RecombinationYScaleBar.js +34 -0
- package/esm/shared/components/SetColorDialogRowPalettizer.d.ts +3 -8
- package/esm/shared/components/SetColorDialogRowPalettizer.js +2 -14
- package/esm/shared/drawAlleleCount.js +9 -0
- package/esm/shared/drawPhased.d.ts +1 -1
- package/esm/shared/drawPhased.js +31 -2
- package/esm/shared/mafFilterUtils.d.ts +5 -0
- package/esm/shared/mafFilterUtils.js +17 -0
- package/esm/shared/minorAlleleFrequencyUtils.d.ts +4 -2
- package/esm/shared/minorAlleleFrequencyUtils.js +261 -19
- package/esm/shared/setupMultiVariantAutoruns.js +2 -0
- package/package.json +11 -10
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
export default function sharedLDConfigFactory(): import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
2
|
+
minorAlleleFrequencyFilter: {
|
|
3
|
+
type: string;
|
|
4
|
+
defaultValue: number;
|
|
5
|
+
};
|
|
6
|
+
lengthCutoffFilter: {
|
|
7
|
+
type: string;
|
|
8
|
+
defaultValue: number;
|
|
9
|
+
};
|
|
10
|
+
lineZoneHeight: {
|
|
11
|
+
type: string;
|
|
12
|
+
defaultValue: number;
|
|
13
|
+
};
|
|
14
|
+
ldMetric: {
|
|
15
|
+
type: string;
|
|
16
|
+
model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
17
|
+
defaultValue: string;
|
|
18
|
+
};
|
|
19
|
+
colorScheme: {
|
|
20
|
+
type: string;
|
|
21
|
+
defaultValue: string;
|
|
22
|
+
};
|
|
23
|
+
showLegend: {
|
|
24
|
+
type: string;
|
|
25
|
+
defaultValue: boolean;
|
|
26
|
+
};
|
|
27
|
+
showLDTriangle: {
|
|
28
|
+
type: string;
|
|
29
|
+
defaultValue: boolean;
|
|
30
|
+
};
|
|
31
|
+
showRecombination: {
|
|
32
|
+
type: string;
|
|
33
|
+
defaultValue: boolean;
|
|
34
|
+
};
|
|
35
|
+
recombinationZoneHeight: {
|
|
36
|
+
type: string;
|
|
37
|
+
defaultValue: number;
|
|
38
|
+
};
|
|
39
|
+
fitToHeight: {
|
|
40
|
+
type: string;
|
|
41
|
+
defaultValue: boolean;
|
|
42
|
+
};
|
|
43
|
+
hweFilterThreshold: {
|
|
44
|
+
type: string;
|
|
45
|
+
defaultValue: number;
|
|
46
|
+
};
|
|
47
|
+
callRateFilter: {
|
|
48
|
+
type: string;
|
|
49
|
+
defaultValue: number;
|
|
50
|
+
};
|
|
51
|
+
showVerticalGuides: {
|
|
52
|
+
type: string;
|
|
53
|
+
defaultValue: boolean;
|
|
54
|
+
};
|
|
55
|
+
showLabels: {
|
|
56
|
+
type: string;
|
|
57
|
+
defaultValue: boolean;
|
|
58
|
+
};
|
|
59
|
+
tickHeight: {
|
|
60
|
+
type: string;
|
|
61
|
+
defaultValue: number;
|
|
62
|
+
};
|
|
63
|
+
useGenomicPositions: {
|
|
64
|
+
type: string;
|
|
65
|
+
defaultValue: boolean;
|
|
66
|
+
};
|
|
67
|
+
signedLD: {
|
|
68
|
+
type: string;
|
|
69
|
+
defaultValue: boolean;
|
|
70
|
+
};
|
|
71
|
+
jexlFilters: {
|
|
72
|
+
type: string;
|
|
73
|
+
defaultValue: never[];
|
|
74
|
+
};
|
|
75
|
+
}, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
76
|
+
maxFeatureScreenDensity: {
|
|
77
|
+
type: string;
|
|
78
|
+
description: string;
|
|
79
|
+
defaultValue: number;
|
|
80
|
+
};
|
|
81
|
+
fetchSizeLimit: {
|
|
82
|
+
type: string;
|
|
83
|
+
defaultValue: number;
|
|
84
|
+
description: string;
|
|
85
|
+
};
|
|
86
|
+
height: {
|
|
87
|
+
type: string;
|
|
88
|
+
defaultValue: number;
|
|
89
|
+
description: string;
|
|
90
|
+
};
|
|
91
|
+
mouseover: {
|
|
92
|
+
type: string;
|
|
93
|
+
description: string;
|
|
94
|
+
defaultValue: string;
|
|
95
|
+
contextVariable: string[];
|
|
96
|
+
};
|
|
97
|
+
jexlFilters: {
|
|
98
|
+
type: string;
|
|
99
|
+
description: string;
|
|
100
|
+
defaultValue: never[];
|
|
101
|
+
};
|
|
102
|
+
}, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>, undefined>>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { ConfigurationSchema } from '@jbrowse/core/configuration';
|
|
2
|
+
import { types } from '@jbrowse/mobx-state-tree';
|
|
3
|
+
import { baseLinearDisplayConfigSchema } from '@jbrowse/plugin-linear-genome-view';
|
|
4
|
+
export default function sharedLDConfigFactory() {
|
|
5
|
+
return ConfigurationSchema('SharedLDDisplay', {
|
|
6
|
+
minorAlleleFrequencyFilter: {
|
|
7
|
+
type: 'number',
|
|
8
|
+
defaultValue: 0.1,
|
|
9
|
+
},
|
|
10
|
+
lengthCutoffFilter: {
|
|
11
|
+
type: 'number',
|
|
12
|
+
defaultValue: Number.MAX_SAFE_INTEGER,
|
|
13
|
+
},
|
|
14
|
+
lineZoneHeight: {
|
|
15
|
+
type: 'number',
|
|
16
|
+
defaultValue: 100,
|
|
17
|
+
},
|
|
18
|
+
ldMetric: {
|
|
19
|
+
type: 'stringEnum',
|
|
20
|
+
model: types.enumeration('LDMetric', ['r2', 'dprime']),
|
|
21
|
+
defaultValue: 'r2',
|
|
22
|
+
},
|
|
23
|
+
colorScheme: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
defaultValue: '',
|
|
26
|
+
},
|
|
27
|
+
showLegend: {
|
|
28
|
+
type: 'boolean',
|
|
29
|
+
defaultValue: false,
|
|
30
|
+
},
|
|
31
|
+
showLDTriangle: {
|
|
32
|
+
type: 'boolean',
|
|
33
|
+
defaultValue: true,
|
|
34
|
+
},
|
|
35
|
+
showRecombination: {
|
|
36
|
+
type: 'boolean',
|
|
37
|
+
defaultValue: false,
|
|
38
|
+
},
|
|
39
|
+
recombinationZoneHeight: {
|
|
40
|
+
type: 'number',
|
|
41
|
+
defaultValue: 50,
|
|
42
|
+
},
|
|
43
|
+
fitToHeight: {
|
|
44
|
+
type: 'boolean',
|
|
45
|
+
defaultValue: false,
|
|
46
|
+
},
|
|
47
|
+
hweFilterThreshold: {
|
|
48
|
+
type: 'number',
|
|
49
|
+
defaultValue: 0,
|
|
50
|
+
},
|
|
51
|
+
callRateFilter: {
|
|
52
|
+
type: 'number',
|
|
53
|
+
defaultValue: 0,
|
|
54
|
+
},
|
|
55
|
+
showVerticalGuides: {
|
|
56
|
+
type: 'boolean',
|
|
57
|
+
defaultValue: true,
|
|
58
|
+
},
|
|
59
|
+
showLabels: {
|
|
60
|
+
type: 'boolean',
|
|
61
|
+
defaultValue: false,
|
|
62
|
+
},
|
|
63
|
+
tickHeight: {
|
|
64
|
+
type: 'number',
|
|
65
|
+
defaultValue: 6,
|
|
66
|
+
},
|
|
67
|
+
useGenomicPositions: {
|
|
68
|
+
type: 'boolean',
|
|
69
|
+
defaultValue: false,
|
|
70
|
+
},
|
|
71
|
+
signedLD: {
|
|
72
|
+
type: 'boolean',
|
|
73
|
+
defaultValue: false,
|
|
74
|
+
},
|
|
75
|
+
jexlFilters: {
|
|
76
|
+
type: 'stringArray',
|
|
77
|
+
defaultValue: [],
|
|
78
|
+
},
|
|
79
|
+
}, {
|
|
80
|
+
baseConfiguration: baseLinearDisplayConfigSchema,
|
|
81
|
+
explicitlyTyped: true,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { getContainingView, getRpcSessionId, getSession, isAbortException, } from '@jbrowse/core/util';
|
|
2
|
+
import { createStopToken, stopStopToken } from '@jbrowse/core/util/stopToken';
|
|
3
|
+
import { addDisposer, isAlive } from '@jbrowse/mobx-state-tree';
|
|
4
|
+
import { drawCanvasImageData } from '@jbrowse/plugin-linear-genome-view';
|
|
5
|
+
import { autorun, untracked } from 'mobx';
|
|
6
|
+
export function doAfterAttach(self) {
|
|
7
|
+
const performRender = async () => {
|
|
8
|
+
if (self.isMinimized) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (!self.showLDTriangle) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const view = getContainingView(self);
|
|
15
|
+
const { bpPerPx, dynamicBlocks } = view;
|
|
16
|
+
const regions = dynamicBlocks.contentBlocks;
|
|
17
|
+
if (!regions.length) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (bpPerPx > 1000) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const { adapterConfig } = self;
|
|
24
|
+
const renderProps = untracked(() => self.renderProps());
|
|
25
|
+
try {
|
|
26
|
+
const session = getSession(self);
|
|
27
|
+
const { rpcManager } = session;
|
|
28
|
+
const rpcSessionId = getRpcSessionId(self);
|
|
29
|
+
const previousToken = untracked(() => self.renderingStopToken);
|
|
30
|
+
if (previousToken) {
|
|
31
|
+
stopStopToken(previousToken);
|
|
32
|
+
}
|
|
33
|
+
const stopToken = createStopToken();
|
|
34
|
+
self.setRenderingStopToken(stopToken);
|
|
35
|
+
self.setLoading(true);
|
|
36
|
+
self.setCanvasDrawn(false);
|
|
37
|
+
const result = (await rpcManager.call(rpcSessionId, 'CoreRender', {
|
|
38
|
+
sessionId: rpcSessionId,
|
|
39
|
+
rendererType: 'LDRenderer',
|
|
40
|
+
regions: [...regions],
|
|
41
|
+
adapterConfig,
|
|
42
|
+
bpPerPx,
|
|
43
|
+
stopToken,
|
|
44
|
+
...renderProps,
|
|
45
|
+
}, {
|
|
46
|
+
statusCallback: (msg) => {
|
|
47
|
+
if (isAlive(self)) {
|
|
48
|
+
self.setStatusMessage(msg);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
}));
|
|
52
|
+
if (result.imageData) {
|
|
53
|
+
self.setRenderingImageData(result.imageData);
|
|
54
|
+
self.setLastDrawnOffsetPx(view.offsetPx);
|
|
55
|
+
self.setLastDrawnBpPerPx(view.bpPerPx);
|
|
56
|
+
}
|
|
57
|
+
self.setFlatbushData(result.flatbush, result.items ?? [], result.ldData?.snps ?? [], result.maxScore ?? 1, result.yScalar ?? 1, result.w ?? 0);
|
|
58
|
+
self.setFilterStats(result.filterStats);
|
|
59
|
+
self.setRecombination(result.recombination);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (!isAbortException(error)) {
|
|
63
|
+
console.error(error);
|
|
64
|
+
if (isAlive(self)) {
|
|
65
|
+
self.setError(error);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
if (isAlive(self)) {
|
|
71
|
+
self.setRenderingStopToken(undefined);
|
|
72
|
+
self.setLoading(false);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
addDisposer(self, autorun(() => {
|
|
77
|
+
if (self.isMinimized) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const view = getContainingView(self);
|
|
81
|
+
if (!view.initialized) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const { dynamicBlocks } = view;
|
|
85
|
+
const regions = dynamicBlocks.contentBlocks;
|
|
86
|
+
self.ldMetric;
|
|
87
|
+
self.minorAlleleFrequencyFilter;
|
|
88
|
+
self.lengthCutoffFilter;
|
|
89
|
+
self.hweFilterThreshold;
|
|
90
|
+
self.callRateFilter;
|
|
91
|
+
self.colorScheme;
|
|
92
|
+
self.showLDTriangle;
|
|
93
|
+
self.fitToHeight;
|
|
94
|
+
self.useGenomicPositions;
|
|
95
|
+
self.signedLD;
|
|
96
|
+
if (self.fitToHeight) {
|
|
97
|
+
self.ldCanvasHeight;
|
|
98
|
+
}
|
|
99
|
+
if (untracked(() => self.error) || !regions.length) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
performRender();
|
|
103
|
+
}, {
|
|
104
|
+
delay: 500,
|
|
105
|
+
name: 'LDDisplayRender',
|
|
106
|
+
}));
|
|
107
|
+
addDisposer(self, autorun(() => {
|
|
108
|
+
if (self.isMinimized) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const view = getContainingView(self);
|
|
112
|
+
if (!view.initialized) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const success = drawCanvasImageData(self.ref, self.renderingImageData);
|
|
116
|
+
if (isAlive(self)) {
|
|
117
|
+
self.setCanvasDrawn(success);
|
|
118
|
+
}
|
|
119
|
+
}, {
|
|
120
|
+
delay: 1000,
|
|
121
|
+
name: 'LDDisplayCanvas',
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface LDDisplayModel {
|
|
3
|
+
error?: unknown;
|
|
4
|
+
regionTooLarge?: boolean;
|
|
5
|
+
reload: () => void;
|
|
6
|
+
regionCannotBeRendered: () => React.ReactElement | null;
|
|
7
|
+
drawn: boolean;
|
|
8
|
+
loading: boolean;
|
|
9
|
+
statusMessage?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const LDBaseDisplayComponent: ({ model, children, }: {
|
|
12
|
+
model: LDDisplayModel;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
}) => import("react/jsx-runtime").JSX.Element | null;
|
|
15
|
+
export default LDBaseDisplayComponent;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
4
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
5
|
+
import { observer } from 'mobx-react';
|
|
6
|
+
const useStyles = makeStyles()({
|
|
7
|
+
loading: {
|
|
8
|
+
position: 'absolute',
|
|
9
|
+
top: 0,
|
|
10
|
+
left: 0,
|
|
11
|
+
right: 0,
|
|
12
|
+
bottom: 0,
|
|
13
|
+
backgroundColor: 'rgba(255, 255, 255, 0.15)',
|
|
14
|
+
backgroundImage: `repeating-linear-gradient(45deg, transparent, transparent 8px, rgba(0, 0, 0, 0.05) 8px, rgba(0, 0, 0, 0.05) 16px)`,
|
|
15
|
+
pointerEvents: 'none',
|
|
16
|
+
display: 'flex',
|
|
17
|
+
justifyContent: 'center',
|
|
18
|
+
alignItems: 'center',
|
|
19
|
+
zIndex: 1,
|
|
20
|
+
},
|
|
21
|
+
loadingMessage: {
|
|
22
|
+
zIndex: 2,
|
|
23
|
+
pointerEvents: 'none',
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
const LDBaseDisplayComponent = observer(function LDBaseDisplayComponent({ model, children, }) {
|
|
27
|
+
const { error, regionTooLarge } = model;
|
|
28
|
+
return error ? (_jsx(ErrorMessage, { error: error })) : regionTooLarge ? (model.regionCannotBeRendered()) : (_jsx(DataDisplay, { model: model, children: children }));
|
|
29
|
+
});
|
|
30
|
+
const DataDisplay = observer(function DataDisplay({ model, children, }) {
|
|
31
|
+
const { drawn, loading } = model;
|
|
32
|
+
return (_jsxs("div", { "data-testid": `drawn-${drawn}`, children: [children, loading ? _jsx(LoadingBar, { model: model }) : null] }));
|
|
33
|
+
});
|
|
34
|
+
const LoadingBar = observer(function LoadingBar({ model, }) {
|
|
35
|
+
const { classes } = useStyles();
|
|
36
|
+
const { statusMessage } = model;
|
|
37
|
+
return (_jsx("div", { className: classes.loading, children: _jsx("div", { className: classes.loadingMessage, children: _jsx(LoadingEllipses, { message: statusMessage }) }) }));
|
|
38
|
+
});
|
|
39
|
+
export default LDBaseDisplayComponent;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare function LDColorLegendContent({ ldMetric, signedLD, x, y, }: {
|
|
2
|
+
ldMetric: string;
|
|
3
|
+
signedLD?: boolean;
|
|
4
|
+
x?: number;
|
|
5
|
+
y?: number;
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function LDSVGColorLegend({ ldMetric, width, signedLD, }: {
|
|
8
|
+
ldMetric: string;
|
|
9
|
+
width: number;
|
|
10
|
+
signedLD?: boolean;
|
|
11
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export default function LDColorLegend({ ldMetric, signedLD, }: {
|
|
13
|
+
ldMetric: string;
|
|
14
|
+
signedLD?: boolean;
|
|
15
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
const LEGEND_WIDTH = 120;
|
|
3
|
+
const LEGEND_HEIGHT = 40;
|
|
4
|
+
const BAR_WIDTH = 100;
|
|
5
|
+
const BAR_HEIGHT = 12;
|
|
6
|
+
const PADDING = 8;
|
|
7
|
+
const FONT_SIZE = 10;
|
|
8
|
+
function getColorStops(ldMetric, signedLD) {
|
|
9
|
+
if (signedLD) {
|
|
10
|
+
if (ldMetric === 'dprime') {
|
|
11
|
+
return [
|
|
12
|
+
{ offset: '0%', color: 'rgb(0,100,0)' },
|
|
13
|
+
{ offset: '25%', color: 'rgb(64,192,64)' },
|
|
14
|
+
{ offset: '50%', color: 'rgb(255,255,255)' },
|
|
15
|
+
{ offset: '75%', color: 'rgb(128,128,255)' },
|
|
16
|
+
{ offset: '100%', color: 'rgb(0,0,160)' },
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
return [
|
|
20
|
+
{ offset: '0%', color: 'rgb(0,0,160)' },
|
|
21
|
+
{ offset: '25%', color: 'rgb(128,128,255)' },
|
|
22
|
+
{ offset: '50%', color: 'rgb(255,255,255)' },
|
|
23
|
+
{ offset: '75%', color: 'rgb(255,128,128)' },
|
|
24
|
+
{ offset: '100%', color: 'rgb(160,0,0)' },
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
if (ldMetric === 'dprime') {
|
|
28
|
+
return [
|
|
29
|
+
{ offset: '0%', color: 'rgb(255,255,255)' },
|
|
30
|
+
{ offset: '50%', color: 'rgb(128,128,255)' },
|
|
31
|
+
{ offset: '100%', color: 'rgb(0,0,160)' },
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
return [
|
|
35
|
+
{ offset: '0%', color: 'rgb(255,255,255)' },
|
|
36
|
+
{ offset: '50%', color: 'rgb(255,128,128)' },
|
|
37
|
+
{ offset: '100%', color: 'rgb(160,0,0)' },
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
function getLabels(ldMetric, signedLD) {
|
|
41
|
+
if (signedLD) {
|
|
42
|
+
return {
|
|
43
|
+
min: '-1',
|
|
44
|
+
max: '1',
|
|
45
|
+
metric: ldMetric === 'dprime' ? "D'" : 'R',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
min: '0',
|
|
50
|
+
max: '1',
|
|
51
|
+
metric: ldMetric === 'dprime' ? "D'" : 'R²',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function LDColorLegendContent({ ldMetric, signedLD = false, x = 0, y = 0, }) {
|
|
55
|
+
const gradientId = `ld-gradient-${ldMetric}-${signedLD ? 'signed' : 'unsigned'}`;
|
|
56
|
+
const stops = getColorStops(ldMetric, signedLD);
|
|
57
|
+
const labels = getLabels(ldMetric, signedLD);
|
|
58
|
+
return (_jsxs("g", { transform: `translate(${x}, ${y})`, children: [_jsx("defs", { children: _jsx("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: stops.map((stop, idx) => (_jsx("stop", { offset: stop.offset, style: { stopColor: stop.color, stopOpacity: 1 } }, idx))) }) }), _jsx("rect", { x: 0, y: 0, width: LEGEND_WIDTH, height: LEGEND_HEIGHT, fill: "rgba(255,255,255,0.9)", stroke: "#ccc", strokeWidth: 1, rx: 4 }), _jsx("rect", { x: PADDING, y: PADDING, width: BAR_WIDTH, height: BAR_HEIGHT, fill: `url(#${gradientId})`, rx: 2 }), _jsx("text", { x: PADDING, y: PADDING + BAR_HEIGHT + FONT_SIZE + 2, fontSize: FONT_SIZE, fill: "black", children: labels.min }), _jsx("text", { x: PADDING + BAR_WIDTH / 2, y: PADDING + BAR_HEIGHT + FONT_SIZE + 2, fontSize: FONT_SIZE, fill: "black", textAnchor: "middle", children: labels.metric }), _jsx("text", { x: PADDING + BAR_WIDTH, y: PADDING + BAR_HEIGHT + FONT_SIZE + 2, fontSize: FONT_SIZE, fill: "black", textAnchor: "end", children: labels.max })] }));
|
|
59
|
+
}
|
|
60
|
+
export function LDSVGColorLegend({ ldMetric, width, signedLD = false, }) {
|
|
61
|
+
const x = width - LEGEND_WIDTH - 10;
|
|
62
|
+
const y = 10;
|
|
63
|
+
return (_jsx(LDColorLegendContent, { ldMetric: ldMetric, signedLD: signedLD, x: x, y: y }));
|
|
64
|
+
}
|
|
65
|
+
export default function LDColorLegend({ ldMetric, signedLD = false, }) {
|
|
66
|
+
return (_jsx("svg", { style: {
|
|
67
|
+
position: 'absolute',
|
|
68
|
+
top: 4,
|
|
69
|
+
right: 4,
|
|
70
|
+
width: LEGEND_WIDTH,
|
|
71
|
+
height: LEGEND_HEIGHT,
|
|
72
|
+
zIndex: 10,
|
|
73
|
+
overflow: 'visible',
|
|
74
|
+
}, children: _jsx(LDColorLegendContent, { ldMetric: ldMetric, signedLD: signedLD }) }));
|
|
75
|
+
}
|
|
@@ -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;
|