@jbrowse/plugin-sequence 3.6.4 → 3.7.0
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/DivSequenceRenderer/components/DivSequenceRendering.js +6 -65
- package/dist/DivSequenceRenderer/components/Sequence.d.ts +10 -0
- package/dist/DivSequenceRenderer/components/Sequence.js +25 -0
- package/dist/DivSequenceRenderer/components/Translation.d.ts +14 -0
- package/dist/DivSequenceRenderer/components/Translation.js +49 -0
- package/dist/LinearReferenceSequenceDisplay/model.d.ts +17 -2
- package/esm/DivSequenceRenderer/components/DivSequenceRendering.js +4 -66
- package/esm/DivSequenceRenderer/components/Sequence.d.ts +10 -0
- package/esm/DivSequenceRenderer/components/Sequence.js +22 -0
- package/esm/DivSequenceRenderer/components/Translation.d.ts +14 -0
- package/esm/DivSequenceRenderer/components/Translation.js +46 -0
- package/esm/LinearReferenceSequenceDisplay/model.d.ts +17 -2
- package/package.json +5 -5
|
@@ -1,72 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
4
|
-
const react_1 = require("react");
|
|
5
7
|
const util_1 = require("@jbrowse/core/util");
|
|
6
|
-
const material_1 = require("@mui/material");
|
|
7
8
|
const mobx_react_1 = require("mobx-react");
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const normalizedFrame = Math.abs(frame) - 1;
|
|
11
|
-
const seqFrame = seqStart % 3;
|
|
12
|
-
const frameShift = (normalizedFrame - seqFrame + 3) % 3;
|
|
13
|
-
const theme = (0, material_1.useTheme)();
|
|
14
|
-
const frameShiftAdjustedSeqLength = seq.length - frameShift;
|
|
15
|
-
const multipleOfThreeLength = frameShiftAdjustedSeqLength - (frameShiftAdjustedSeqLength % 3);
|
|
16
|
-
const seqSliced = seq.slice(frameShift, frameShift + multipleOfThreeLength);
|
|
17
|
-
const translated = [];
|
|
18
|
-
for (let i = 0; i < seqSliced.length; i += 3) {
|
|
19
|
-
const codon = seqSliced.slice(i, i + 3);
|
|
20
|
-
const normalizedCodon = reverse ? (0, util_1.revcom)(codon) : codon;
|
|
21
|
-
const aminoAcid = codonTable[normalizedCodon] || '';
|
|
22
|
-
translated.push({
|
|
23
|
-
letter: aminoAcid,
|
|
24
|
-
codon: normalizedCodon.toUpperCase(),
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
const codonWidth = (1 / bpPerPx) * 3;
|
|
28
|
-
const renderLetter = 1 / bpPerPx >= 12;
|
|
29
|
-
const frameOffset = frameShift / bpPerPx;
|
|
30
|
-
const startOffset = (region.start - seqStart) / bpPerPx;
|
|
31
|
-
const offset = frameOffset - startOffset;
|
|
32
|
-
const dark = theme.palette.mode === 'dark' ? 'dark' : 'main';
|
|
33
|
-
const defaultFill = colorByCDS
|
|
34
|
-
? (_a = theme.palette.framesCDS.at(frame)) === null || _a === void 0 ? void 0 : _a[dark]
|
|
35
|
-
: (_b = theme.palette.frames.at(frame)) === null || _b === void 0 ? void 0 : _b[dark];
|
|
36
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("rect", { x: 0, y: y, width: width, height: height, fill: defaultFill }), translated.map((element, index) => {
|
|
37
|
-
const x = region.reversed
|
|
38
|
-
? width - (index + 1) * codonWidth - offset
|
|
39
|
-
: codonWidth * index + offset;
|
|
40
|
-
const { letter, codon } = element;
|
|
41
|
-
const codonFill = util_1.defaultStarts.includes(codon)
|
|
42
|
-
? theme.palette.startCodon
|
|
43
|
-
: util_1.defaultStops.includes(codon)
|
|
44
|
-
? theme.palette.stopCodon
|
|
45
|
-
: undefined;
|
|
46
|
-
return !(renderLetter || codonFill) ? null : ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("rect", { x: x, y: y, width: renderLetter
|
|
47
|
-
? codonWidth
|
|
48
|
-
: codonWidth + 0.7, height: height, stroke: renderLetter ? '#555' : 'none', fill: codonFill || 'none' }), renderLetter ? ((0, jsx_runtime_1.jsx)("text", { x: x + codonWidth / 2, fontSize: height - 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", children: letter })) : null] }, `${index}-${letter}`));
|
|
49
|
-
})] }));
|
|
50
|
-
}
|
|
51
|
-
function Sequence({ bpPerPx, region, feature, sequenceType, height, seq, y, }) {
|
|
52
|
-
const render = 1 / bpPerPx >= 12;
|
|
53
|
-
const s = feature.get('start');
|
|
54
|
-
const e = feature.get('end');
|
|
55
|
-
const [leftPx, rightPx] = (0, util_1.bpSpanPx)(s, e, region, bpPerPx);
|
|
56
|
-
const reverse = region.reversed;
|
|
57
|
-
const len = e - s;
|
|
58
|
-
const w = Math.max((rightPx - leftPx) / len, 0.8);
|
|
59
|
-
const theme = (0, material_1.useTheme)();
|
|
60
|
-
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: seq.split('').map((letter, index) => {
|
|
61
|
-
const color = sequenceType === 'dna'
|
|
62
|
-
?
|
|
63
|
-
theme.palette.bases[letter.toUpperCase()]
|
|
64
|
-
: undefined;
|
|
65
|
-
const dark = theme.palette.mode === 'dark';
|
|
66
|
-
const x = reverse ? rightPx - (index + 1) * w : leftPx + index * w;
|
|
67
|
-
return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("rect", { x: x, y: y, width: w, height: height, fill: color ? (dark ? color.dark : color.main) : '#aaa', stroke: render ? '#555' : 'none' }), render ? ((0, jsx_runtime_1.jsx)("text", { x: x + w / 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", fontSize: height - 2, fill: color ? theme.palette.getContrastText(color.main) : 'black', children: letter })) : null] }, `${letter}-${index}`));
|
|
68
|
-
}) }));
|
|
69
|
-
}
|
|
9
|
+
const Sequence_1 = __importDefault(require("./Sequence"));
|
|
10
|
+
const Translation_1 = __importDefault(require("./Translation"));
|
|
70
11
|
function SequenceSVG({ regions, width, colorByCDS, features = new Map(), showReverse = true, showForward = true, showTranslation = true, sequenceType = 'dna', bpPerPx, rowHeight, }) {
|
|
71
12
|
const region = regions[0];
|
|
72
13
|
const codonTable = (0, util_1.generateCodonTable)(util_1.defaultCodonTable);
|
|
@@ -85,7 +26,7 @@ function SequenceSVG({ regions, width, colorByCDS, features = new Map(), showRev
|
|
|
85
26
|
const [topFrames, bottomFrames] = region.reversed
|
|
86
27
|
? [reverseFrames.toReversed(), forwardFrames.toReversed()]
|
|
87
28
|
: [forwardFrames, reverseFrames];
|
|
88
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [topFrames.map(index => ((0, jsx_runtime_1.jsx)(
|
|
29
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [topFrames.map(index => ((0, jsx_runtime_1.jsx)(Translation_1.default, { width: width, colorByCDS: colorByCDS, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, seqStart: feature.get('start'), height: rowHeight, reverse: region.reversed }, `translation-${index}`))), showForward && showSequence ? ((0, jsx_runtime_1.jsx)(Sequence_1.default, { height: rowHeight, sequenceType: sequenceType, y: (currY += rowHeight), feature: feature, region: region, seq: region.reversed ? (0, util_1.complement)(seq) : seq, bpPerPx: bpPerPx })) : null, showReverse && showSequence ? ((0, jsx_runtime_1.jsx)(Sequence_1.default, { height: rowHeight, sequenceType: sequenceType, y: (currY += rowHeight), feature: feature, region: region, seq: region.reversed ? seq : (0, util_1.complement)(seq), bpPerPx: bpPerPx })) : null, bottomFrames.map(index => ((0, jsx_runtime_1.jsx)(Translation_1.default, { width: width, colorByCDS: colorByCDS, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, seqStart: feature.get('start'), height: rowHeight, reverse: !region.reversed }, `rev-translation-${index}`)))] }));
|
|
89
30
|
}
|
|
90
31
|
function Wrapper({ exportSVG, width, totalHeight, children, }) {
|
|
91
32
|
return exportSVG ? (children) : ((0, jsx_runtime_1.jsx)("svg", { "data-testid": "sequence_track", width: width, height: totalHeight, style: {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Feature, Region } from '@jbrowse/core/util';
|
|
2
|
+
export default function Sequence({ bpPerPx, region, feature, sequenceType, height, seq, y, }: {
|
|
3
|
+
seq: string;
|
|
4
|
+
bpPerPx: number;
|
|
5
|
+
sequenceType: string;
|
|
6
|
+
height: number;
|
|
7
|
+
region: Region;
|
|
8
|
+
feature: Feature;
|
|
9
|
+
y: number;
|
|
10
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = Sequence;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const util_1 = require("@jbrowse/core/util");
|
|
7
|
+
const material_1 = require("@mui/material");
|
|
8
|
+
function Sequence({ bpPerPx, region, feature, sequenceType, height, seq, y, }) {
|
|
9
|
+
const theme = (0, material_1.useTheme)();
|
|
10
|
+
const render = 1 / bpPerPx >= 12;
|
|
11
|
+
const s = feature.get('start');
|
|
12
|
+
const e = feature.get('end');
|
|
13
|
+
const [leftPx, rightPx] = (0, util_1.bpSpanPx)(s, e, region, bpPerPx);
|
|
14
|
+
const reverse = region.reversed;
|
|
15
|
+
const len = e - s;
|
|
16
|
+
const w = Math.max((rightPx - leftPx) / len, 0.8);
|
|
17
|
+
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: seq.split('').map((letter, index) => {
|
|
18
|
+
const color = sequenceType === 'dna'
|
|
19
|
+
?
|
|
20
|
+
theme.palette.bases[letter.toUpperCase()]
|
|
21
|
+
: undefined;
|
|
22
|
+
const x = reverse ? rightPx - (index + 1) * w : leftPx + index * w;
|
|
23
|
+
return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("rect", { x: x, y: y, width: w, height: height, fill: color ? color.main : '#aaa', stroke: render ? '#555' : 'none' }), render ? ((0, jsx_runtime_1.jsx)("text", { x: x + w / 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", fontSize: height - 2, fill: color ? theme.palette.getContrastText(color.main) : 'black', children: letter })) : null] }, `${letter}-${index}`));
|
|
24
|
+
}) }));
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Frame, Region } from '@jbrowse/core/util';
|
|
2
|
+
export default function Translation({ codonTable, seq, frame, width, bpPerPx, colorByCDS, region, seqStart, height, y, reverse, }: {
|
|
3
|
+
codonTable: Record<string, string>;
|
|
4
|
+
width: number;
|
|
5
|
+
seq: string;
|
|
6
|
+
frame: Frame;
|
|
7
|
+
colorByCDS: boolean;
|
|
8
|
+
bpPerPx: number;
|
|
9
|
+
region: Region;
|
|
10
|
+
seqStart: number;
|
|
11
|
+
reverse?: boolean;
|
|
12
|
+
height: number;
|
|
13
|
+
y: number;
|
|
14
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = Translation;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const util_1 = require("@jbrowse/core/util");
|
|
7
|
+
const material_1 = require("@mui/material");
|
|
8
|
+
function Translation({ codonTable, seq, frame, width, bpPerPx, colorByCDS, region, seqStart, height, y, reverse = false, }) {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
const theme = (0, material_1.useTheme)();
|
|
11
|
+
const normalizedFrame = Math.abs(frame) - 1;
|
|
12
|
+
const seqFrame = seqStart % 3;
|
|
13
|
+
const frameShift = (normalizedFrame - seqFrame + 3) % 3;
|
|
14
|
+
const frameShiftAdjustedSeqLength = seq.length - frameShift;
|
|
15
|
+
const multipleOfThreeLength = frameShiftAdjustedSeqLength - (frameShiftAdjustedSeqLength % 3);
|
|
16
|
+
const seqSliced = seq.slice(frameShift, frameShift + multipleOfThreeLength);
|
|
17
|
+
const translated = [];
|
|
18
|
+
for (let i = 0; i < seqSliced.length; i += 3) {
|
|
19
|
+
const codon = seqSliced.slice(i, i + 3);
|
|
20
|
+
const normalizedCodon = reverse ? (0, util_1.revcom)(codon) : codon;
|
|
21
|
+
const aminoAcid = codonTable[normalizedCodon] || '';
|
|
22
|
+
translated.push({
|
|
23
|
+
letter: aminoAcid,
|
|
24
|
+
codon: normalizedCodon.toUpperCase(),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const codonWidth = (1 / bpPerPx) * 3;
|
|
28
|
+
const renderLetter = 1 / bpPerPx >= 12;
|
|
29
|
+
const frameOffset = frameShift / bpPerPx;
|
|
30
|
+
const startOffset = (region.start - seqStart) / bpPerPx;
|
|
31
|
+
const offset = frameOffset - startOffset;
|
|
32
|
+
const defaultFill = colorByCDS
|
|
33
|
+
? (_a = theme.palette.framesCDS.at(frame)) === null || _a === void 0 ? void 0 : _a.main
|
|
34
|
+
: (_b = theme.palette.frames.at(frame)) === null || _b === void 0 ? void 0 : _b.main;
|
|
35
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("rect", { x: 0, y: y, width: width, height: height, fill: defaultFill }), translated.map((element, index) => {
|
|
36
|
+
const x = region.reversed
|
|
37
|
+
? width - (index + 1) * codonWidth - offset
|
|
38
|
+
: codonWidth * index + offset;
|
|
39
|
+
const { letter, codon } = element;
|
|
40
|
+
const codonFill = util_1.defaultStarts.includes(codon)
|
|
41
|
+
? theme.palette.startCodon
|
|
42
|
+
: util_1.defaultStops.includes(codon)
|
|
43
|
+
? theme.palette.stopCodon
|
|
44
|
+
: undefined;
|
|
45
|
+
return !(renderLetter || codonFill) ? null : ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("rect", { x: x, y: y, width: renderLetter
|
|
46
|
+
? codonWidth
|
|
47
|
+
: codonWidth + 0.7, height: height, stroke: renderLetter ? '#555' : 'none', fill: codonFill || 'none' }), renderLetter ? ((0, jsx_runtime_1.jsx)("text", { x: x + codonWidth / 2, fontSize: height - 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", children: letter })) : null] }, `${index}-${letter}`));
|
|
48
|
+
})] }));
|
|
49
|
+
}
|
|
@@ -174,6 +174,7 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
174
174
|
regionCannotBeRenderedText(_region: import("@jbrowse/core/util").Region): "" | "Force load to see features";
|
|
175
175
|
regionCannotBeRendered(_region: import("@jbrowse/core/util").Region): import("react/jsx-runtime").JSX.Element | null;
|
|
176
176
|
} & {
|
|
177
|
+
mouseoverExtraInformation: string | undefined;
|
|
177
178
|
featureIdUnderMouse: undefined | string;
|
|
178
179
|
contextMenuFeature: undefined | import("@jbrowse/core/util").Feature;
|
|
179
180
|
} & {
|
|
@@ -188,9 +189,22 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
188
189
|
} & {
|
|
189
190
|
readonly features: import("@jbrowse/core/util/compositeMap").default<string, import("@jbrowse/core/util").Feature>;
|
|
190
191
|
readonly featureUnderMouse: import("@jbrowse/core/util").Feature | undefined;
|
|
192
|
+
readonly layoutFeatures: import("@jbrowse/core/util/compositeMap").default<string, [number, number, number, number] | [number, number, number, number, {
|
|
193
|
+
label?: string;
|
|
194
|
+
description?: string;
|
|
195
|
+
refName: string;
|
|
196
|
+
}]>;
|
|
191
197
|
getFeatureOverlapping(blockKey: string, x: number, y: number): string | undefined;
|
|
192
|
-
getFeatureByID(blockKey: string, id: string): [number, number, number, number] |
|
|
193
|
-
|
|
198
|
+
getFeatureByID(blockKey: string, id: string): ([number, number, number, number] | [number, number, number, number, {
|
|
199
|
+
label?: string;
|
|
200
|
+
description?: string;
|
|
201
|
+
refName: string;
|
|
202
|
+
}]) | undefined;
|
|
203
|
+
searchFeatureByID(id: string): ([number, number, number, number] | [number, number, number, number, {
|
|
204
|
+
label?: string;
|
|
205
|
+
description?: string;
|
|
206
|
+
refName: string;
|
|
207
|
+
}]) | undefined;
|
|
194
208
|
} & {
|
|
195
209
|
addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
|
|
196
210
|
deleteBlock(key: string): void;
|
|
@@ -199,6 +213,7 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
199
213
|
clearFeatureSelection(): void;
|
|
200
214
|
setFeatureIdUnderMouse(feature?: string): void;
|
|
201
215
|
setContextMenuFeature(feature?: import("@jbrowse/core/util").Feature): void;
|
|
216
|
+
setMouseoverExtraInformation(extra?: string): void;
|
|
202
217
|
} & {
|
|
203
218
|
reload(): Promise<void>;
|
|
204
219
|
} & {
|
|
@@ -1,70 +1,8 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
2
|
-
import {
|
|
3
|
-
import { bpSpanPx, complement, defaultCodonTable, defaultStarts, defaultStops, generateCodonTable, revcom, } from '@jbrowse/core/util';
|
|
4
|
-
import { useTheme } from '@mui/material';
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { complement, defaultCodonTable, generateCodonTable, } from '@jbrowse/core/util';
|
|
5
3
|
import { observer } from 'mobx-react';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const normalizedFrame = Math.abs(frame) - 1;
|
|
9
|
-
const seqFrame = seqStart % 3;
|
|
10
|
-
const frameShift = (normalizedFrame - seqFrame + 3) % 3;
|
|
11
|
-
const theme = useTheme();
|
|
12
|
-
const frameShiftAdjustedSeqLength = seq.length - frameShift;
|
|
13
|
-
const multipleOfThreeLength = frameShiftAdjustedSeqLength - (frameShiftAdjustedSeqLength % 3);
|
|
14
|
-
const seqSliced = seq.slice(frameShift, frameShift + multipleOfThreeLength);
|
|
15
|
-
const translated = [];
|
|
16
|
-
for (let i = 0; i < seqSliced.length; i += 3) {
|
|
17
|
-
const codon = seqSliced.slice(i, i + 3);
|
|
18
|
-
const normalizedCodon = reverse ? revcom(codon) : codon;
|
|
19
|
-
const aminoAcid = codonTable[normalizedCodon] || '';
|
|
20
|
-
translated.push({
|
|
21
|
-
letter: aminoAcid,
|
|
22
|
-
codon: normalizedCodon.toUpperCase(),
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
const codonWidth = (1 / bpPerPx) * 3;
|
|
26
|
-
const renderLetter = 1 / bpPerPx >= 12;
|
|
27
|
-
const frameOffset = frameShift / bpPerPx;
|
|
28
|
-
const startOffset = (region.start - seqStart) / bpPerPx;
|
|
29
|
-
const offset = frameOffset - startOffset;
|
|
30
|
-
const dark = theme.palette.mode === 'dark' ? 'dark' : 'main';
|
|
31
|
-
const defaultFill = colorByCDS
|
|
32
|
-
? (_a = theme.palette.framesCDS.at(frame)) === null || _a === void 0 ? void 0 : _a[dark]
|
|
33
|
-
: (_b = theme.palette.frames.at(frame)) === null || _b === void 0 ? void 0 : _b[dark];
|
|
34
|
-
return (_jsxs(_Fragment, { children: [_jsx("rect", { x: 0, y: y, width: width, height: height, fill: defaultFill }), translated.map((element, index) => {
|
|
35
|
-
const x = region.reversed
|
|
36
|
-
? width - (index + 1) * codonWidth - offset
|
|
37
|
-
: codonWidth * index + offset;
|
|
38
|
-
const { letter, codon } = element;
|
|
39
|
-
const codonFill = defaultStarts.includes(codon)
|
|
40
|
-
? theme.palette.startCodon
|
|
41
|
-
: defaultStops.includes(codon)
|
|
42
|
-
? theme.palette.stopCodon
|
|
43
|
-
: undefined;
|
|
44
|
-
return !(renderLetter || codonFill) ? null : (_jsxs(Fragment, { children: [_jsx("rect", { x: x, y: y, width: renderLetter
|
|
45
|
-
? codonWidth
|
|
46
|
-
: codonWidth + 0.7, height: height, stroke: renderLetter ? '#555' : 'none', fill: codonFill || 'none' }), renderLetter ? (_jsx("text", { x: x + codonWidth / 2, fontSize: height - 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", children: letter })) : null] }, `${index}-${letter}`));
|
|
47
|
-
})] }));
|
|
48
|
-
}
|
|
49
|
-
function Sequence({ bpPerPx, region, feature, sequenceType, height, seq, y, }) {
|
|
50
|
-
const render = 1 / bpPerPx >= 12;
|
|
51
|
-
const s = feature.get('start');
|
|
52
|
-
const e = feature.get('end');
|
|
53
|
-
const [leftPx, rightPx] = bpSpanPx(s, e, region, bpPerPx);
|
|
54
|
-
const reverse = region.reversed;
|
|
55
|
-
const len = e - s;
|
|
56
|
-
const w = Math.max((rightPx - leftPx) / len, 0.8);
|
|
57
|
-
const theme = useTheme();
|
|
58
|
-
return (_jsx(_Fragment, { children: seq.split('').map((letter, index) => {
|
|
59
|
-
const color = sequenceType === 'dna'
|
|
60
|
-
?
|
|
61
|
-
theme.palette.bases[letter.toUpperCase()]
|
|
62
|
-
: undefined;
|
|
63
|
-
const dark = theme.palette.mode === 'dark';
|
|
64
|
-
const x = reverse ? rightPx - (index + 1) * w : leftPx + index * w;
|
|
65
|
-
return (_jsxs(Fragment, { children: [_jsx("rect", { x: x, y: y, width: w, height: height, fill: color ? (dark ? color.dark : color.main) : '#aaa', stroke: render ? '#555' : 'none' }), render ? (_jsx("text", { x: x + w / 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", fontSize: height - 2, fill: color ? theme.palette.getContrastText(color.main) : 'black', children: letter })) : null] }, `${letter}-${index}`));
|
|
66
|
-
}) }));
|
|
67
|
-
}
|
|
4
|
+
import Sequence from './Sequence';
|
|
5
|
+
import Translation from './Translation';
|
|
68
6
|
function SequenceSVG({ regions, width, colorByCDS, features = new Map(), showReverse = true, showForward = true, showTranslation = true, sequenceType = 'dna', bpPerPx, rowHeight, }) {
|
|
69
7
|
const region = regions[0];
|
|
70
8
|
const codonTable = generateCodonTable(defaultCodonTable);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Feature, Region } from '@jbrowse/core/util';
|
|
2
|
+
export default function Sequence({ bpPerPx, region, feature, sequenceType, height, seq, y, }: {
|
|
3
|
+
seq: string;
|
|
4
|
+
bpPerPx: number;
|
|
5
|
+
sequenceType: string;
|
|
6
|
+
height: number;
|
|
7
|
+
region: Region;
|
|
8
|
+
feature: Feature;
|
|
9
|
+
y: number;
|
|
10
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment } from 'react';
|
|
3
|
+
import { bpSpanPx } from '@jbrowse/core/util';
|
|
4
|
+
import { useTheme } from '@mui/material';
|
|
5
|
+
export default function Sequence({ bpPerPx, region, feature, sequenceType, height, seq, y, }) {
|
|
6
|
+
const theme = useTheme();
|
|
7
|
+
const render = 1 / bpPerPx >= 12;
|
|
8
|
+
const s = feature.get('start');
|
|
9
|
+
const e = feature.get('end');
|
|
10
|
+
const [leftPx, rightPx] = bpSpanPx(s, e, region, bpPerPx);
|
|
11
|
+
const reverse = region.reversed;
|
|
12
|
+
const len = e - s;
|
|
13
|
+
const w = Math.max((rightPx - leftPx) / len, 0.8);
|
|
14
|
+
return (_jsx(_Fragment, { children: seq.split('').map((letter, index) => {
|
|
15
|
+
const color = sequenceType === 'dna'
|
|
16
|
+
?
|
|
17
|
+
theme.palette.bases[letter.toUpperCase()]
|
|
18
|
+
: undefined;
|
|
19
|
+
const x = reverse ? rightPx - (index + 1) * w : leftPx + index * w;
|
|
20
|
+
return (_jsxs(Fragment, { children: [_jsx("rect", { x: x, y: y, width: w, height: height, fill: color ? color.main : '#aaa', stroke: render ? '#555' : 'none' }), render ? (_jsx("text", { x: x + w / 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", fontSize: height - 2, fill: color ? theme.palette.getContrastText(color.main) : 'black', children: letter })) : null] }, `${letter}-${index}`));
|
|
21
|
+
}) }));
|
|
22
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Frame, Region } from '@jbrowse/core/util';
|
|
2
|
+
export default function Translation({ codonTable, seq, frame, width, bpPerPx, colorByCDS, region, seqStart, height, y, reverse, }: {
|
|
3
|
+
codonTable: Record<string, string>;
|
|
4
|
+
width: number;
|
|
5
|
+
seq: string;
|
|
6
|
+
frame: Frame;
|
|
7
|
+
colorByCDS: boolean;
|
|
8
|
+
bpPerPx: number;
|
|
9
|
+
region: Region;
|
|
10
|
+
seqStart: number;
|
|
11
|
+
reverse?: boolean;
|
|
12
|
+
height: number;
|
|
13
|
+
y: number;
|
|
14
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment } from 'react';
|
|
3
|
+
import { defaultStarts, defaultStops, revcom } from '@jbrowse/core/util';
|
|
4
|
+
import { useTheme } from '@mui/material';
|
|
5
|
+
export default function Translation({ codonTable, seq, frame, width, bpPerPx, colorByCDS, region, seqStart, height, y, reverse = false, }) {
|
|
6
|
+
var _a, _b;
|
|
7
|
+
const theme = useTheme();
|
|
8
|
+
const normalizedFrame = Math.abs(frame) - 1;
|
|
9
|
+
const seqFrame = seqStart % 3;
|
|
10
|
+
const frameShift = (normalizedFrame - seqFrame + 3) % 3;
|
|
11
|
+
const frameShiftAdjustedSeqLength = seq.length - frameShift;
|
|
12
|
+
const multipleOfThreeLength = frameShiftAdjustedSeqLength - (frameShiftAdjustedSeqLength % 3);
|
|
13
|
+
const seqSliced = seq.slice(frameShift, frameShift + multipleOfThreeLength);
|
|
14
|
+
const translated = [];
|
|
15
|
+
for (let i = 0; i < seqSliced.length; i += 3) {
|
|
16
|
+
const codon = seqSliced.slice(i, i + 3);
|
|
17
|
+
const normalizedCodon = reverse ? revcom(codon) : codon;
|
|
18
|
+
const aminoAcid = codonTable[normalizedCodon] || '';
|
|
19
|
+
translated.push({
|
|
20
|
+
letter: aminoAcid,
|
|
21
|
+
codon: normalizedCodon.toUpperCase(),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const codonWidth = (1 / bpPerPx) * 3;
|
|
25
|
+
const renderLetter = 1 / bpPerPx >= 12;
|
|
26
|
+
const frameOffset = frameShift / bpPerPx;
|
|
27
|
+
const startOffset = (region.start - seqStart) / bpPerPx;
|
|
28
|
+
const offset = frameOffset - startOffset;
|
|
29
|
+
const defaultFill = colorByCDS
|
|
30
|
+
? (_a = theme.palette.framesCDS.at(frame)) === null || _a === void 0 ? void 0 : _a.main
|
|
31
|
+
: (_b = theme.palette.frames.at(frame)) === null || _b === void 0 ? void 0 : _b.main;
|
|
32
|
+
return (_jsxs(_Fragment, { children: [_jsx("rect", { x: 0, y: y, width: width, height: height, fill: defaultFill }), translated.map((element, index) => {
|
|
33
|
+
const x = region.reversed
|
|
34
|
+
? width - (index + 1) * codonWidth - offset
|
|
35
|
+
: codonWidth * index + offset;
|
|
36
|
+
const { letter, codon } = element;
|
|
37
|
+
const codonFill = defaultStarts.includes(codon)
|
|
38
|
+
? theme.palette.startCodon
|
|
39
|
+
: defaultStops.includes(codon)
|
|
40
|
+
? theme.palette.stopCodon
|
|
41
|
+
: undefined;
|
|
42
|
+
return !(renderLetter || codonFill) ? null : (_jsxs(Fragment, { children: [_jsx("rect", { x: x, y: y, width: renderLetter
|
|
43
|
+
? codonWidth
|
|
44
|
+
: codonWidth + 0.7, height: height, stroke: renderLetter ? '#555' : 'none', fill: codonFill || 'none' }), renderLetter ? (_jsx("text", { x: x + codonWidth / 2, fontSize: height - 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", children: letter })) : null] }, `${index}-${letter}`));
|
|
45
|
+
})] }));
|
|
46
|
+
}
|
|
@@ -174,6 +174,7 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
174
174
|
regionCannotBeRenderedText(_region: import("@jbrowse/core/util").Region): "" | "Force load to see features";
|
|
175
175
|
regionCannotBeRendered(_region: import("@jbrowse/core/util").Region): import("react/jsx-runtime").JSX.Element | null;
|
|
176
176
|
} & {
|
|
177
|
+
mouseoverExtraInformation: string | undefined;
|
|
177
178
|
featureIdUnderMouse: undefined | string;
|
|
178
179
|
contextMenuFeature: undefined | import("@jbrowse/core/util").Feature;
|
|
179
180
|
} & {
|
|
@@ -188,9 +189,22 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
188
189
|
} & {
|
|
189
190
|
readonly features: import("@jbrowse/core/util/compositeMap").default<string, import("@jbrowse/core/util").Feature>;
|
|
190
191
|
readonly featureUnderMouse: import("@jbrowse/core/util").Feature | undefined;
|
|
192
|
+
readonly layoutFeatures: import("@jbrowse/core/util/compositeMap").default<string, [number, number, number, number] | [number, number, number, number, {
|
|
193
|
+
label?: string;
|
|
194
|
+
description?: string;
|
|
195
|
+
refName: string;
|
|
196
|
+
}]>;
|
|
191
197
|
getFeatureOverlapping(blockKey: string, x: number, y: number): string | undefined;
|
|
192
|
-
getFeatureByID(blockKey: string, id: string): [number, number, number, number] |
|
|
193
|
-
|
|
198
|
+
getFeatureByID(blockKey: string, id: string): ([number, number, number, number] | [number, number, number, number, {
|
|
199
|
+
label?: string;
|
|
200
|
+
description?: string;
|
|
201
|
+
refName: string;
|
|
202
|
+
}]) | undefined;
|
|
203
|
+
searchFeatureByID(id: string): ([number, number, number, number] | [number, number, number, number, {
|
|
204
|
+
label?: string;
|
|
205
|
+
description?: string;
|
|
206
|
+
refName: string;
|
|
207
|
+
}]) | undefined;
|
|
194
208
|
} & {
|
|
195
209
|
addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
|
|
196
210
|
deleteBlock(key: string): void;
|
|
@@ -199,6 +213,7 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
199
213
|
clearFeatureSelection(): void;
|
|
200
214
|
setFeatureIdUnderMouse(feature?: string): void;
|
|
201
215
|
setContextMenuFeature(feature?: import("@jbrowse/core/util").Feature): void;
|
|
216
|
+
setMouseoverExtraInformation(extra?: string): void;
|
|
202
217
|
} & {
|
|
203
218
|
reload(): Promise<void>;
|
|
204
219
|
} & {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-sequence",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "JBrowse 2 sequence adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"@gmod/abortable-promise-cache": "^3.0.1",
|
|
40
40
|
"@gmod/indexedfasta": "^4.0.0",
|
|
41
41
|
"@gmod/twobit": "^6.0.0",
|
|
42
|
-
"@jbrowse/core": "^3.
|
|
43
|
-
"@jbrowse/plugin-linear-genome-view": "^3.
|
|
44
|
-
"@jbrowse/plugin-wiggle": "^3.
|
|
42
|
+
"@jbrowse/core": "^3.7.0",
|
|
43
|
+
"@jbrowse/plugin-linear-genome-view": "^3.7.0",
|
|
44
|
+
"@jbrowse/plugin-wiggle": "^3.7.0",
|
|
45
45
|
"@mui/material": "^7.0.0",
|
|
46
46
|
"mobx": "^6.0.0",
|
|
47
47
|
"mobx-react": "^9.0.0",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"distModule": "esm/index.js",
|
|
58
58
|
"srcModule": "src/index.ts",
|
|
59
59
|
"module": "esm/index.js",
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "85bdd0d58286b7adbfd408146b15847676317635"
|
|
61
61
|
}
|