@jbrowse/plugin-variants 2.10.1 → 2.10.2
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/dist/VariantFeatureWidget/BreakendOptionDialog.d.ts +4 -2
- package/dist/VariantFeatureWidget/BreakendOptionDialog.js +30 -18
- package/dist/VariantFeatureWidget/BreakendPanel.d.ts +3 -2
- package/dist/VariantFeatureWidget/BreakendPanel.js +35 -31
- package/dist/VariantFeatureWidget/VariantFeatureWidget.d.ts +2 -5
- package/dist/VariantFeatureWidget/VariantFeatureWidget.js +2 -13
- package/dist/VariantFeatureWidget/configSchema.d.ts +1 -0
- package/dist/VariantFeatureWidget/configSchema.js +5 -0
- package/dist/VariantFeatureWidget/index.d.ts +0 -49
- package/dist/VariantFeatureWidget/index.js +4 -15
- package/dist/VariantFeatureWidget/stateModelFactory.d.ts +52 -0
- package/dist/VariantFeatureWidget/stateModelFactory.js +13 -0
- package/dist/VariantFeatureWidget/variantFieldDescriptions.d.ts +9 -0
- package/dist/VariantFeatureWidget/variantFieldDescriptions.js +12 -0
- package/dist/VcfAdapter/VcfAdapter.d.ts +4 -3
- package/dist/VcfAdapter/VcfAdapter.js +14 -17
- package/esm/VariantFeatureWidget/BreakendOptionDialog.d.ts +4 -2
- package/esm/VariantFeatureWidget/BreakendOptionDialog.js +30 -18
- package/esm/VariantFeatureWidget/BreakendPanel.d.ts +3 -2
- package/esm/VariantFeatureWidget/BreakendPanel.js +37 -30
- package/esm/VariantFeatureWidget/VariantFeatureWidget.d.ts +2 -5
- package/esm/VariantFeatureWidget/VariantFeatureWidget.js +3 -14
- package/esm/VariantFeatureWidget/configSchema.d.ts +1 -0
- package/esm/VariantFeatureWidget/configSchema.js +2 -0
- package/esm/VariantFeatureWidget/index.d.ts +0 -49
- package/esm/VariantFeatureWidget/index.js +3 -12
- package/esm/VariantFeatureWidget/stateModelFactory.d.ts +52 -0
- package/esm/VariantFeatureWidget/stateModelFactory.js +9 -0
- package/esm/VariantFeatureWidget/variantFieldDescriptions.d.ts +9 -0
- package/esm/VariantFeatureWidget/variantFieldDescriptions.js +9 -0
- package/esm/VcfAdapter/VcfAdapter.d.ts +4 -3
- package/esm/VcfAdapter/VcfAdapter.js +14 -17
- package/package.json +2 -2
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Feature } from '@jbrowse/core/util';
|
|
3
|
+
import { ViewType } from '@jbrowse/core/pluggableElementTypes';
|
|
4
|
+
import { VariantFeatureWidgetModel } from './stateModelFactory';
|
|
3
5
|
declare const BreakendOptionDialog: ({ model, handleClose, feature, viewType, }: {
|
|
4
|
-
model:
|
|
6
|
+
model: VariantFeatureWidgetModel;
|
|
5
7
|
handleClose: () => void;
|
|
6
8
|
feature: Feature;
|
|
7
|
-
viewType:
|
|
9
|
+
viewType: ViewType;
|
|
8
10
|
}) => React.JSX.Element;
|
|
9
11
|
export default BreakendOptionDialog;
|
|
@@ -23,13 +23,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
27
26
|
const react_1 = __importStar(require("react"));
|
|
28
27
|
const mobx_react_1 = require("mobx-react");
|
|
29
28
|
const material_1 = require("@mui/material");
|
|
30
29
|
const mui_1 = require("tss-react/mui");
|
|
31
30
|
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
32
|
-
// jbrowse
|
|
33
31
|
const ui_1 = require("@jbrowse/core/ui");
|
|
34
32
|
const util_1 = require("@jbrowse/core/util");
|
|
35
33
|
const useStyles = (0, mui_1.makeStyles)()({
|
|
@@ -37,34 +35,48 @@ const useStyles = (0, mui_1.makeStyles)()({
|
|
|
37
35
|
display: 'block',
|
|
38
36
|
},
|
|
39
37
|
});
|
|
40
|
-
|
|
38
|
+
function stripIds(arr) {
|
|
39
|
+
return arr.map(({ id, displays, ...rest }) => ({
|
|
40
|
+
...rest,
|
|
41
|
+
displays: displays.map(({ id, ...rest }) => rest),
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
function Checkbox2({ checked, label, onChange, }) {
|
|
41
45
|
const { classes } = useStyles();
|
|
46
|
+
return (react_1.default.createElement(material_1.FormControlLabel, { className: classes.block, control: react_1.default.createElement(material_1.Checkbox, { checked: checked, onChange: onChange }), label: label }));
|
|
47
|
+
}
|
|
48
|
+
const BreakendOptionDialog = (0, mobx_react_1.observer)(function ({ model, handleClose, feature, viewType, }) {
|
|
42
49
|
const [copyTracks, setCopyTracks] = (0, react_1.useState)(true);
|
|
43
|
-
const [
|
|
50
|
+
const [mirror, setMirror] = (0, react_1.useState)(true);
|
|
44
51
|
return (react_1.default.createElement(ui_1.Dialog, { open: true, onClose: handleClose, title: "Breakpoint split view options" },
|
|
45
52
|
react_1.default.createElement(material_1.DialogContent, null,
|
|
46
|
-
react_1.default.createElement(
|
|
47
|
-
react_1.default.createElement(
|
|
53
|
+
react_1.default.createElement(Checkbox2, { checked: copyTracks, onChange: event => setCopyTracks(event.target.checked), label: "Copy tracks into the new view" }),
|
|
54
|
+
react_1.default.createElement(Checkbox2, { checked: mirror, onChange: event => setMirror(event.target.checked), label: "Mirror tracks vertically in vertically stacked view" })),
|
|
48
55
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
49
56
|
react_1.default.createElement(material_1.Button, { onClick: () => {
|
|
50
57
|
const { view } = model;
|
|
51
58
|
const session = (0, util_1.getSession)(model);
|
|
52
59
|
try {
|
|
60
|
+
// @ts-expect-error
|
|
53
61
|
const viewSnapshot = viewType.snapshotFromBreakendFeature(feature, view);
|
|
54
|
-
|
|
55
|
-
return arr.map(v => ({
|
|
56
|
-
...v,
|
|
57
|
-
id: `${v.trackId}-${Math.random()}`,
|
|
58
|
-
}));
|
|
59
|
-
}
|
|
60
|
-
viewSnapshot.views[0].offsetPx -= view.width / 2 + 100;
|
|
61
|
-
viewSnapshot.views[1].offsetPx -= view.width / 2 + 100;
|
|
62
|
-
viewSnapshot.featureData = feature;
|
|
62
|
+
const [view1, view2] = viewSnapshot.views;
|
|
63
63
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
64
64
|
const viewTracks = (0, mobx_state_tree_1.getSnapshot)(view.tracks);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
session.addView('BreakpointSplitView', {
|
|
66
|
+
...viewSnapshot,
|
|
67
|
+
views: [
|
|
68
|
+
{
|
|
69
|
+
...view1,
|
|
70
|
+
tracks: stripIds(viewTracks),
|
|
71
|
+
offsetPx: view1.offsetPx - view.width / 2 + 100,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
...view2,
|
|
75
|
+
tracks: stripIds(mirror ? [...viewTracks].reverse() : viewTracks),
|
|
76
|
+
offsetPx: view2.offsetPx - view.width / 2 + 100,
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
});
|
|
68
80
|
}
|
|
69
81
|
catch (e) {
|
|
70
82
|
console.error(e);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { SimpleFeatureSerialized } from '@jbrowse/core/util
|
|
2
|
+
import { SimpleFeatureSerialized } from '@jbrowse/core/util';
|
|
3
|
+
import { VariantFeatureWidgetModel } from './stateModelFactory';
|
|
3
4
|
export default function BreakendPanel(props: {
|
|
4
5
|
locStrings: string[];
|
|
5
|
-
model:
|
|
6
|
+
model: VariantFeatureWidgetModel;
|
|
6
7
|
feature: SimpleFeatureSerialized;
|
|
7
8
|
}): React.JSX.Element;
|
|
@@ -22,33 +22,18 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
30
26
|
const react_1 = __importStar(require("react"));
|
|
31
27
|
const material_1 = require("@mui/material");
|
|
32
|
-
const simpleFeature_1 = __importDefault(require("@jbrowse/core/util/simpleFeature"));
|
|
33
28
|
const util_1 = require("@jbrowse/core/util");
|
|
34
29
|
const BaseFeatureDetail_1 = require("@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail");
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
// lazies
|
|
31
|
+
const BreakendOptionDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./BreakendOptionDialog'))));
|
|
32
|
+
function LocStringList({ locStrings, model, }) {
|
|
38
33
|
const session = (0, util_1.getSession)(model);
|
|
39
|
-
|
|
40
|
-
const [breakpointDialog, setBreakpointDialog] = (0, react_1.useState)(false);
|
|
41
|
-
let viewType;
|
|
42
|
-
try {
|
|
43
|
-
viewType = pluginManager.getViewType('BreakpointSplitView');
|
|
44
|
-
}
|
|
45
|
-
catch (e) {
|
|
46
|
-
// ignore
|
|
47
|
-
}
|
|
48
|
-
const simpleFeature = new simpleFeature_1.default(feature);
|
|
49
|
-
return (react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { ...props, title: "Breakends" },
|
|
34
|
+
return (react_1.default.createElement("div", null,
|
|
50
35
|
react_1.default.createElement(material_1.Typography, null, "Link to linear view of breakend endpoints"),
|
|
51
|
-
react_1.default.createElement("ul", null, locStrings.map(locString => (react_1.default.createElement("li", { key: `${
|
|
36
|
+
react_1.default.createElement("ul", null, locStrings.map((locString, index) => (react_1.default.createElement("li", { key: `${locString}-${index}` },
|
|
52
37
|
react_1.default.createElement(material_1.Link, { href: "#", onClick: event => {
|
|
53
38
|
var _a;
|
|
54
39
|
event.preventDefault();
|
|
@@ -65,16 +50,35 @@ function BreakendPanel(props) {
|
|
|
65
50
|
console.error(e);
|
|
66
51
|
session.notify(`${e}`);
|
|
67
52
|
}
|
|
68
|
-
} }, `LGV - ${locString}`)))))
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
53
|
+
} }, `LGV - ${locString}`)))))));
|
|
54
|
+
}
|
|
55
|
+
function LaunchBreakpointSplitViewPanel({ locStrings, model, feature, viewType, }) {
|
|
56
|
+
const session = (0, util_1.getSession)(model);
|
|
57
|
+
const simpleFeature = new util_1.SimpleFeature(feature);
|
|
58
|
+
return (react_1.default.createElement("div", null,
|
|
59
|
+
react_1.default.createElement(material_1.Typography, null, "Launch split views with breakend source and target"),
|
|
60
|
+
react_1.default.createElement("ul", null, locStrings.map(locString => (react_1.default.createElement("li", { key: `${JSON.stringify(locString)}` },
|
|
61
|
+
react_1.default.createElement(material_1.Link, { href: "#", onClick: event => {
|
|
62
|
+
event.preventDefault();
|
|
63
|
+
session.queueDialog(handleClose => [
|
|
64
|
+
BreakendOptionDialog,
|
|
65
|
+
{ handleClose, model, feature: simpleFeature, viewType },
|
|
66
|
+
]);
|
|
67
|
+
} }, `${feature.refName}:${feature.start} // ${locString} (split view)`)))))));
|
|
68
|
+
}
|
|
69
|
+
function BreakendPanel(props) {
|
|
70
|
+
const { model, locStrings, feature } = props;
|
|
71
|
+
const session = (0, util_1.getSession)(model);
|
|
72
|
+
const { pluginManager } = (0, util_1.getEnv)(session);
|
|
73
|
+
let viewType;
|
|
74
|
+
try {
|
|
75
|
+
viewType = pluginManager.getViewType('BreakpointSplitView');
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
// ignore
|
|
79
|
+
}
|
|
80
|
+
return (react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { ...props, title: "Breakends" },
|
|
81
|
+
react_1.default.createElement(LocStringList, { model: model, locStrings: locStrings }),
|
|
82
|
+
viewType ? (react_1.default.createElement(LaunchBreakpointSplitViewPanel, { viewType: viewType, model: model, locStrings: locStrings, feature: feature })) : null));
|
|
79
83
|
}
|
|
80
84
|
exports.default = BreakendPanel;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { VariantFeatureWidgetModel } from './stateModelFactory';
|
|
3
3
|
declare const VariantFeatureWidget: (props: {
|
|
4
|
-
model:
|
|
5
|
-
featureData: SimpleFeatureSerialized;
|
|
6
|
-
descriptions: Record<string, string>;
|
|
7
|
-
};
|
|
4
|
+
model: VariantFeatureWidgetModel;
|
|
8
5
|
}) => React.JSX.Element;
|
|
9
6
|
export default VariantFeatureWidget;
|
|
@@ -12,15 +12,7 @@ const vcf_1 = require("@gmod/vcf");
|
|
|
12
12
|
const VariantSampleGrid_1 = __importDefault(require("./VariantSampleGrid"));
|
|
13
13
|
const BreakendPanel_1 = __importDefault(require("./BreakendPanel"));
|
|
14
14
|
const VariantAnnotationTable_1 = __importDefault(require("./VariantAnnotationTable"));
|
|
15
|
-
const
|
|
16
|
-
CHROM: 'chromosome: An identifier from the reference genome',
|
|
17
|
-
POS: 'position: The reference position, with the 1st base having position 1',
|
|
18
|
-
ID: 'identifier: Semi-colon separated list of unique identifiers where available',
|
|
19
|
-
REF: 'reference base(s): Each base must be one of A,C,G,T,N (case insensitive).',
|
|
20
|
-
ALT: 'alternate base(s): Comma-separated list of alternate non-reference alleles',
|
|
21
|
-
QUAL: 'quality: Phred-scaled quality score for the assertion made in ALT',
|
|
22
|
-
FILTER: 'filter status: PASS if this position has passed all filters, otherwise a semicolon-separated list of codes for filters that fail',
|
|
23
|
-
};
|
|
15
|
+
const variantFieldDescriptions_1 = require("./variantFieldDescriptions");
|
|
24
16
|
function AnnPanel({ descriptions, feature, }) {
|
|
25
17
|
var _a, _b, _c, _d;
|
|
26
18
|
const annDesc = (_b = (_a = descriptions === null || descriptions === void 0 ? void 0 : descriptions.INFO) === null || _a === void 0 ? void 0 : _a.ANN) === null || _b === void 0 ? void 0 : _b.Description;
|
|
@@ -41,12 +33,9 @@ const VariantFeatureWidget = (0, mobx_react_1.observer)(function (props) {
|
|
|
41
33
|
const feat = JSON.parse(JSON.stringify(featureData));
|
|
42
34
|
const { samples, ...rest } = feat;
|
|
43
35
|
return (react_1.default.createElement(material_1.Paper, { "data-testid": "variant-side-drawer" },
|
|
44
|
-
react_1.default.createElement(BaseFeatureDetail_1.FeatureDetails, { feature: rest, descriptions: { ...
|
|
45
|
-
react_1.default.createElement(material_1.Divider, null),
|
|
36
|
+
react_1.default.createElement(BaseFeatureDetail_1.FeatureDetails, { feature: rest, descriptions: { ...variantFieldDescriptions_1.variantFieldDescriptions, ...descriptions }, ...props }),
|
|
46
37
|
react_1.default.createElement(CsqPanel, { feature: rest, descriptions: descriptions }),
|
|
47
|
-
react_1.default.createElement(material_1.Divider, null),
|
|
48
38
|
react_1.default.createElement(AnnPanel, { feature: rest, descriptions: descriptions }),
|
|
49
|
-
react_1.default.createElement(material_1.Divider, null),
|
|
50
39
|
feat.type === 'breakend' ? (react_1.default.createElement(BreakendPanel_1.default, { feature: feat, locStrings: feat.ALT.map((alt) => { var _a; return ((_a = (0, vcf_1.parseBreakend)(alt)) === null || _a === void 0 ? void 0 : _a.MatePosition) || ''; }), model: model })) : null,
|
|
51
40
|
feat.type === 'translocation' ? (react_1.default.createElement(BreakendPanel_1.default, { feature: feat, model: model, locStrings: [`${feat.INFO.CHR2[0]}:${feat.INFO.END}`] })) : null,
|
|
52
41
|
react_1.default.createElement(VariantSampleGrid_1.default, { feature: feat, ...props, descriptions: descriptions })));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const configSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configSchema = void 0;
|
|
4
|
+
const configuration_1 = require("@jbrowse/core/configuration");
|
|
5
|
+
exports.configSchema = (0, configuration_1.ConfigurationSchema)('VariantFeatureWidget', {});
|
|
@@ -1,52 +1,3 @@
|
|
|
1
1
|
import PluginManager from '@jbrowse/core/PluginManager';
|
|
2
|
-
export declare const configSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
3
|
-
export declare function stateModelFactory(pluginManager: PluginManager): import("mobx-state-tree").IModelType<{
|
|
4
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
5
|
-
type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
|
|
6
|
-
featureData: import("mobx-state-tree").IType<any, any, any>;
|
|
7
|
-
formattedFields: import("mobx-state-tree").IType<any, any, any>;
|
|
8
|
-
unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
|
|
9
|
-
view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
10
|
-
track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
11
|
-
trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
12
|
-
trackType: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
13
|
-
maxDepth: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
|
|
14
|
-
} & {
|
|
15
|
-
type: import("mobx-state-tree").ISimpleType<"VariantFeatureWidget">;
|
|
16
|
-
descriptions: import("mobx-state-tree").IType<any, any, any>;
|
|
17
|
-
}, {
|
|
18
|
-
error: unknown;
|
|
19
|
-
} & {
|
|
20
|
-
setFeatureData(featureData: Record<string, unknown>): void;
|
|
21
|
-
clearFeatureData(): void;
|
|
22
|
-
setFormattedData(feat: Record<string, unknown>): void;
|
|
23
|
-
setExtra(type?: string | undefined, trackId?: string | undefined, maxDepth?: number | undefined): void;
|
|
24
|
-
setError(e: unknown): void;
|
|
25
|
-
} & {
|
|
26
|
-
afterCreate(): void;
|
|
27
|
-
}, {
|
|
28
|
-
type: "BaseFeatureWidget";
|
|
29
|
-
} & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
|
|
30
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
31
|
-
type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
|
|
32
|
-
featureData: import("mobx-state-tree").IType<any, any, any>;
|
|
33
|
-
formattedFields: import("mobx-state-tree").IType<any, any, any>;
|
|
34
|
-
unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
|
|
35
|
-
view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
36
|
-
track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
37
|
-
trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
38
|
-
trackType: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
39
|
-
maxDepth: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
|
|
40
|
-
}>> & import("mobx-state-tree/dist/internal").NonEmptyObject & import("mobx-state-tree")._NotCustomized, {
|
|
41
|
-
type: "BaseFeatureWidget";
|
|
42
|
-
id: string;
|
|
43
|
-
track: import("mobx-state-tree").ReferenceIdentifier | undefined;
|
|
44
|
-
view: import("mobx-state-tree").ReferenceIdentifier | undefined;
|
|
45
|
-
trackId: string | undefined;
|
|
46
|
-
trackType: string | undefined;
|
|
47
|
-
maxDepth: number | undefined;
|
|
48
|
-
formattedFields: any;
|
|
49
|
-
finalizedFeatureData: any;
|
|
50
|
-
} & import("mobx-state-tree")._NotCustomized>;
|
|
51
2
|
declare const _default: (pluginManager: PluginManager) => void;
|
|
52
3
|
export default _default;
|
|
@@ -26,27 +26,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.stateModelFactory = exports.configSchema = void 0;
|
|
30
29
|
const react_1 = require("react");
|
|
31
|
-
const configuration_1 = require("@jbrowse/core/configuration");
|
|
32
30
|
const WidgetType_1 = __importDefault(require("@jbrowse/core/pluggableElementTypes/WidgetType"));
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
exports.configSchema = (0, configuration_1.ConfigurationSchema)('VariantFeatureWidget', {});
|
|
36
|
-
function stateModelFactory(pluginManager) {
|
|
37
|
-
const baseModel = (0, BaseFeatureWidget_1.stateModelFactory)(pluginManager);
|
|
38
|
-
return mobx_state_tree_1.types.compose(baseModel, mobx_state_tree_1.types.model('VariantFeatureWidget', {
|
|
39
|
-
type: mobx_state_tree_1.types.literal('VariantFeatureWidget'),
|
|
40
|
-
descriptions: mobx_state_tree_1.types.frozen(),
|
|
41
|
-
}));
|
|
42
|
-
}
|
|
43
|
-
exports.stateModelFactory = stateModelFactory;
|
|
31
|
+
const stateModelFactory_1 = require("./stateModelFactory");
|
|
32
|
+
const configSchema_1 = require("./configSchema");
|
|
44
33
|
exports.default = (pluginManager) => {
|
|
45
34
|
pluginManager.addWidgetType(() => new WidgetType_1.default({
|
|
46
35
|
name: 'VariantFeatureWidget',
|
|
47
36
|
heading: 'Feature details',
|
|
48
|
-
configSchema:
|
|
49
|
-
stateModel: stateModelFactory(pluginManager),
|
|
37
|
+
configSchema: configSchema_1.configSchema,
|
|
38
|
+
stateModel: (0, stateModelFactory_1.stateModelFactory)(pluginManager),
|
|
50
39
|
ReactComponent: (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./VariantFeatureWidget')))),
|
|
51
40
|
}));
|
|
52
41
|
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import PluginManager from '@jbrowse/core/PluginManager';
|
|
2
|
+
import { Instance } from 'mobx-state-tree';
|
|
3
|
+
export declare function stateModelFactory(pluginManager: PluginManager): import("mobx-state-tree").IModelType<{
|
|
4
|
+
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
5
|
+
type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
|
|
6
|
+
featureData: import("mobx-state-tree").IType<any, any, any>;
|
|
7
|
+
formattedFields: import("mobx-state-tree").IType<any, any, any>;
|
|
8
|
+
unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
|
|
9
|
+
view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
10
|
+
track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
11
|
+
trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
12
|
+
trackType: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
13
|
+
maxDepth: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
|
|
14
|
+
} & {
|
|
15
|
+
type: import("mobx-state-tree").ISimpleType<"VariantFeatureWidget">;
|
|
16
|
+
descriptions: import("mobx-state-tree").IType<any, any, any>;
|
|
17
|
+
}, {
|
|
18
|
+
error: unknown;
|
|
19
|
+
} & {
|
|
20
|
+
setFeatureData(featureData: Record<string, unknown>): void;
|
|
21
|
+
clearFeatureData(): void;
|
|
22
|
+
setFormattedData(feat: Record<string, unknown>): void;
|
|
23
|
+
setExtra(type?: string | undefined, trackId?: string | undefined, maxDepth?: number | undefined): void;
|
|
24
|
+
setError(e: unknown): void;
|
|
25
|
+
} & {
|
|
26
|
+
afterCreate(): void;
|
|
27
|
+
}, {
|
|
28
|
+
type: "BaseFeatureWidget";
|
|
29
|
+
} & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
|
|
30
|
+
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
31
|
+
type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
|
|
32
|
+
featureData: import("mobx-state-tree").IType<any, any, any>;
|
|
33
|
+
formattedFields: import("mobx-state-tree").IType<any, any, any>;
|
|
34
|
+
unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
|
|
35
|
+
view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
36
|
+
track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
37
|
+
trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
38
|
+
trackType: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
39
|
+
maxDepth: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
|
|
40
|
+
}>> & import("mobx-state-tree/dist/internal").NonEmptyObject & import("mobx-state-tree")._NotCustomized, {
|
|
41
|
+
type: "BaseFeatureWidget";
|
|
42
|
+
id: string;
|
|
43
|
+
track: import("mobx-state-tree").ReferenceIdentifier | undefined;
|
|
44
|
+
view: import("mobx-state-tree").ReferenceIdentifier | undefined;
|
|
45
|
+
trackId: string | undefined;
|
|
46
|
+
trackType: string | undefined;
|
|
47
|
+
maxDepth: number | undefined;
|
|
48
|
+
formattedFields: any;
|
|
49
|
+
finalizedFeatureData: any;
|
|
50
|
+
} & import("mobx-state-tree")._NotCustomized>;
|
|
51
|
+
export type VariantFeatureWidgetStateModel = ReturnType<typeof stateModelFactory>;
|
|
52
|
+
export type VariantFeatureWidgetModel = Instance<VariantFeatureWidgetStateModel>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stateModelFactory = void 0;
|
|
4
|
+
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
5
|
+
const BaseFeatureWidget_1 = require("@jbrowse/core/BaseFeatureWidget");
|
|
6
|
+
function stateModelFactory(pluginManager) {
|
|
7
|
+
const baseModel = (0, BaseFeatureWidget_1.stateModelFactory)(pluginManager);
|
|
8
|
+
return mobx_state_tree_1.types.compose(baseModel, mobx_state_tree_1.types.model('VariantFeatureWidget', {
|
|
9
|
+
type: mobx_state_tree_1.types.literal('VariantFeatureWidget'),
|
|
10
|
+
descriptions: mobx_state_tree_1.types.frozen(),
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
exports.stateModelFactory = stateModelFactory;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.variantFieldDescriptions = void 0;
|
|
4
|
+
exports.variantFieldDescriptions = {
|
|
5
|
+
CHROM: 'chromosome: An identifier from the reference genome',
|
|
6
|
+
POS: 'position: The reference position, with the 1st base having position 1',
|
|
7
|
+
ID: 'identifier: Semi-colon separated list of unique identifiers where available',
|
|
8
|
+
REF: 'reference base(s): Each base must be one of A,C,G,T,N (case insensitive).',
|
|
9
|
+
ALT: 'alternate base(s): Comma-separated list of alternate non-reference alleles',
|
|
10
|
+
QUAL: 'quality: Phred-scaled quality score for the assertion made in ALT',
|
|
11
|
+
FILTER: 'filter status: PASS if this position has passed all filters, otherwise a semicolon-separated list of codes for filters that fail',
|
|
12
|
+
};
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { BaseFeatureDataAdapter, BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
2
|
import { Region, Feature } from '@jbrowse/core/util';
|
|
3
3
|
import IntervalTree from '@flatten-js/interval-tree';
|
|
4
|
+
import VcfFeature from '../VcfFeature';
|
|
4
5
|
export default class VcfAdapter extends BaseFeatureDataAdapter {
|
|
5
6
|
static capabilities: string[];
|
|
6
7
|
protected vcfFeatures?: Promise<{
|
|
7
8
|
header: string;
|
|
8
|
-
intervalTree: Record<string, IntervalTree
|
|
9
|
+
intervalTree: Record<string, IntervalTree<VcfFeature>>;
|
|
9
10
|
}>;
|
|
10
11
|
getHeader(): Promise<string>;
|
|
11
12
|
getMetadata(): Promise<any>;
|
|
12
13
|
setupP(): Promise<{
|
|
13
14
|
header: string;
|
|
14
|
-
intervalTree: Record<string, IntervalTree<
|
|
15
|
+
intervalTree: Record<string, IntervalTree<VcfFeature>>;
|
|
15
16
|
}>;
|
|
16
17
|
setup(): Promise<{
|
|
17
18
|
header: string;
|
|
18
|
-
intervalTree: Record<string, IntervalTree<
|
|
19
|
+
intervalTree: Record<string, IntervalTree<VcfFeature>>;
|
|
19
20
|
}>;
|
|
20
21
|
getRefNames(_?: BaseOptions): Promise<string[]>;
|
|
21
22
|
getFeatures(region: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
@@ -52,19 +52,19 @@ class VcfAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
52
52
|
const str = new TextDecoder().decode(buffer);
|
|
53
53
|
const { header, lines } = readVcf(str);
|
|
54
54
|
const intervalTree = {};
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const key =
|
|
55
|
+
const parser = new vcf_1.default({ header });
|
|
56
|
+
let idx = 0;
|
|
57
|
+
for (const line of lines) {
|
|
58
|
+
const f = new VcfFeature_1.default({
|
|
59
|
+
variant: parser.parseLine(line),
|
|
60
|
+
parser,
|
|
61
|
+
id: `${this.id}-${idx++}`,
|
|
62
|
+
});
|
|
63
|
+
const key = f.get('refName');
|
|
64
64
|
if (!intervalTree[key]) {
|
|
65
65
|
intervalTree[key] = new interval_tree_1.default();
|
|
66
66
|
}
|
|
67
|
-
intervalTree[key].insert([
|
|
67
|
+
intervalTree[key].insert([f.get('start'), f.get('end')], f);
|
|
68
68
|
}
|
|
69
69
|
return { header, intervalTree };
|
|
70
70
|
}
|
|
@@ -86,13 +86,10 @@ class VcfAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
86
86
|
var _a;
|
|
87
87
|
try {
|
|
88
88
|
const { start, end, refName } = region;
|
|
89
|
-
const {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
parser,
|
|
94
|
-
id: `${this.id}-${f.id}`,
|
|
95
|
-
})));
|
|
89
|
+
const { intervalTree } = await this.setup();
|
|
90
|
+
(_a = intervalTree[refName]) === null || _a === void 0 ? void 0 : _a.search([start, end]).forEach((f) => {
|
|
91
|
+
observer.next(f);
|
|
92
|
+
});
|
|
96
93
|
observer.complete();
|
|
97
94
|
}
|
|
98
95
|
catch (e) {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Feature } from '@jbrowse/core/util';
|
|
3
|
+
import { ViewType } from '@jbrowse/core/pluggableElementTypes';
|
|
4
|
+
import { VariantFeatureWidgetModel } from './stateModelFactory';
|
|
3
5
|
declare const BreakendOptionDialog: ({ model, handleClose, feature, viewType, }: {
|
|
4
|
-
model:
|
|
6
|
+
model: VariantFeatureWidgetModel;
|
|
5
7
|
handleClose: () => void;
|
|
6
8
|
feature: Feature;
|
|
7
|
-
viewType:
|
|
9
|
+
viewType: ViewType;
|
|
8
10
|
}) => React.JSX.Element;
|
|
9
11
|
export default BreakendOptionDialog;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
1
|
import React, { useState } from 'react';
|
|
3
2
|
import { observer } from 'mobx-react';
|
|
4
3
|
import { Button, Checkbox, DialogActions, DialogContent, FormControlLabel, } from '@mui/material';
|
|
5
4
|
import { makeStyles } from 'tss-react/mui';
|
|
6
5
|
import { getSnapshot } from 'mobx-state-tree';
|
|
7
|
-
// jbrowse
|
|
8
6
|
import { Dialog } from '@jbrowse/core/ui';
|
|
9
7
|
import { getSession } from '@jbrowse/core/util';
|
|
10
8
|
const useStyles = makeStyles()({
|
|
@@ -12,34 +10,48 @@ const useStyles = makeStyles()({
|
|
|
12
10
|
display: 'block',
|
|
13
11
|
},
|
|
14
12
|
});
|
|
15
|
-
|
|
13
|
+
function stripIds(arr) {
|
|
14
|
+
return arr.map(({ id, displays, ...rest }) => ({
|
|
15
|
+
...rest,
|
|
16
|
+
displays: displays.map(({ id, ...rest }) => rest),
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
function Checkbox2({ checked, label, onChange, }) {
|
|
16
20
|
const { classes } = useStyles();
|
|
21
|
+
return (React.createElement(FormControlLabel, { className: classes.block, control: React.createElement(Checkbox, { checked: checked, onChange: onChange }), label: label }));
|
|
22
|
+
}
|
|
23
|
+
const BreakendOptionDialog = observer(function ({ model, handleClose, feature, viewType, }) {
|
|
17
24
|
const [copyTracks, setCopyTracks] = useState(true);
|
|
18
|
-
const [
|
|
25
|
+
const [mirror, setMirror] = useState(true);
|
|
19
26
|
return (React.createElement(Dialog, { open: true, onClose: handleClose, title: "Breakpoint split view options" },
|
|
20
27
|
React.createElement(DialogContent, null,
|
|
21
|
-
React.createElement(
|
|
22
|
-
React.createElement(
|
|
28
|
+
React.createElement(Checkbox2, { checked: copyTracks, onChange: event => setCopyTracks(event.target.checked), label: "Copy tracks into the new view" }),
|
|
29
|
+
React.createElement(Checkbox2, { checked: mirror, onChange: event => setMirror(event.target.checked), label: "Mirror tracks vertically in vertically stacked view" })),
|
|
23
30
|
React.createElement(DialogActions, null,
|
|
24
31
|
React.createElement(Button, { onClick: () => {
|
|
25
32
|
const { view } = model;
|
|
26
33
|
const session = getSession(model);
|
|
27
34
|
try {
|
|
35
|
+
// @ts-expect-error
|
|
28
36
|
const viewSnapshot = viewType.snapshotFromBreakendFeature(feature, view);
|
|
29
|
-
|
|
30
|
-
return arr.map(v => ({
|
|
31
|
-
...v,
|
|
32
|
-
id: `${v.trackId}-${Math.random()}`,
|
|
33
|
-
}));
|
|
34
|
-
}
|
|
35
|
-
viewSnapshot.views[0].offsetPx -= view.width / 2 + 100;
|
|
36
|
-
viewSnapshot.views[1].offsetPx -= view.width / 2 + 100;
|
|
37
|
-
viewSnapshot.featureData = feature;
|
|
37
|
+
const [view1, view2] = viewSnapshot.views;
|
|
38
38
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
39
39
|
const viewTracks = getSnapshot(view.tracks);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
session.addView('BreakpointSplitView', {
|
|
41
|
+
...viewSnapshot,
|
|
42
|
+
views: [
|
|
43
|
+
{
|
|
44
|
+
...view1,
|
|
45
|
+
tracks: stripIds(viewTracks),
|
|
46
|
+
offsetPx: view1.offsetPx - view.width / 2 + 100,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
...view2,
|
|
50
|
+
tracks: stripIds(mirror ? [...viewTracks].reverse() : viewTracks),
|
|
51
|
+
offsetPx: view2.offsetPx - view.width / 2 + 100,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
});
|
|
43
55
|
}
|
|
44
56
|
catch (e) {
|
|
45
57
|
console.error(e);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { SimpleFeatureSerialized } from '@jbrowse/core/util
|
|
2
|
+
import { SimpleFeatureSerialized } from '@jbrowse/core/util';
|
|
3
|
+
import { VariantFeatureWidgetModel } from './stateModelFactory';
|
|
3
4
|
export default function BreakendPanel(props: {
|
|
4
5
|
locStrings: string[];
|
|
5
|
-
model:
|
|
6
|
+
model: VariantFeatureWidgetModel;
|
|
6
7
|
feature: SimpleFeatureSerialized;
|
|
7
8
|
}): React.JSX.Element;
|
|
@@ -1,26 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { lazy } from 'react';
|
|
3
2
|
import { Link, Typography } from '@mui/material';
|
|
4
|
-
import SimpleFeature from '@jbrowse/core/util
|
|
5
|
-
import { getEnv, getSession } from '@jbrowse/core/util';
|
|
3
|
+
import { getEnv, getSession, SimpleFeature, } from '@jbrowse/core/util';
|
|
6
4
|
import { BaseCard } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
// lazies
|
|
6
|
+
const BreakendOptionDialog = lazy(() => import('./BreakendOptionDialog'));
|
|
7
|
+
function LocStringList({ locStrings, model, }) {
|
|
10
8
|
const session = getSession(model);
|
|
11
|
-
|
|
12
|
-
const [breakpointDialog, setBreakpointDialog] = useState(false);
|
|
13
|
-
let viewType;
|
|
14
|
-
try {
|
|
15
|
-
viewType = pluginManager.getViewType('BreakpointSplitView');
|
|
16
|
-
}
|
|
17
|
-
catch (e) {
|
|
18
|
-
// ignore
|
|
19
|
-
}
|
|
20
|
-
const simpleFeature = new SimpleFeature(feature);
|
|
21
|
-
return (React.createElement(BaseCard, { ...props, title: "Breakends" },
|
|
9
|
+
return (React.createElement("div", null,
|
|
22
10
|
React.createElement(Typography, null, "Link to linear view of breakend endpoints"),
|
|
23
|
-
React.createElement("ul", null, locStrings.map(locString => (React.createElement("li", { key: `${
|
|
11
|
+
React.createElement("ul", null, locStrings.map((locString, index) => (React.createElement("li", { key: `${locString}-${index}` },
|
|
24
12
|
React.createElement(Link, { href: "#", onClick: event => {
|
|
25
13
|
var _a;
|
|
26
14
|
event.preventDefault();
|
|
@@ -37,15 +25,34 @@ export default function BreakendPanel(props) {
|
|
|
37
25
|
console.error(e);
|
|
38
26
|
session.notify(`${e}`);
|
|
39
27
|
}
|
|
40
|
-
} }, `LGV - ${locString}`)))))
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
28
|
+
} }, `LGV - ${locString}`)))))));
|
|
29
|
+
}
|
|
30
|
+
function LaunchBreakpointSplitViewPanel({ locStrings, model, feature, viewType, }) {
|
|
31
|
+
const session = getSession(model);
|
|
32
|
+
const simpleFeature = new SimpleFeature(feature);
|
|
33
|
+
return (React.createElement("div", null,
|
|
34
|
+
React.createElement(Typography, null, "Launch split views with breakend source and target"),
|
|
35
|
+
React.createElement("ul", null, locStrings.map(locString => (React.createElement("li", { key: `${JSON.stringify(locString)}` },
|
|
36
|
+
React.createElement(Link, { href: "#", onClick: event => {
|
|
37
|
+
event.preventDefault();
|
|
38
|
+
session.queueDialog(handleClose => [
|
|
39
|
+
BreakendOptionDialog,
|
|
40
|
+
{ handleClose, model, feature: simpleFeature, viewType },
|
|
41
|
+
]);
|
|
42
|
+
} }, `${feature.refName}:${feature.start} // ${locString} (split view)`)))))));
|
|
43
|
+
}
|
|
44
|
+
export default function BreakendPanel(props) {
|
|
45
|
+
const { model, locStrings, feature } = props;
|
|
46
|
+
const session = getSession(model);
|
|
47
|
+
const { pluginManager } = getEnv(session);
|
|
48
|
+
let viewType;
|
|
49
|
+
try {
|
|
50
|
+
viewType = pluginManager.getViewType('BreakpointSplitView');
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
// ignore
|
|
54
|
+
}
|
|
55
|
+
return (React.createElement(BaseCard, { ...props, title: "Breakends" },
|
|
56
|
+
React.createElement(LocStringList, { model: model, locStrings: locStrings }),
|
|
57
|
+
viewType ? (React.createElement(LaunchBreakpointSplitViewPanel, { viewType: viewType, model: model, locStrings: locStrings, feature: feature })) : null));
|
|
51
58
|
}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { VariantFeatureWidgetModel } from './stateModelFactory';
|
|
3
3
|
declare const VariantFeatureWidget: (props: {
|
|
4
|
-
model:
|
|
5
|
-
featureData: SimpleFeatureSerialized;
|
|
6
|
-
descriptions: Record<string, string>;
|
|
7
|
-
};
|
|
4
|
+
model: VariantFeatureWidgetModel;
|
|
8
5
|
}) => React.JSX.Element;
|
|
9
6
|
export default VariantFeatureWidget;
|
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { observer } from 'mobx-react';
|
|
3
|
-
import {
|
|
3
|
+
import { Paper } from '@mui/material';
|
|
4
4
|
import { FeatureDetails } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail';
|
|
5
5
|
import { parseBreakend } from '@gmod/vcf';
|
|
6
6
|
// locals
|
|
7
7
|
import VariantSampleGrid from './VariantSampleGrid';
|
|
8
8
|
import BreakendPanel from './BreakendPanel';
|
|
9
9
|
import VariantAnnotationTable from './VariantAnnotationTable';
|
|
10
|
-
|
|
11
|
-
CHROM: 'chromosome: An identifier from the reference genome',
|
|
12
|
-
POS: 'position: The reference position, with the 1st base having position 1',
|
|
13
|
-
ID: 'identifier: Semi-colon separated list of unique identifiers where available',
|
|
14
|
-
REF: 'reference base(s): Each base must be one of A,C,G,T,N (case insensitive).',
|
|
15
|
-
ALT: 'alternate base(s): Comma-separated list of alternate non-reference alleles',
|
|
16
|
-
QUAL: 'quality: Phred-scaled quality score for the assertion made in ALT',
|
|
17
|
-
FILTER: 'filter status: PASS if this position has passed all filters, otherwise a semicolon-separated list of codes for filters that fail',
|
|
18
|
-
};
|
|
10
|
+
import { variantFieldDescriptions } from './variantFieldDescriptions';
|
|
19
11
|
function AnnPanel({ descriptions, feature, }) {
|
|
20
12
|
var _a, _b, _c, _d;
|
|
21
13
|
const annDesc = (_b = (_a = descriptions === null || descriptions === void 0 ? void 0 : descriptions.INFO) === null || _a === void 0 ? void 0 : _a.ANN) === null || _b === void 0 ? void 0 : _b.Description;
|
|
@@ -36,12 +28,9 @@ const VariantFeatureWidget = observer(function (props) {
|
|
|
36
28
|
const feat = JSON.parse(JSON.stringify(featureData));
|
|
37
29
|
const { samples, ...rest } = feat;
|
|
38
30
|
return (React.createElement(Paper, { "data-testid": "variant-side-drawer" },
|
|
39
|
-
React.createElement(FeatureDetails, { feature: rest, descriptions: { ...
|
|
40
|
-
React.createElement(Divider, null),
|
|
31
|
+
React.createElement(FeatureDetails, { feature: rest, descriptions: { ...variantFieldDescriptions, ...descriptions }, ...props }),
|
|
41
32
|
React.createElement(CsqPanel, { feature: rest, descriptions: descriptions }),
|
|
42
|
-
React.createElement(Divider, null),
|
|
43
33
|
React.createElement(AnnPanel, { feature: rest, descriptions: descriptions }),
|
|
44
|
-
React.createElement(Divider, null),
|
|
45
34
|
feat.type === 'breakend' ? (React.createElement(BreakendPanel, { feature: feat, locStrings: feat.ALT.map((alt) => { var _a; return ((_a = parseBreakend(alt)) === null || _a === void 0 ? void 0 : _a.MatePosition) || ''; }), model: model })) : null,
|
|
46
35
|
feat.type === 'translocation' ? (React.createElement(BreakendPanel, { feature: feat, model: model, locStrings: [`${feat.INFO.CHR2[0]}:${feat.INFO.END}`] })) : null,
|
|
47
36
|
React.createElement(VariantSampleGrid, { feature: feat, ...props, descriptions: descriptions })));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const configSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
@@ -1,52 +1,3 @@
|
|
|
1
1
|
import PluginManager from '@jbrowse/core/PluginManager';
|
|
2
|
-
export declare const configSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
3
|
-
export declare function stateModelFactory(pluginManager: PluginManager): import("mobx-state-tree").IModelType<{
|
|
4
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
5
|
-
type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
|
|
6
|
-
featureData: import("mobx-state-tree").IType<any, any, any>;
|
|
7
|
-
formattedFields: import("mobx-state-tree").IType<any, any, any>;
|
|
8
|
-
unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
|
|
9
|
-
view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
10
|
-
track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
11
|
-
trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
12
|
-
trackType: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
13
|
-
maxDepth: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
|
|
14
|
-
} & {
|
|
15
|
-
type: import("mobx-state-tree").ISimpleType<"VariantFeatureWidget">;
|
|
16
|
-
descriptions: import("mobx-state-tree").IType<any, any, any>;
|
|
17
|
-
}, {
|
|
18
|
-
error: unknown;
|
|
19
|
-
} & {
|
|
20
|
-
setFeatureData(featureData: Record<string, unknown>): void;
|
|
21
|
-
clearFeatureData(): void;
|
|
22
|
-
setFormattedData(feat: Record<string, unknown>): void;
|
|
23
|
-
setExtra(type?: string | undefined, trackId?: string | undefined, maxDepth?: number | undefined): void;
|
|
24
|
-
setError(e: unknown): void;
|
|
25
|
-
} & {
|
|
26
|
-
afterCreate(): void;
|
|
27
|
-
}, {
|
|
28
|
-
type: "BaseFeatureWidget";
|
|
29
|
-
} & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
|
|
30
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
31
|
-
type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
|
|
32
|
-
featureData: import("mobx-state-tree").IType<any, any, any>;
|
|
33
|
-
formattedFields: import("mobx-state-tree").IType<any, any, any>;
|
|
34
|
-
unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
|
|
35
|
-
view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
36
|
-
track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
37
|
-
trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
38
|
-
trackType: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
39
|
-
maxDepth: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
|
|
40
|
-
}>> & import("mobx-state-tree/dist/internal").NonEmptyObject & import("mobx-state-tree")._NotCustomized, {
|
|
41
|
-
type: "BaseFeatureWidget";
|
|
42
|
-
id: string;
|
|
43
|
-
track: import("mobx-state-tree").ReferenceIdentifier | undefined;
|
|
44
|
-
view: import("mobx-state-tree").ReferenceIdentifier | undefined;
|
|
45
|
-
trackId: string | undefined;
|
|
46
|
-
trackType: string | undefined;
|
|
47
|
-
maxDepth: number | undefined;
|
|
48
|
-
formattedFields: any;
|
|
49
|
-
finalizedFeatureData: any;
|
|
50
|
-
} & import("mobx-state-tree")._NotCustomized>;
|
|
51
2
|
declare const _default: (pluginManager: PluginManager) => void;
|
|
52
3
|
export default _default;
|
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
import { lazy } from 'react';
|
|
2
|
-
import { ConfigurationSchema } from '@jbrowse/core/configuration';
|
|
3
2
|
import WidgetType from '@jbrowse/core/pluggableElementTypes/WidgetType';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
export const configSchema = ConfigurationSchema('VariantFeatureWidget', {});
|
|
7
|
-
export function stateModelFactory(pluginManager) {
|
|
8
|
-
const baseModel = baseModelFactory(pluginManager);
|
|
9
|
-
return types.compose(baseModel, types.model('VariantFeatureWidget', {
|
|
10
|
-
type: types.literal('VariantFeatureWidget'),
|
|
11
|
-
descriptions: types.frozen(),
|
|
12
|
-
}));
|
|
13
|
-
}
|
|
3
|
+
import { stateModelFactory } from './stateModelFactory';
|
|
4
|
+
import { configSchema } from './configSchema';
|
|
14
5
|
export default (pluginManager) => {
|
|
15
6
|
pluginManager.addWidgetType(() => new WidgetType({
|
|
16
7
|
name: 'VariantFeatureWidget',
|
|
17
8
|
heading: 'Feature details',
|
|
18
|
-
configSchema,
|
|
9
|
+
configSchema: configSchema,
|
|
19
10
|
stateModel: stateModelFactory(pluginManager),
|
|
20
11
|
ReactComponent: lazy(() => import('./VariantFeatureWidget')),
|
|
21
12
|
}));
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import PluginManager from '@jbrowse/core/PluginManager';
|
|
2
|
+
import { Instance } from 'mobx-state-tree';
|
|
3
|
+
export declare function stateModelFactory(pluginManager: PluginManager): import("mobx-state-tree").IModelType<{
|
|
4
|
+
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
5
|
+
type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
|
|
6
|
+
featureData: import("mobx-state-tree").IType<any, any, any>;
|
|
7
|
+
formattedFields: import("mobx-state-tree").IType<any, any, any>;
|
|
8
|
+
unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
|
|
9
|
+
view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
10
|
+
track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
11
|
+
trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
12
|
+
trackType: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
13
|
+
maxDepth: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
|
|
14
|
+
} & {
|
|
15
|
+
type: import("mobx-state-tree").ISimpleType<"VariantFeatureWidget">;
|
|
16
|
+
descriptions: import("mobx-state-tree").IType<any, any, any>;
|
|
17
|
+
}, {
|
|
18
|
+
error: unknown;
|
|
19
|
+
} & {
|
|
20
|
+
setFeatureData(featureData: Record<string, unknown>): void;
|
|
21
|
+
clearFeatureData(): void;
|
|
22
|
+
setFormattedData(feat: Record<string, unknown>): void;
|
|
23
|
+
setExtra(type?: string | undefined, trackId?: string | undefined, maxDepth?: number | undefined): void;
|
|
24
|
+
setError(e: unknown): void;
|
|
25
|
+
} & {
|
|
26
|
+
afterCreate(): void;
|
|
27
|
+
}, {
|
|
28
|
+
type: "BaseFeatureWidget";
|
|
29
|
+
} & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
|
|
30
|
+
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
31
|
+
type: import("mobx-state-tree").ISimpleType<"BaseFeatureWidget">;
|
|
32
|
+
featureData: import("mobx-state-tree").IType<any, any, any>;
|
|
33
|
+
formattedFields: import("mobx-state-tree").IType<any, any, any>;
|
|
34
|
+
unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
|
|
35
|
+
view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
36
|
+
track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
37
|
+
trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
38
|
+
trackType: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
39
|
+
maxDepth: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<number>>;
|
|
40
|
+
}>> & import("mobx-state-tree/dist/internal").NonEmptyObject & import("mobx-state-tree")._NotCustomized, {
|
|
41
|
+
type: "BaseFeatureWidget";
|
|
42
|
+
id: string;
|
|
43
|
+
track: import("mobx-state-tree").ReferenceIdentifier | undefined;
|
|
44
|
+
view: import("mobx-state-tree").ReferenceIdentifier | undefined;
|
|
45
|
+
trackId: string | undefined;
|
|
46
|
+
trackType: string | undefined;
|
|
47
|
+
maxDepth: number | undefined;
|
|
48
|
+
formattedFields: any;
|
|
49
|
+
finalizedFeatureData: any;
|
|
50
|
+
} & import("mobx-state-tree")._NotCustomized>;
|
|
51
|
+
export type VariantFeatureWidgetStateModel = ReturnType<typeof stateModelFactory>;
|
|
52
|
+
export type VariantFeatureWidgetModel = Instance<VariantFeatureWidgetStateModel>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { types } from 'mobx-state-tree';
|
|
2
|
+
import { stateModelFactory as baseModelFactory } from '@jbrowse/core/BaseFeatureWidget';
|
|
3
|
+
export function stateModelFactory(pluginManager) {
|
|
4
|
+
const baseModel = baseModelFactory(pluginManager);
|
|
5
|
+
return types.compose(baseModel, types.model('VariantFeatureWidget', {
|
|
6
|
+
type: types.literal('VariantFeatureWidget'),
|
|
7
|
+
descriptions: types.frozen(),
|
|
8
|
+
}));
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const variantFieldDescriptions = {
|
|
2
|
+
CHROM: 'chromosome: An identifier from the reference genome',
|
|
3
|
+
POS: 'position: The reference position, with the 1st base having position 1',
|
|
4
|
+
ID: 'identifier: Semi-colon separated list of unique identifiers where available',
|
|
5
|
+
REF: 'reference base(s): Each base must be one of A,C,G,T,N (case insensitive).',
|
|
6
|
+
ALT: 'alternate base(s): Comma-separated list of alternate non-reference alleles',
|
|
7
|
+
QUAL: 'quality: Phred-scaled quality score for the assertion made in ALT',
|
|
8
|
+
FILTER: 'filter status: PASS if this position has passed all filters, otherwise a semicolon-separated list of codes for filters that fail',
|
|
9
|
+
};
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { BaseFeatureDataAdapter, BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
2
|
import { Region, Feature } from '@jbrowse/core/util';
|
|
3
3
|
import IntervalTree from '@flatten-js/interval-tree';
|
|
4
|
+
import VcfFeature from '../VcfFeature';
|
|
4
5
|
export default class VcfAdapter extends BaseFeatureDataAdapter {
|
|
5
6
|
static capabilities: string[];
|
|
6
7
|
protected vcfFeatures?: Promise<{
|
|
7
8
|
header: string;
|
|
8
|
-
intervalTree: Record<string, IntervalTree
|
|
9
|
+
intervalTree: Record<string, IntervalTree<VcfFeature>>;
|
|
9
10
|
}>;
|
|
10
11
|
getHeader(): Promise<string>;
|
|
11
12
|
getMetadata(): Promise<any>;
|
|
12
13
|
setupP(): Promise<{
|
|
13
14
|
header: string;
|
|
14
|
-
intervalTree: Record<string, IntervalTree<
|
|
15
|
+
intervalTree: Record<string, IntervalTree<VcfFeature>>;
|
|
15
16
|
}>;
|
|
16
17
|
setup(): Promise<{
|
|
17
18
|
header: string;
|
|
18
|
-
intervalTree: Record<string, IntervalTree<
|
|
19
|
+
intervalTree: Record<string, IntervalTree<VcfFeature>>;
|
|
19
20
|
}>;
|
|
20
21
|
getRefNames(_?: BaseOptions): Promise<string[]>;
|
|
21
22
|
getFeatures(region: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
@@ -47,19 +47,19 @@ class VcfAdapter extends BaseFeatureDataAdapter {
|
|
|
47
47
|
const str = new TextDecoder().decode(buffer);
|
|
48
48
|
const { header, lines } = readVcf(str);
|
|
49
49
|
const intervalTree = {};
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const key =
|
|
50
|
+
const parser = new VCF({ header });
|
|
51
|
+
let idx = 0;
|
|
52
|
+
for (const line of lines) {
|
|
53
|
+
const f = new VcfFeature({
|
|
54
|
+
variant: parser.parseLine(line),
|
|
55
|
+
parser,
|
|
56
|
+
id: `${this.id}-${idx++}`,
|
|
57
|
+
});
|
|
58
|
+
const key = f.get('refName');
|
|
59
59
|
if (!intervalTree[key]) {
|
|
60
60
|
intervalTree[key] = new IntervalTree();
|
|
61
61
|
}
|
|
62
|
-
intervalTree[key].insert([
|
|
62
|
+
intervalTree[key].insert([f.get('start'), f.get('end')], f);
|
|
63
63
|
}
|
|
64
64
|
return { header, intervalTree };
|
|
65
65
|
}
|
|
@@ -81,13 +81,10 @@ class VcfAdapter extends BaseFeatureDataAdapter {
|
|
|
81
81
|
var _a;
|
|
82
82
|
try {
|
|
83
83
|
const { start, end, refName } = region;
|
|
84
|
-
const {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
parser,
|
|
89
|
-
id: `${this.id}-${f.id}`,
|
|
90
|
-
})));
|
|
84
|
+
const { intervalTree } = await this.setup();
|
|
85
|
+
(_a = intervalTree[refName]) === null || _a === void 0 ? void 0 : _a.search([start, end]).forEach((f) => {
|
|
86
|
+
observer.next(f);
|
|
87
|
+
});
|
|
91
88
|
observer.complete();
|
|
92
89
|
}
|
|
93
90
|
catch (e) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-variants",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.2",
|
|
4
4
|
"description": "JBrowse 2 variant adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"distModule": "esm/index.js",
|
|
64
64
|
"srcModule": "src/index.ts",
|
|
65
65
|
"module": "esm/index.js",
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "7ca3b7db337ebd88853e2d96cdab940ed550c4fb"
|
|
67
67
|
}
|