@jbrowse/plugin-arc 2.10.0 → 2.10.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.
- package/dist/ArcRenderer/ArcRendering.js +32 -12
- package/dist/ArcTooltip.d.ts +5 -0
- package/dist/ArcTooltip.js +51 -0
- package/dist/LinearArcDisplay/model.d.ts +1 -1
- package/dist/LinearPairedArcDisplay/components/Arcs.js +12 -66
- package/dist/LinearPairedArcDisplay/components/util.d.ts +17 -0
- package/dist/LinearPairedArcDisplay/components/util.js +74 -0
- package/esm/ArcRenderer/ArcRendering.js +10 -13
- package/esm/ArcTooltip.d.ts +5 -0
- package/esm/ArcTooltip.js +46 -0
- package/esm/LinearArcDisplay/model.d.ts +1 -1
- package/esm/LinearPairedArcDisplay/components/Arcs.js +10 -67
- package/esm/LinearPairedArcDisplay/components/util.d.ts +17 -0
- package/esm/LinearPairedArcDisplay/components/util.js +69 -0
- package/package.json +2 -5
|
@@ -1,14 +1,39 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const react_1 =
|
|
29
|
+
const react_1 = __importStar(require("react"));
|
|
7
30
|
const configuration_1 = require("@jbrowse/core/configuration");
|
|
8
31
|
const util_1 = require("@jbrowse/core/util");
|
|
9
32
|
const mobx_react_1 = require("mobx-react");
|
|
10
|
-
|
|
33
|
+
// locals
|
|
34
|
+
const ArcTooltip_1 = __importDefault(require("../ArcTooltip"));
|
|
11
35
|
function Arc({ selectedFeatureId, region, bpPerPx, config, onFeatureClick, feature, }) {
|
|
36
|
+
const [isMouseOvered, setIsMouseOvered] = (0, react_1.useState)(false);
|
|
12
37
|
const [left, right] = (0, util_1.bpSpanPx)(feature.get('start'), feature.get('end'), region, bpPerPx);
|
|
13
38
|
const featureId = feature.id();
|
|
14
39
|
let stroke = (0, configuration_1.readConfObject)(config, 'color', { feature });
|
|
@@ -21,7 +46,6 @@ function Arc({ selectedFeatureId, region, bpPerPx, config, onFeatureClick, featu
|
|
|
21
46
|
const strokeWidth = (0, configuration_1.readConfObject)(config, 'thickness', { feature }) || 1;
|
|
22
47
|
const height = (0, configuration_1.readConfObject)(config, 'height', { feature }) || 100;
|
|
23
48
|
const ref = react_1.default.createRef();
|
|
24
|
-
const tooltipWidth = 20 + (0, util_1.measureText)(caption === null || caption === void 0 ? void 0 : caption.toString());
|
|
25
49
|
const t = 0.5;
|
|
26
50
|
// formula: https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B%C3%A9zier_curves
|
|
27
51
|
const textYCoord = (1 - t) * (1 - t) * (1 - t) * 0 +
|
|
@@ -29,10 +53,8 @@ function Arc({ selectedFeatureId, region, bpPerPx, config, onFeatureClick, featu
|
|
|
29
53
|
3 * (1 - t) * (t * t) * height +
|
|
30
54
|
t * t * t * 0;
|
|
31
55
|
return (react_1.default.createElement("g", null,
|
|
32
|
-
react_1.default.createElement("path", { d: `M ${left} 0 C ${left} ${height}, ${right} ${height}, ${right} 0`, stroke: stroke, strokeWidth: strokeWidth, fill: "transparent", onClick: e => onFeatureClick === null || onFeatureClick === void 0 ? void 0 : onFeatureClick(e, featureId), ref: ref, pointerEvents: "stroke" }),
|
|
33
|
-
react_1.default.createElement(
|
|
34
|
-
react_1.default.createElement("rect", { x: 12, y: 0, width: tooltipWidth, height: 20, rx: 5, ry: 5, fill: "black", fillOpacity: "50%" }),
|
|
35
|
-
react_1.default.createElement("text", { x: 22, y: 14, fontSize: 10, fill: "white", textLength: tooltipWidth - 20 }, caption)),
|
|
56
|
+
react_1.default.createElement("path", { d: `M ${left} 0 C ${left} ${height}, ${right} ${height}, ${right} 0`, stroke: stroke, strokeWidth: strokeWidth, fill: "transparent", onClick: e => onFeatureClick === null || onFeatureClick === void 0 ? void 0 : onFeatureClick(e, featureId), onMouseOver: () => setIsMouseOvered(true), onMouseLeave: () => setIsMouseOvered(false), ref: ref, pointerEvents: "stroke" }),
|
|
57
|
+
isMouseOvered ? react_1.default.createElement(ArcTooltip_1.default, { contents: caption }) : null,
|
|
36
58
|
react_1.default.createElement("text", { x: left + (right - left) / 2, y: textYCoord + 3, style: { stroke: 'white', strokeWidth: '0.6em' } }, label),
|
|
37
59
|
react_1.default.createElement("text", { x: left + (right - left) / 2, y: textYCoord + 3, style: { stroke: textStroke } }, label)));
|
|
38
60
|
}
|
|
@@ -62,6 +84,7 @@ function describeArc(x, y, radius, startAngle, endAngle) {
|
|
|
62
84
|
].join(' ');
|
|
63
85
|
}
|
|
64
86
|
function SemiCircles({ selectedFeatureId, region, bpPerPx, config, onFeatureClick, feature, }) {
|
|
87
|
+
const [isMouseOvered, setIsMouseOvered] = (0, react_1.useState)(false);
|
|
65
88
|
const [left, right] = (0, util_1.bpSpanPx)(feature.get('start'), feature.get('end'), region, bpPerPx);
|
|
66
89
|
const featureId = feature.id();
|
|
67
90
|
let stroke = (0, configuration_1.readConfObject)(config, 'color', { feature });
|
|
@@ -73,13 +96,10 @@ function SemiCircles({ selectedFeatureId, region, bpPerPx, config, onFeatureClic
|
|
|
73
96
|
const caption = (0, configuration_1.readConfObject)(config, 'caption', { feature });
|
|
74
97
|
const strokeWidth = (0, configuration_1.readConfObject)(config, 'thickness', { feature }) || 1;
|
|
75
98
|
const ref = react_1.default.createRef();
|
|
76
|
-
const tooltipWidth = 20 + (0, util_1.measureText)(caption === null || caption === void 0 ? void 0 : caption.toString());
|
|
77
99
|
const textYCoord = (right - left) / 2;
|
|
78
100
|
return (react_1.default.createElement("g", null,
|
|
79
|
-
react_1.default.createElement("path", { d: describeArc(left + (right - left) / 2, 0, (right - left) / 2, 90, 270), stroke: stroke, strokeWidth: strokeWidth, fill: "transparent", onClick: e => onFeatureClick === null || onFeatureClick === void 0 ? void 0 : onFeatureClick(e, featureId), ref: ref, pointerEvents: "stroke" }),
|
|
80
|
-
react_1.default.createElement(
|
|
81
|
-
react_1.default.createElement("rect", { x: 12, y: 0, width: tooltipWidth, height: 20, rx: 5, ry: 5, fill: "black", fillOpacity: "50%" }),
|
|
82
|
-
react_1.default.createElement("text", { x: 22, y: 14, fontSize: 10, fill: "white", textLength: tooltipWidth - 20 }, caption)),
|
|
101
|
+
react_1.default.createElement("path", { d: describeArc(left + (right - left) / 2, 0, (right - left) / 2, 90, 270), stroke: stroke, strokeWidth: strokeWidth, fill: "transparent", onClick: e => onFeatureClick === null || onFeatureClick === void 0 ? void 0 : onFeatureClick(e, featureId), onMouseOver: () => setIsMouseOvered(true), onMouseLeave: () => setIsMouseOvered(false), ref: ref, pointerEvents: "stroke" }),
|
|
102
|
+
isMouseOvered ? react_1.default.createElement(ArcTooltip_1.default, { contents: caption }) : null,
|
|
83
103
|
react_1.default.createElement("text", { x: left + (right - left) / 2, y: textYCoord + 3, style: { stroke: 'white', strokeWidth: '0.6em' } }, label),
|
|
84
104
|
react_1.default.createElement("text", { x: left + (right - left) / 2, y: textYCoord + 3, style: { stroke: textStroke } }, label)));
|
|
85
105
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const ui_1 = require("@jbrowse/core/ui");
|
|
8
|
+
const mobx_react_1 = require("mobx-react");
|
|
9
|
+
const material_1 = require("@mui/material");
|
|
10
|
+
const mui_1 = require("tss-react/mui");
|
|
11
|
+
const react_2 = require("@floating-ui/react");
|
|
12
|
+
function round(value) {
|
|
13
|
+
return Math.round(value * 1e5) / 1e5;
|
|
14
|
+
}
|
|
15
|
+
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
16
|
+
// these styles come from
|
|
17
|
+
// https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Tooltip/Tooltip.js
|
|
18
|
+
tooltip: {
|
|
19
|
+
pointerEvents: 'none',
|
|
20
|
+
backgroundColor: (0, material_1.alpha)(theme.palette.grey[700], 0.9),
|
|
21
|
+
borderRadius: theme.shape.borderRadius,
|
|
22
|
+
color: theme.palette.common.white,
|
|
23
|
+
fontFamily: theme.typography.fontFamily,
|
|
24
|
+
padding: '4px 8px',
|
|
25
|
+
fontSize: theme.typography.pxToRem(12),
|
|
26
|
+
lineHeight: `${round(14 / 10)}em`,
|
|
27
|
+
maxWidth: 300,
|
|
28
|
+
wordWrap: 'break-word',
|
|
29
|
+
},
|
|
30
|
+
}));
|
|
31
|
+
const TooltipContents = react_1.default.forwardRef(function TooltipContents2({ message }, ref) {
|
|
32
|
+
return (react_1.default.createElement("div", { ref: ref }, react_1.default.isValidElement(message) ? (message) : message ? (react_1.default.createElement(ui_1.SanitizedHTML, { html: String(message) })) : null));
|
|
33
|
+
});
|
|
34
|
+
const ArcTooltip = (0, mobx_react_1.observer)(function ({ contents }) {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
const { theme, classes } = useStyles();
|
|
37
|
+
const { refs, floatingStyles, context } = (0, react_2.useFloating)({
|
|
38
|
+
placement: 'right',
|
|
39
|
+
});
|
|
40
|
+
const clientPoint = (0, react_2.useClientPoint)(context);
|
|
41
|
+
const { getFloatingProps } = (0, react_2.useInteractions)([clientPoint]);
|
|
42
|
+
const popperTheme = (_a = theme === null || theme === void 0 ? void 0 : theme.components) === null || _a === void 0 ? void 0 : _a.MuiPopper;
|
|
43
|
+
return contents ? (react_1.default.createElement(material_1.Portal, { container: (_b = popperTheme === null || popperTheme === void 0 ? void 0 : popperTheme.defaultProps) === null || _b === void 0 ? void 0 : _b.container },
|
|
44
|
+
react_1.default.createElement("div", { className: classes.tooltip, ref: refs.setFloating, style: {
|
|
45
|
+
...floatingStyles,
|
|
46
|
+
zIndex: 100000,
|
|
47
|
+
pointerEvents: 'none',
|
|
48
|
+
}, ...getFloatingProps() },
|
|
49
|
+
react_1.default.createElement(TooltipContents, { message: contents })))) : null;
|
|
50
|
+
});
|
|
51
|
+
exports.default = ArcTooltip;
|
|
@@ -375,8 +375,8 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
375
375
|
};
|
|
376
376
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
377
377
|
}>> & import("mobx-state-tree/dist/internal").NonEmptyObject & import("mobx-state-tree")._NotCustomized, {
|
|
378
|
-
type: string;
|
|
379
378
|
id: string;
|
|
379
|
+
type: string;
|
|
380
380
|
configuration: import("mobx-state-tree").ModelSnapshotType<Record<string, any>>;
|
|
381
381
|
rpcDriverName: string | undefined;
|
|
382
382
|
heightPreConfig: number | undefined;
|
|
@@ -22,79 +22,21 @@ 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
|
+
};
|
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
29
|
const react_1 = __importStar(require("react"));
|
|
27
30
|
const mobx_react_1 = require("mobx-react");
|
|
28
31
|
const util_1 = require("@jbrowse/core/util");
|
|
29
32
|
const configuration_1 = require("@jbrowse/core/configuration");
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
function f(feature, alt) {
|
|
33
|
-
var _a, _b, _c, _d, _e;
|
|
34
|
-
const bnd = alt ? (0, vcf_1.parseBreakend)(alt) : undefined;
|
|
35
|
-
let start = feature.get('start');
|
|
36
|
-
let end = feature.get('end');
|
|
37
|
-
const strand = feature.get('strand');
|
|
38
|
-
const mate = feature.get('mate');
|
|
39
|
-
const refName = feature.get('refName');
|
|
40
|
-
let mateRefName;
|
|
41
|
-
let mateEnd = 0;
|
|
42
|
-
let mateStart = 0;
|
|
43
|
-
// one sided bracket used, because there could be <INS:ME> and we just check
|
|
44
|
-
// startswith below
|
|
45
|
-
const symbolicAlleles = ['<TRA', '<DEL', '<INV', '<INS', '<DUP', '<CNV'];
|
|
46
|
-
if (symbolicAlleles.some(a => alt === null || alt === void 0 ? void 0 : alt.startsWith(a))) {
|
|
47
|
-
// END is defined to be a single value, not an array. CHR2 not defined in
|
|
48
|
-
// VCF spec, but should be similar
|
|
49
|
-
const e = ((_b = (_a = feature.get('INFO')) === null || _a === void 0 ? void 0 : _a.END) === null || _b === void 0 ? void 0 : _b[0]) || feature.get('end');
|
|
50
|
-
mateEnd = e;
|
|
51
|
-
mateStart = e - 1;
|
|
52
|
-
mateRefName = (_e = (_d = (_c = feature.get('INFO')) === null || _c === void 0 ? void 0 : _c.CHR2) === null || _d === void 0 ? void 0 : _d[0]) !== null && _e !== void 0 ? _e : refName;
|
|
53
|
-
// re-adjust the arc to be from start to end of feature by re-assigning end
|
|
54
|
-
// to the 'mate'
|
|
55
|
-
start = feature.get('start');
|
|
56
|
-
end = feature.get('start') + 1;
|
|
57
|
-
}
|
|
58
|
-
else if (bnd === null || bnd === void 0 ? void 0 : bnd.MatePosition) {
|
|
59
|
-
const matePosition = bnd.MatePosition.split(':');
|
|
60
|
-
mateEnd = +matePosition[1];
|
|
61
|
-
mateStart = +matePosition[1] - 1;
|
|
62
|
-
mateRefName = matePosition[0];
|
|
63
|
-
}
|
|
64
|
-
return {
|
|
65
|
-
k1: { refName, start, end, strand },
|
|
66
|
-
k2: mate !== null && mate !== void 0 ? mate : { refName: mateRefName, end: mateEnd, start: mateStart },
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
function makeSummary(feature, alt) {
|
|
70
|
-
var _a;
|
|
71
|
-
const { k1, k2 } = f(feature, alt);
|
|
72
|
-
return [
|
|
73
|
-
feature.get('name'),
|
|
74
|
-
feature.get('id'),
|
|
75
|
-
(0, util_1.assembleLocString)(k1),
|
|
76
|
-
(0, util_1.assembleLocString)(k2),
|
|
77
|
-
(_a = feature.get('INFO')) === null || _a === void 0 ? void 0 : _a.SVTYPE,
|
|
78
|
-
alt,
|
|
79
|
-
]
|
|
80
|
-
.filter(f => !!f)
|
|
81
|
-
.join(' - ');
|
|
82
|
-
}
|
|
83
|
-
// conditionally rendered tooltip only on mouseover, speeds up
|
|
84
|
-
const SvgTooltip = react_1.default.forwardRef(function SvgTooltip2({ feature, alt }, ref) {
|
|
85
|
-
const caption = makeSummary(feature, alt);
|
|
86
|
-
const tooltipWidth = 20 + (0, util_1.measureText)(caption);
|
|
87
|
-
return ref !== null ? (
|
|
88
|
-
// @ts-expect-error
|
|
89
|
-
react_1.default.createElement(react_svg_tooltip_1.Tooltip, { triggerRef: ref },
|
|
90
|
-
react_1.default.createElement("rect", { x: 12, y: 0, width: tooltipWidth, height: 20, rx: 5, ry: 5, fill: "black", fillOpacity: "50%" }),
|
|
91
|
-
react_1.default.createElement("text", { x: 22, y: 14, fontSize: 10, fill: "white", textLength: tooltipWidth - 20 }, caption))) : null;
|
|
92
|
-
});
|
|
33
|
+
const ArcTooltip_1 = __importDefault(require("../../ArcTooltip"));
|
|
34
|
+
const util_2 = require("./util");
|
|
93
35
|
const Arc = (0, mobx_react_1.observer)(function ({ model, feature, alt, assembly, view, }) {
|
|
94
36
|
var _a, _b;
|
|
95
37
|
const [mouseOvered, setMouseOvered] = (0, react_1.useState)(false);
|
|
96
38
|
const { height } = model;
|
|
97
|
-
const { k1, k2 } =
|
|
39
|
+
const { k1, k2 } = (0, util_2.makeFeaturePair)(feature, alt);
|
|
98
40
|
const ref = (0, react_1.useRef)(null);
|
|
99
41
|
const c = (0, configuration_1.getConf)(model, 'color', { feature, alt });
|
|
100
42
|
const ra1 = assembly.getCanonicalRefName(k1.refName) || k1.refName;
|
|
@@ -111,9 +53,13 @@ const Arc = (0, mobx_react_1.observer)(function ({ model, feature, alt, assembly
|
|
|
111
53
|
const p2 = r2 - view.offsetPx;
|
|
112
54
|
const left = p1;
|
|
113
55
|
const right = p2;
|
|
56
|
+
const col = mouseOvered ? 'black' : c;
|
|
57
|
+
const sw = 3;
|
|
114
58
|
return absrad > 1 ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
115
|
-
react_1.default.createElement("path", { d: `M ${left} 0 C ${left} ${destY}, ${right} ${destY}, ${right} 0`, ref: ref, stroke:
|
|
116
|
-
|
|
59
|
+
react_1.default.createElement("path", { d: `M ${left} 0 C ${left} ${destY}, ${right} ${destY}, ${right} 0`, ref: ref, stroke: col, strokeWidth: sw, onMouseOut: () => setMouseOvered(false), onMouseOver: () => setMouseOvered(true), onClick: () => model.selectFeature(feature), fill: "none", pointerEvents: "stroke" }),
|
|
60
|
+
k1.mateDirection !== undefined ? (react_1.default.createElement("line", { stroke: col, strokeWidth: sw, onMouseOut: () => setMouseOvered(false), onMouseOver: () => setMouseOvered(true), onClick: () => model.selectFeature(feature), x1: left, x2: left + k1.mateDirection * 20, y1: 1.5, y2: 1.5 })) : null,
|
|
61
|
+
k2.mateDirection !== undefined ? (react_1.default.createElement("line", { stroke: col, strokeWidth: sw, onMouseOut: () => setMouseOvered(false), onMouseOver: () => setMouseOvered(true), onClick: () => model.selectFeature(feature), x1: right, x2: right + k2.mateDirection * 20, y1: 1.5, y2: 1.5 })) : null,
|
|
62
|
+
mouseOvered ? (react_1.default.createElement(ArcTooltip_1.default, { contents: (0, util_2.makeSummary)(feature, alt) })) : null)) : null;
|
|
117
63
|
}
|
|
118
64
|
return null;
|
|
119
65
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Feature } from '@jbrowse/core/util';
|
|
2
|
+
export declare function makeFeaturePair(feature: Feature, alt?: string): {
|
|
3
|
+
k1: {
|
|
4
|
+
refName: string;
|
|
5
|
+
start: number;
|
|
6
|
+
end: number;
|
|
7
|
+
strand: any;
|
|
8
|
+
mateDirection: number;
|
|
9
|
+
};
|
|
10
|
+
k2: {
|
|
11
|
+
refName: string;
|
|
12
|
+
start: number;
|
|
13
|
+
end: number;
|
|
14
|
+
mateDirection?: number | undefined;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export declare function makeSummary(feature: Feature, alt?: string): string;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeSummary = exports.makeFeaturePair = void 0;
|
|
4
|
+
const vcf_1 = require("@gmod/vcf");
|
|
5
|
+
const util_1 = require("@jbrowse/core/util");
|
|
6
|
+
function makeFeaturePair(feature, alt) {
|
|
7
|
+
var _a, _b, _c, _d;
|
|
8
|
+
const bnd = alt ? (0, vcf_1.parseBreakend)(alt) : undefined;
|
|
9
|
+
let start = feature.get('start');
|
|
10
|
+
let end = feature.get('end');
|
|
11
|
+
const strand = feature.get('strand');
|
|
12
|
+
const mate = feature.get('mate');
|
|
13
|
+
const refName = feature.get('refName');
|
|
14
|
+
let mateRefName;
|
|
15
|
+
let mateEnd = 0;
|
|
16
|
+
let mateStart = 0;
|
|
17
|
+
let joinDirection = 0;
|
|
18
|
+
let mateDirection = 0;
|
|
19
|
+
// one sided bracket used, because there could be <INS:ME> and we just check
|
|
20
|
+
// startswith below
|
|
21
|
+
const symbolicAlleles = ['<TRA', '<DEL', '<INV', '<INS', '<DUP', '<CNV'];
|
|
22
|
+
if (symbolicAlleles.some(a => alt === null || alt === void 0 ? void 0 : alt.startsWith(a))) {
|
|
23
|
+
// END is defined to be a single value, not an array. CHR2 not defined in
|
|
24
|
+
// VCF spec, but should be similar
|
|
25
|
+
const info = feature.get('INFO');
|
|
26
|
+
const e = (_b = (_a = info === null || info === void 0 ? void 0 : info.END) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : end;
|
|
27
|
+
mateRefName = (_d = (_c = info === null || info === void 0 ? void 0 : info.CHR2) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : refName;
|
|
28
|
+
mateEnd = e;
|
|
29
|
+
mateStart = e - 1;
|
|
30
|
+
// re-adjust the arc to be from start to end of feature by re-assigning end
|
|
31
|
+
// to the 'mate'
|
|
32
|
+
start = start;
|
|
33
|
+
end = start + 1;
|
|
34
|
+
}
|
|
35
|
+
else if (bnd === null || bnd === void 0 ? void 0 : bnd.MatePosition) {
|
|
36
|
+
const matePosition = bnd.MatePosition.split(':');
|
|
37
|
+
mateDirection = bnd.MateDirection === 'left' ? 1 : -1;
|
|
38
|
+
joinDirection = bnd.Join === 'left' ? -1 : 1;
|
|
39
|
+
mateEnd = +matePosition[1];
|
|
40
|
+
mateStart = +matePosition[1] - 1;
|
|
41
|
+
mateRefName = matePosition[0];
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
k1: {
|
|
45
|
+
refName,
|
|
46
|
+
start,
|
|
47
|
+
end,
|
|
48
|
+
strand,
|
|
49
|
+
mateDirection,
|
|
50
|
+
},
|
|
51
|
+
k2: mate !== null && mate !== void 0 ? mate : {
|
|
52
|
+
refName: mateRefName,
|
|
53
|
+
end: mateEnd,
|
|
54
|
+
start: mateStart,
|
|
55
|
+
mateDirection: joinDirection,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
exports.makeFeaturePair = makeFeaturePair;
|
|
60
|
+
function makeSummary(feature, alt) {
|
|
61
|
+
var _a;
|
|
62
|
+
const { k1, k2 } = makeFeaturePair(feature, alt);
|
|
63
|
+
return [
|
|
64
|
+
feature.get('name'),
|
|
65
|
+
feature.get('id'),
|
|
66
|
+
(0, util_1.assembleLocString)(k1),
|
|
67
|
+
(0, util_1.assembleLocString)(k2),
|
|
68
|
+
(_a = feature.get('INFO')) === null || _a === void 0 ? void 0 : _a.SVTYPE,
|
|
69
|
+
alt,
|
|
70
|
+
]
|
|
71
|
+
.filter(f => !!f)
|
|
72
|
+
.join(' - ');
|
|
73
|
+
}
|
|
74
|
+
exports.makeSummary = makeSummary;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import { readConfObject, } from '@jbrowse/core/configuration';
|
|
3
|
-
import { bpSpanPx
|
|
3
|
+
import { bpSpanPx } from '@jbrowse/core/util';
|
|
4
4
|
import { observer } from 'mobx-react';
|
|
5
|
-
|
|
5
|
+
// locals
|
|
6
|
+
import ArcTooltip from '../ArcTooltip';
|
|
6
7
|
function Arc({ selectedFeatureId, region, bpPerPx, config, onFeatureClick, feature, }) {
|
|
8
|
+
const [isMouseOvered, setIsMouseOvered] = useState(false);
|
|
7
9
|
const [left, right] = bpSpanPx(feature.get('start'), feature.get('end'), region, bpPerPx);
|
|
8
10
|
const featureId = feature.id();
|
|
9
11
|
let stroke = readConfObject(config, 'color', { feature });
|
|
@@ -16,7 +18,6 @@ function Arc({ selectedFeatureId, region, bpPerPx, config, onFeatureClick, featu
|
|
|
16
18
|
const strokeWidth = readConfObject(config, 'thickness', { feature }) || 1;
|
|
17
19
|
const height = readConfObject(config, 'height', { feature }) || 100;
|
|
18
20
|
const ref = React.createRef();
|
|
19
|
-
const tooltipWidth = 20 + measureText(caption === null || caption === void 0 ? void 0 : caption.toString());
|
|
20
21
|
const t = 0.5;
|
|
21
22
|
// formula: https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B%C3%A9zier_curves
|
|
22
23
|
const textYCoord = (1 - t) * (1 - t) * (1 - t) * 0 +
|
|
@@ -24,10 +25,8 @@ function Arc({ selectedFeatureId, region, bpPerPx, config, onFeatureClick, featu
|
|
|
24
25
|
3 * (1 - t) * (t * t) * height +
|
|
25
26
|
t * t * t * 0;
|
|
26
27
|
return (React.createElement("g", null,
|
|
27
|
-
React.createElement("path", { d: `M ${left} 0 C ${left} ${height}, ${right} ${height}, ${right} 0`, stroke: stroke, strokeWidth: strokeWidth, fill: "transparent", onClick: e => onFeatureClick === null || onFeatureClick === void 0 ? void 0 : onFeatureClick(e, featureId), ref: ref, pointerEvents: "stroke" }),
|
|
28
|
-
React.createElement(
|
|
29
|
-
React.createElement("rect", { x: 12, y: 0, width: tooltipWidth, height: 20, rx: 5, ry: 5, fill: "black", fillOpacity: "50%" }),
|
|
30
|
-
React.createElement("text", { x: 22, y: 14, fontSize: 10, fill: "white", textLength: tooltipWidth - 20 }, caption)),
|
|
28
|
+
React.createElement("path", { d: `M ${left} 0 C ${left} ${height}, ${right} ${height}, ${right} 0`, stroke: stroke, strokeWidth: strokeWidth, fill: "transparent", onClick: e => onFeatureClick === null || onFeatureClick === void 0 ? void 0 : onFeatureClick(e, featureId), onMouseOver: () => setIsMouseOvered(true), onMouseLeave: () => setIsMouseOvered(false), ref: ref, pointerEvents: "stroke" }),
|
|
29
|
+
isMouseOvered ? React.createElement(ArcTooltip, { contents: caption }) : null,
|
|
31
30
|
React.createElement("text", { x: left + (right - left) / 2, y: textYCoord + 3, style: { stroke: 'white', strokeWidth: '0.6em' } }, label),
|
|
32
31
|
React.createElement("text", { x: left + (right - left) / 2, y: textYCoord + 3, style: { stroke: textStroke } }, label)));
|
|
33
32
|
}
|
|
@@ -57,6 +56,7 @@ function describeArc(x, y, radius, startAngle, endAngle) {
|
|
|
57
56
|
].join(' ');
|
|
58
57
|
}
|
|
59
58
|
function SemiCircles({ selectedFeatureId, region, bpPerPx, config, onFeatureClick, feature, }) {
|
|
59
|
+
const [isMouseOvered, setIsMouseOvered] = useState(false);
|
|
60
60
|
const [left, right] = bpSpanPx(feature.get('start'), feature.get('end'), region, bpPerPx);
|
|
61
61
|
const featureId = feature.id();
|
|
62
62
|
let stroke = readConfObject(config, 'color', { feature });
|
|
@@ -68,13 +68,10 @@ function SemiCircles({ selectedFeatureId, region, bpPerPx, config, onFeatureClic
|
|
|
68
68
|
const caption = readConfObject(config, 'caption', { feature });
|
|
69
69
|
const strokeWidth = readConfObject(config, 'thickness', { feature }) || 1;
|
|
70
70
|
const ref = React.createRef();
|
|
71
|
-
const tooltipWidth = 20 + measureText(caption === null || caption === void 0 ? void 0 : caption.toString());
|
|
72
71
|
const textYCoord = (right - left) / 2;
|
|
73
72
|
return (React.createElement("g", null,
|
|
74
|
-
React.createElement("path", { d: describeArc(left + (right - left) / 2, 0, (right - left) / 2, 90, 270), stroke: stroke, strokeWidth: strokeWidth, fill: "transparent", onClick: e => onFeatureClick === null || onFeatureClick === void 0 ? void 0 : onFeatureClick(e, featureId), ref: ref, pointerEvents: "stroke" }),
|
|
75
|
-
React.createElement(
|
|
76
|
-
React.createElement("rect", { x: 12, y: 0, width: tooltipWidth, height: 20, rx: 5, ry: 5, fill: "black", fillOpacity: "50%" }),
|
|
77
|
-
React.createElement("text", { x: 22, y: 14, fontSize: 10, fill: "white", textLength: tooltipWidth - 20 }, caption)),
|
|
73
|
+
React.createElement("path", { d: describeArc(left + (right - left) / 2, 0, (right - left) / 2, 90, 270), stroke: stroke, strokeWidth: strokeWidth, fill: "transparent", onClick: e => onFeatureClick === null || onFeatureClick === void 0 ? void 0 : onFeatureClick(e, featureId), onMouseOver: () => setIsMouseOvered(true), onMouseLeave: () => setIsMouseOvered(false), ref: ref, pointerEvents: "stroke" }),
|
|
74
|
+
isMouseOvered ? React.createElement(ArcTooltip, { contents: caption }) : null,
|
|
78
75
|
React.createElement("text", { x: left + (right - left) / 2, y: textYCoord + 3, style: { stroke: 'white', strokeWidth: '0.6em' } }, label),
|
|
79
76
|
React.createElement("text", { x: left + (right - left) / 2, y: textYCoord + 3, style: { stroke: textStroke } }, label)));
|
|
80
77
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SanitizedHTML } from '@jbrowse/core/ui';
|
|
3
|
+
import { observer } from 'mobx-react';
|
|
4
|
+
import { Portal, alpha } from '@mui/material';
|
|
5
|
+
import { makeStyles } from 'tss-react/mui';
|
|
6
|
+
import { useClientPoint, useFloating, useInteractions, } from '@floating-ui/react';
|
|
7
|
+
function round(value) {
|
|
8
|
+
return Math.round(value * 1e5) / 1e5;
|
|
9
|
+
}
|
|
10
|
+
const useStyles = makeStyles()(theme => ({
|
|
11
|
+
// these styles come from
|
|
12
|
+
// https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Tooltip/Tooltip.js
|
|
13
|
+
tooltip: {
|
|
14
|
+
pointerEvents: 'none',
|
|
15
|
+
backgroundColor: alpha(theme.palette.grey[700], 0.9),
|
|
16
|
+
borderRadius: theme.shape.borderRadius,
|
|
17
|
+
color: theme.palette.common.white,
|
|
18
|
+
fontFamily: theme.typography.fontFamily,
|
|
19
|
+
padding: '4px 8px',
|
|
20
|
+
fontSize: theme.typography.pxToRem(12),
|
|
21
|
+
lineHeight: `${round(14 / 10)}em`,
|
|
22
|
+
maxWidth: 300,
|
|
23
|
+
wordWrap: 'break-word',
|
|
24
|
+
},
|
|
25
|
+
}));
|
|
26
|
+
const TooltipContents = React.forwardRef(function TooltipContents2({ message }, ref) {
|
|
27
|
+
return (React.createElement("div", { ref: ref }, React.isValidElement(message) ? (message) : message ? (React.createElement(SanitizedHTML, { html: String(message) })) : null));
|
|
28
|
+
});
|
|
29
|
+
const ArcTooltip = observer(function ({ contents }) {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
const { theme, classes } = useStyles();
|
|
32
|
+
const { refs, floatingStyles, context } = useFloating({
|
|
33
|
+
placement: 'right',
|
|
34
|
+
});
|
|
35
|
+
const clientPoint = useClientPoint(context);
|
|
36
|
+
const { getFloatingProps } = useInteractions([clientPoint]);
|
|
37
|
+
const popperTheme = (_a = theme === null || theme === void 0 ? void 0 : theme.components) === null || _a === void 0 ? void 0 : _a.MuiPopper;
|
|
38
|
+
return contents ? (React.createElement(Portal, { container: (_b = popperTheme === null || popperTheme === void 0 ? void 0 : popperTheme.defaultProps) === null || _b === void 0 ? void 0 : _b.container },
|
|
39
|
+
React.createElement("div", { className: classes.tooltip, ref: refs.setFloating, style: {
|
|
40
|
+
...floatingStyles,
|
|
41
|
+
zIndex: 100000,
|
|
42
|
+
pointerEvents: 'none',
|
|
43
|
+
}, ...getFloatingProps() },
|
|
44
|
+
React.createElement(TooltipContents, { message: contents })))) : null;
|
|
45
|
+
});
|
|
46
|
+
export default ArcTooltip;
|
|
@@ -375,8 +375,8 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
375
375
|
};
|
|
376
376
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "displayId">>;
|
|
377
377
|
}>> & import("mobx-state-tree/dist/internal").NonEmptyObject & import("mobx-state-tree")._NotCustomized, {
|
|
378
|
-
type: string;
|
|
379
378
|
id: string;
|
|
379
|
+
type: string;
|
|
380
380
|
configuration: import("mobx-state-tree").ModelSnapshotType<Record<string, any>>;
|
|
381
381
|
rpcDriverName: string | undefined;
|
|
382
382
|
heightPreConfig: number | undefined;
|
|
@@ -1,75 +1,14 @@
|
|
|
1
1
|
import React, { useRef, useState } from 'react';
|
|
2
2
|
import { observer } from 'mobx-react';
|
|
3
|
-
import {
|
|
3
|
+
import { getContainingView, getSession, } from '@jbrowse/core/util';
|
|
4
4
|
import { getConf } from '@jbrowse/core/configuration';
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
function f(feature, alt) {
|
|
8
|
-
var _a, _b, _c, _d, _e;
|
|
9
|
-
const bnd = alt ? parseBreakend(alt) : undefined;
|
|
10
|
-
let start = feature.get('start');
|
|
11
|
-
let end = feature.get('end');
|
|
12
|
-
const strand = feature.get('strand');
|
|
13
|
-
const mate = feature.get('mate');
|
|
14
|
-
const refName = feature.get('refName');
|
|
15
|
-
let mateRefName;
|
|
16
|
-
let mateEnd = 0;
|
|
17
|
-
let mateStart = 0;
|
|
18
|
-
// one sided bracket used, because there could be <INS:ME> and we just check
|
|
19
|
-
// startswith below
|
|
20
|
-
const symbolicAlleles = ['<TRA', '<DEL', '<INV', '<INS', '<DUP', '<CNV'];
|
|
21
|
-
if (symbolicAlleles.some(a => alt === null || alt === void 0 ? void 0 : alt.startsWith(a))) {
|
|
22
|
-
// END is defined to be a single value, not an array. CHR2 not defined in
|
|
23
|
-
// VCF spec, but should be similar
|
|
24
|
-
const e = ((_b = (_a = feature.get('INFO')) === null || _a === void 0 ? void 0 : _a.END) === null || _b === void 0 ? void 0 : _b[0]) || feature.get('end');
|
|
25
|
-
mateEnd = e;
|
|
26
|
-
mateStart = e - 1;
|
|
27
|
-
mateRefName = (_e = (_d = (_c = feature.get('INFO')) === null || _c === void 0 ? void 0 : _c.CHR2) === null || _d === void 0 ? void 0 : _d[0]) !== null && _e !== void 0 ? _e : refName;
|
|
28
|
-
// re-adjust the arc to be from start to end of feature by re-assigning end
|
|
29
|
-
// to the 'mate'
|
|
30
|
-
start = feature.get('start');
|
|
31
|
-
end = feature.get('start') + 1;
|
|
32
|
-
}
|
|
33
|
-
else if (bnd === null || bnd === void 0 ? void 0 : bnd.MatePosition) {
|
|
34
|
-
const matePosition = bnd.MatePosition.split(':');
|
|
35
|
-
mateEnd = +matePosition[1];
|
|
36
|
-
mateStart = +matePosition[1] - 1;
|
|
37
|
-
mateRefName = matePosition[0];
|
|
38
|
-
}
|
|
39
|
-
return {
|
|
40
|
-
k1: { refName, start, end, strand },
|
|
41
|
-
k2: mate !== null && mate !== void 0 ? mate : { refName: mateRefName, end: mateEnd, start: mateStart },
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
function makeSummary(feature, alt) {
|
|
45
|
-
var _a;
|
|
46
|
-
const { k1, k2 } = f(feature, alt);
|
|
47
|
-
return [
|
|
48
|
-
feature.get('name'),
|
|
49
|
-
feature.get('id'),
|
|
50
|
-
assembleLocString(k1),
|
|
51
|
-
assembleLocString(k2),
|
|
52
|
-
(_a = feature.get('INFO')) === null || _a === void 0 ? void 0 : _a.SVTYPE,
|
|
53
|
-
alt,
|
|
54
|
-
]
|
|
55
|
-
.filter(f => !!f)
|
|
56
|
-
.join(' - ');
|
|
57
|
-
}
|
|
58
|
-
// conditionally rendered tooltip only on mouseover, speeds up
|
|
59
|
-
const SvgTooltip = React.forwardRef(function SvgTooltip2({ feature, alt }, ref) {
|
|
60
|
-
const caption = makeSummary(feature, alt);
|
|
61
|
-
const tooltipWidth = 20 + measureText(caption);
|
|
62
|
-
return ref !== null ? (
|
|
63
|
-
// @ts-expect-error
|
|
64
|
-
React.createElement(Tooltip, { triggerRef: ref },
|
|
65
|
-
React.createElement("rect", { x: 12, y: 0, width: tooltipWidth, height: 20, rx: 5, ry: 5, fill: "black", fillOpacity: "50%" }),
|
|
66
|
-
React.createElement("text", { x: 22, y: 14, fontSize: 10, fill: "white", textLength: tooltipWidth - 20 }, caption))) : null;
|
|
67
|
-
});
|
|
5
|
+
import ArcTooltip from '../../ArcTooltip';
|
|
6
|
+
import { makeFeaturePair, makeSummary } from './util';
|
|
68
7
|
const Arc = observer(function ({ model, feature, alt, assembly, view, }) {
|
|
69
8
|
var _a, _b;
|
|
70
9
|
const [mouseOvered, setMouseOvered] = useState(false);
|
|
71
10
|
const { height } = model;
|
|
72
|
-
const { k1, k2 } =
|
|
11
|
+
const { k1, k2 } = makeFeaturePair(feature, alt);
|
|
73
12
|
const ref = useRef(null);
|
|
74
13
|
const c = getConf(model, 'color', { feature, alt });
|
|
75
14
|
const ra1 = assembly.getCanonicalRefName(k1.refName) || k1.refName;
|
|
@@ -86,9 +25,13 @@ const Arc = observer(function ({ model, feature, alt, assembly, view, }) {
|
|
|
86
25
|
const p2 = r2 - view.offsetPx;
|
|
87
26
|
const left = p1;
|
|
88
27
|
const right = p2;
|
|
28
|
+
const col = mouseOvered ? 'black' : c;
|
|
29
|
+
const sw = 3;
|
|
89
30
|
return absrad > 1 ? (React.createElement(React.Fragment, null,
|
|
90
|
-
React.createElement("path", { d: `M ${left} 0 C ${left} ${destY}, ${right} ${destY}, ${right} 0`, ref: ref, stroke:
|
|
91
|
-
|
|
31
|
+
React.createElement("path", { d: `M ${left} 0 C ${left} ${destY}, ${right} ${destY}, ${right} 0`, ref: ref, stroke: col, strokeWidth: sw, onMouseOut: () => setMouseOvered(false), onMouseOver: () => setMouseOvered(true), onClick: () => model.selectFeature(feature), fill: "none", pointerEvents: "stroke" }),
|
|
32
|
+
k1.mateDirection !== undefined ? (React.createElement("line", { stroke: col, strokeWidth: sw, onMouseOut: () => setMouseOvered(false), onMouseOver: () => setMouseOvered(true), onClick: () => model.selectFeature(feature), x1: left, x2: left + k1.mateDirection * 20, y1: 1.5, y2: 1.5 })) : null,
|
|
33
|
+
k2.mateDirection !== undefined ? (React.createElement("line", { stroke: col, strokeWidth: sw, onMouseOut: () => setMouseOvered(false), onMouseOver: () => setMouseOvered(true), onClick: () => model.selectFeature(feature), x1: right, x2: right + k2.mateDirection * 20, y1: 1.5, y2: 1.5 })) : null,
|
|
34
|
+
mouseOvered ? (React.createElement(ArcTooltip, { contents: makeSummary(feature, alt) })) : null)) : null;
|
|
92
35
|
}
|
|
93
36
|
return null;
|
|
94
37
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Feature } from '@jbrowse/core/util';
|
|
2
|
+
export declare function makeFeaturePair(feature: Feature, alt?: string): {
|
|
3
|
+
k1: {
|
|
4
|
+
refName: string;
|
|
5
|
+
start: number;
|
|
6
|
+
end: number;
|
|
7
|
+
strand: any;
|
|
8
|
+
mateDirection: number;
|
|
9
|
+
};
|
|
10
|
+
k2: {
|
|
11
|
+
refName: string;
|
|
12
|
+
start: number;
|
|
13
|
+
end: number;
|
|
14
|
+
mateDirection?: number | undefined;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export declare function makeSummary(feature: Feature, alt?: string): string;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { parseBreakend } from '@gmod/vcf';
|
|
2
|
+
import { assembleLocString } from '@jbrowse/core/util';
|
|
3
|
+
export function makeFeaturePair(feature, alt) {
|
|
4
|
+
var _a, _b, _c, _d;
|
|
5
|
+
const bnd = alt ? parseBreakend(alt) : undefined;
|
|
6
|
+
let start = feature.get('start');
|
|
7
|
+
let end = feature.get('end');
|
|
8
|
+
const strand = feature.get('strand');
|
|
9
|
+
const mate = feature.get('mate');
|
|
10
|
+
const refName = feature.get('refName');
|
|
11
|
+
let mateRefName;
|
|
12
|
+
let mateEnd = 0;
|
|
13
|
+
let mateStart = 0;
|
|
14
|
+
let joinDirection = 0;
|
|
15
|
+
let mateDirection = 0;
|
|
16
|
+
// one sided bracket used, because there could be <INS:ME> and we just check
|
|
17
|
+
// startswith below
|
|
18
|
+
const symbolicAlleles = ['<TRA', '<DEL', '<INV', '<INS', '<DUP', '<CNV'];
|
|
19
|
+
if (symbolicAlleles.some(a => alt === null || alt === void 0 ? void 0 : alt.startsWith(a))) {
|
|
20
|
+
// END is defined to be a single value, not an array. CHR2 not defined in
|
|
21
|
+
// VCF spec, but should be similar
|
|
22
|
+
const info = feature.get('INFO');
|
|
23
|
+
const e = (_b = (_a = info === null || info === void 0 ? void 0 : info.END) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : end;
|
|
24
|
+
mateRefName = (_d = (_c = info === null || info === void 0 ? void 0 : info.CHR2) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : refName;
|
|
25
|
+
mateEnd = e;
|
|
26
|
+
mateStart = e - 1;
|
|
27
|
+
// re-adjust the arc to be from start to end of feature by re-assigning end
|
|
28
|
+
// to the 'mate'
|
|
29
|
+
start = start;
|
|
30
|
+
end = start + 1;
|
|
31
|
+
}
|
|
32
|
+
else if (bnd === null || bnd === void 0 ? void 0 : bnd.MatePosition) {
|
|
33
|
+
const matePosition = bnd.MatePosition.split(':');
|
|
34
|
+
mateDirection = bnd.MateDirection === 'left' ? 1 : -1;
|
|
35
|
+
joinDirection = bnd.Join === 'left' ? -1 : 1;
|
|
36
|
+
mateEnd = +matePosition[1];
|
|
37
|
+
mateStart = +matePosition[1] - 1;
|
|
38
|
+
mateRefName = matePosition[0];
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
k1: {
|
|
42
|
+
refName,
|
|
43
|
+
start,
|
|
44
|
+
end,
|
|
45
|
+
strand,
|
|
46
|
+
mateDirection,
|
|
47
|
+
},
|
|
48
|
+
k2: mate !== null && mate !== void 0 ? mate : {
|
|
49
|
+
refName: mateRefName,
|
|
50
|
+
end: mateEnd,
|
|
51
|
+
start: mateStart,
|
|
52
|
+
mateDirection: joinDirection,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export function makeSummary(feature, alt) {
|
|
57
|
+
var _a;
|
|
58
|
+
const { k1, k2 } = makeFeaturePair(feature, alt);
|
|
59
|
+
return [
|
|
60
|
+
feature.get('name'),
|
|
61
|
+
feature.get('id'),
|
|
62
|
+
assembleLocString(k1),
|
|
63
|
+
assembleLocString(k2),
|
|
64
|
+
(_a = feature.get('INFO')) === null || _a === void 0 ? void 0 : _a.SVTYPE,
|
|
65
|
+
alt,
|
|
66
|
+
]
|
|
67
|
+
.filter(f => !!f)
|
|
68
|
+
.join(' - ');
|
|
69
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-arc",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.1",
|
|
4
4
|
"description": "JBrowse 2 arc adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -35,9 +35,6 @@
|
|
|
35
35
|
"build:commonjs": "tsc --build tsconfig.build.commonjs.json",
|
|
36
36
|
"clean": "rimraf dist esm *.tsbuildinfo"
|
|
37
37
|
},
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"react-svg-tooltip": "^0.0.11"
|
|
40
|
-
},
|
|
41
38
|
"peerDependencies": {
|
|
42
39
|
"@jbrowse/core": "^2.0.0",
|
|
43
40
|
"@jbrowse/plugin-linear-genome-view": "^2.0.0",
|
|
@@ -56,5 +53,5 @@
|
|
|
56
53
|
"publishConfig": {
|
|
57
54
|
"access": "public"
|
|
58
55
|
},
|
|
59
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "442b5f87efddfdf4ccf520b4d9dd01ddd370cb07"
|
|
60
57
|
}
|