@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.
@@ -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
- function Translation({ codonTable, seq, frame, width, bpPerPx, colorByCDS, region, seqStart, height, y, reverse = false, }) {
9
- var _a, _b;
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)(Translation, { 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, { 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, { 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, { 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}`)))] }));
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] | undefined;
193
- searchFeatureByID(id: string): [number, number, number, number] | undefined;
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, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Fragment } from 'react';
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
- function Translation({ codonTable, seq, frame, width, bpPerPx, colorByCDS, region, seqStart, height, y, reverse = false, }) {
7
- var _a, _b;
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] | undefined;
193
- searchFeatureByID(id: string): [number, number, number, number] | undefined;
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.6.4",
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.6.4",
43
- "@jbrowse/plugin-linear-genome-view": "^3.6.4",
44
- "@jbrowse/plugin-wiggle": "^3.6.4",
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": "3db8e50ce2bd9c081efbf6c2e7ae5f342380a25a"
60
+ "gitHead": "85bdd0d58286b7adbfd408146b15847676317635"
61
61
  }