@jbrowse/plugin-sequence 2.10.3 → 2.11.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.d.ts +1 -0
- package/dist/DivSequenceRenderer/components/DivSequenceRendering.js +56 -41
- package/dist/LinearReferenceSequenceDisplay/model.d.ts +38 -20
- package/dist/LinearReferenceSequenceDisplay/model.js +4 -2
- package/esm/DivSequenceRenderer/components/DivSequenceRendering.d.ts +1 -0
- package/esm/DivSequenceRenderer/components/DivSequenceRendering.js +56 -41
- package/esm/LinearReferenceSequenceDisplay/model.d.ts +38 -20
- package/esm/LinearReferenceSequenceDisplay/model.js +4 -2
- package/package.json +2 -2
|
@@ -7,42 +7,54 @@ const react_1 = __importDefault(require("react"));
|
|
|
7
7
|
const ui_1 = require("@jbrowse/core/ui");
|
|
8
8
|
const mobx_react_1 = require("mobx-react");
|
|
9
9
|
const util_1 = require("@jbrowse/core/util");
|
|
10
|
-
function Translation(
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// can otherwise result in effectiveFrame -1
|
|
19
|
-
const effectiveFrame = (frame + tilt + 3) % 3;
|
|
20
|
-
const seqSliced = seq.slice(effectiveFrame);
|
|
10
|
+
function Translation({ codonTable, seq, frame, bpPerPx, colorByCDS, region, seqStart, height, y, reverse = false, theme, }) {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
const normalizedFrame = Math.abs(frame) - 1;
|
|
13
|
+
const seqFrame = seqStart % 3;
|
|
14
|
+
const frameShift = (normalizedFrame - seqFrame + 3) % 3;
|
|
15
|
+
const frameShiftAdjustedSeqLength = seq.length - frameShift;
|
|
16
|
+
const multipleOfThreeLength = frameShiftAdjustedSeqLength - (frameShiftAdjustedSeqLength % 3);
|
|
17
|
+
const seqSliced = seq.slice(frameShift, frameShift + multipleOfThreeLength);
|
|
21
18
|
const translated = [];
|
|
22
19
|
for (let i = 0; i < seqSliced.length; i += 3) {
|
|
23
20
|
const codon = seqSliced.slice(i, i + 3);
|
|
24
21
|
const normalizedCodon = reverse ? (0, util_1.revcom)(codon) : codon;
|
|
25
22
|
const aminoAcid = codonTable[normalizedCodon] || '';
|
|
26
|
-
translated.push({
|
|
23
|
+
translated.push({
|
|
24
|
+
letter: aminoAcid,
|
|
25
|
+
codon: normalizedCodon.toUpperCase(),
|
|
26
|
+
});
|
|
27
27
|
}
|
|
28
|
-
const w = (1 / scale) * 3;
|
|
29
|
-
const drop = region.start === 0 ? 0 : w;
|
|
30
|
-
const render = 1 / bpPerPx >= 12;
|
|
31
28
|
const width = (region.end - region.start) / bpPerPx;
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
29
|
+
const codonWidth = (1 / bpPerPx) * 3;
|
|
30
|
+
const renderLetter = 1 / bpPerPx >= 12;
|
|
31
|
+
const frameOffset = frameShift / bpPerPx;
|
|
32
|
+
const startOffset = (region.start - seqStart) / bpPerPx;
|
|
33
|
+
const offset = frameOffset - startOffset;
|
|
34
|
+
const defaultFill = colorByCDS
|
|
35
|
+
? (_a = theme === null || theme === void 0 ? void 0 : theme.palette.framesCDS.at(frame)) === null || _a === void 0 ? void 0 : _a.main
|
|
36
|
+
: (_b = theme === null || theme === void 0 ? void 0 : theme.palette.frames.at(frame)) === null || _b === void 0 ? void 0 : _b.main;
|
|
37
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
38
|
+
react_1.default.createElement("rect", { x: 0, y: y, width: width, height: height, fill: defaultFill }),
|
|
39
|
+
translated.map((element, index) => {
|
|
40
|
+
const x = region.reversed
|
|
41
|
+
? width - (index + 1) * codonWidth - offset
|
|
42
|
+
: codonWidth * index + offset;
|
|
43
|
+
const { letter, codon } = element;
|
|
44
|
+
const codonFill = util_1.defaultStarts.includes(codon)
|
|
45
|
+
? theme === null || theme === void 0 ? void 0 : theme.palette.startCodon
|
|
46
|
+
: util_1.defaultStops.includes(codon)
|
|
47
|
+
? theme === null || theme === void 0 ? void 0 : theme.palette.stopCodon
|
|
48
|
+
: undefined;
|
|
49
|
+
if (!(renderLetter || codonFill)) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
return (react_1.default.createElement(react_1.default.Fragment, { key: `${index}-${letter}` },
|
|
53
|
+
react_1.default.createElement("rect", { x: x, y: y, width: renderLetter
|
|
54
|
+
? codonWidth
|
|
55
|
+
: codonWidth + 0.7 /* small fudge factor when zoomed out*/, height: height, stroke: renderLetter ? '#555' : 'none', fill: codonFill || 'none' }),
|
|
56
|
+
renderLetter ? (react_1.default.createElement("text", { x: x + codonWidth / 2, fontSize: height - 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle" }, letter)) : null));
|
|
57
|
+
})));
|
|
46
58
|
}
|
|
47
59
|
function DNA(props) {
|
|
48
60
|
const { bpPerPx, region, feature, theme, height, seq, y } = props;
|
|
@@ -60,7 +72,7 @@ function DNA(props) {
|
|
|
60
72
|
render ? (react_1.default.createElement("text", { x: x + w / 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", fontSize: height - 2, fill: color ? theme.palette.getContrastText(color.main) : 'black' }, letter)) : null));
|
|
61
73
|
})));
|
|
62
74
|
}
|
|
63
|
-
function SequenceSVG({ regions, theme: configTheme, features = new Map(), showReverse = true, showForward = true, showTranslation = true, bpPerPx, rowHeight, }) {
|
|
75
|
+
function SequenceSVG({ regions, theme: configTheme, colorByCDS, features = new Map(), showReverse = true, showForward = true, showTranslation = true, bpPerPx, rowHeight, }) {
|
|
64
76
|
const [region] = regions;
|
|
65
77
|
const theme = (0, ui_1.createJBrowseTheme)(configTheme);
|
|
66
78
|
const codonTable = (0, util_1.generateCodonTable)(util_1.defaultCodonTable);
|
|
@@ -75,23 +87,26 @@ function SequenceSVG({ regions, theme: configTheme, features = new Map(), showRe
|
|
|
75
87
|
// incrementer for the y-position of the current sequence being rendered
|
|
76
88
|
// (applies to both translation rows and dna rows)
|
|
77
89
|
let currY = -rowHeight;
|
|
90
|
+
const showDNA = bpPerPx <= 1;
|
|
91
|
+
const forwardFrames = showTranslation && showForward ? [3, 2, 1] : [];
|
|
92
|
+
const reverseFrames = showTranslation && showReverse ? [-1, -2, -3] : [];
|
|
93
|
+
// if region.reversed, the forward translation is on bottom, reverse on top
|
|
94
|
+
const [topFrames, bottomFrames] = region.reversed
|
|
95
|
+
? [reverseFrames.toReversed(), forwardFrames.toReversed()]
|
|
96
|
+
: [forwardFrames, reverseFrames];
|
|
78
97
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
showReverse ? (react_1.default.createElement(DNA, { height: rowHeight, y: (currY += rowHeight), feature: feature, region: region, seq: region.reversed ? seq : (0, util_1.complement)(seq), bpPerPx: bpPerPx, theme: theme })) : null,
|
|
84
|
-
showTranslation && (region.reversed ? showForward : showReverse)
|
|
85
|
-
? [0, -1, -2].map(index => (react_1.default.createElement(Translation, { key: `rev-translation-${index}`, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, theme: theme, height: rowHeight, reverse: !region.reversed })))
|
|
86
|
-
: null));
|
|
98
|
+
topFrames.map(index => (react_1.default.createElement(Translation, { key: `translation-${index}`, colorByCDS: colorByCDS, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, seqStart: feature.get('start'), theme: theme, height: rowHeight, reverse: region.reversed }))),
|
|
99
|
+
showForward && showDNA ? (react_1.default.createElement(DNA, { height: rowHeight, y: (currY += rowHeight), feature: feature, region: region, seq: region.reversed ? (0, util_1.complement)(seq) : seq, bpPerPx: bpPerPx, theme: theme })) : null,
|
|
100
|
+
showReverse && showDNA ? (react_1.default.createElement(DNA, { height: rowHeight, y: (currY += rowHeight), feature: feature, region: region, seq: region.reversed ? seq : (0, util_1.complement)(seq), bpPerPx: bpPerPx, theme: theme })) : null,
|
|
101
|
+
bottomFrames.map(index => (react_1.default.createElement(Translation, { key: `rev-translation-${index}`, colorByCDS: colorByCDS, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, seqStart: feature.get('start'), theme: theme, height: rowHeight, reverse: !region.reversed })))));
|
|
87
102
|
}
|
|
88
103
|
function Wrapper({ exportSVG, width, totalHeight, children, }) {
|
|
89
|
-
return exportSVG ? (
|
|
104
|
+
return exportSVG ? (children) : (react_1.default.createElement("svg", { "data-testid": "sequence_track", width: width, height: totalHeight, style: {
|
|
105
|
+
// use block because svg by default is inline, which adds a margin
|
|
106
|
+
display: 'block',
|
|
90
107
|
width,
|
|
91
108
|
height: totalHeight,
|
|
92
109
|
userSelect: 'none',
|
|
93
|
-
// use block because svg by default is inline, which adds a margin
|
|
94
|
-
display: 'block',
|
|
95
110
|
} }, children));
|
|
96
111
|
}
|
|
97
112
|
const DivSequenceRendering = (0, mobx_react_1.observer)(function (props) {
|
|
@@ -70,24 +70,31 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
70
70
|
configuration: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
71
71
|
maxFeatureScreenDensity: {
|
|
72
72
|
type: string;
|
|
73
|
-
description: string;
|
|
73
|
+
description: string; /**
|
|
74
|
+
* #property
|
|
75
|
+
*/
|
|
74
76
|
defaultValue: number;
|
|
75
77
|
};
|
|
76
78
|
fetchSizeLimit: {
|
|
77
|
-
type: string;
|
|
79
|
+
type: string; /**
|
|
80
|
+
* #property
|
|
81
|
+
*/
|
|
78
82
|
defaultValue: number;
|
|
79
83
|
description: string;
|
|
80
84
|
};
|
|
81
85
|
height: {
|
|
82
86
|
type: string;
|
|
83
|
-
defaultValue: number;
|
|
84
|
-
description: string; /**
|
|
87
|
+
defaultValue: number; /**
|
|
85
88
|
* #property
|
|
86
89
|
*/
|
|
90
|
+
description: string;
|
|
87
91
|
};
|
|
88
92
|
mouseover: {
|
|
89
93
|
type: string;
|
|
90
94
|
description: string;
|
|
95
|
+
/**
|
|
96
|
+
* #getter
|
|
97
|
+
*/
|
|
91
98
|
defaultValue: string;
|
|
92
99
|
contextVariable: string[];
|
|
93
100
|
};
|
|
@@ -107,13 +114,15 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
107
114
|
model: {
|
|
108
115
|
id: string;
|
|
109
116
|
type: string;
|
|
110
|
-
rpcDriverName: string | undefined;
|
|
111
|
-
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
112
|
-
rendererTypeName: string; /**
|
|
117
|
+
rpcDriverName: string | undefined; /**
|
|
113
118
|
* #property
|
|
114
119
|
*/
|
|
120
|
+
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
121
|
+
rendererTypeName: string;
|
|
115
122
|
error: unknown;
|
|
116
|
-
message: string | undefined;
|
|
123
|
+
message: string | undefined; /**
|
|
124
|
+
* #property
|
|
125
|
+
*/
|
|
117
126
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
118
127
|
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
119
128
|
type: import("mobx-state-tree").ISimpleType<string>;
|
|
@@ -161,13 +170,15 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
161
170
|
} & {
|
|
162
171
|
scrollTop: number;
|
|
163
172
|
} & {
|
|
164
|
-
readonly height: number;
|
|
165
|
-
} & {
|
|
166
|
-
setScrollTop(scrollTop: number): void; /**
|
|
173
|
+
readonly height: number; /**
|
|
167
174
|
* #property
|
|
168
175
|
*/
|
|
176
|
+
} & {
|
|
177
|
+
setScrollTop(scrollTop: number): void;
|
|
169
178
|
setHeight(displayHeight: number): number;
|
|
170
|
-
resizeHeight(distance: number): number;
|
|
179
|
+
resizeHeight(distance: number): number; /**
|
|
180
|
+
* #getter
|
|
181
|
+
*/
|
|
171
182
|
} & {
|
|
172
183
|
featureDensityStatsP: Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats> | undefined;
|
|
173
184
|
featureDensityStats: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined;
|
|
@@ -175,13 +186,13 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
175
186
|
} & {
|
|
176
187
|
readonly currentBytesRequested: number;
|
|
177
188
|
readonly currentFeatureScreenDensity: number;
|
|
178
|
-
readonly maxFeatureScreenDensity: any;
|
|
189
|
+
readonly maxFeatureScreenDensity: any; /**
|
|
190
|
+
* #method
|
|
191
|
+
*/
|
|
179
192
|
readonly featureDensityStatsReady: boolean;
|
|
180
193
|
readonly maxAllowableBytes: number;
|
|
181
194
|
} & {
|
|
182
|
-
afterAttach(): void;
|
|
183
|
-
* #getter
|
|
184
|
-
*/
|
|
195
|
+
afterAttach(): void;
|
|
185
196
|
} & {
|
|
186
197
|
setCurrStatsBpPerPx(n: number): void;
|
|
187
198
|
setFeatureDensityStatsLimit(stats?: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined): void;
|
|
@@ -344,24 +355,31 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
344
355
|
configuration: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
345
356
|
maxFeatureScreenDensity: {
|
|
346
357
|
type: string;
|
|
347
|
-
description: string;
|
|
358
|
+
description: string; /**
|
|
359
|
+
* #property
|
|
360
|
+
*/
|
|
348
361
|
defaultValue: number;
|
|
349
362
|
};
|
|
350
363
|
fetchSizeLimit: {
|
|
351
|
-
type: string;
|
|
364
|
+
type: string; /**
|
|
365
|
+
* #property
|
|
366
|
+
*/
|
|
352
367
|
defaultValue: number;
|
|
353
368
|
description: string;
|
|
354
369
|
};
|
|
355
370
|
height: {
|
|
356
371
|
type: string;
|
|
357
|
-
defaultValue: number;
|
|
358
|
-
description: string; /**
|
|
372
|
+
defaultValue: number; /**
|
|
359
373
|
* #property
|
|
360
374
|
*/
|
|
375
|
+
description: string;
|
|
361
376
|
};
|
|
362
377
|
mouseover: {
|
|
363
378
|
type: string;
|
|
364
379
|
description: string;
|
|
380
|
+
/**
|
|
381
|
+
* #getter
|
|
382
|
+
*/
|
|
365
383
|
defaultValue: string;
|
|
366
384
|
contextVariable: string[];
|
|
367
385
|
};
|
|
@@ -4,6 +4,7 @@ exports.modelFactory = void 0;
|
|
|
4
4
|
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
5
5
|
const plugin_linear_genome_view_1 = require("@jbrowse/plugin-linear-genome-view");
|
|
6
6
|
const configuration_1 = require("@jbrowse/core/configuration");
|
|
7
|
+
const tracks_1 = require("@jbrowse/core/util/tracks");
|
|
7
8
|
const util_1 = require("@jbrowse/core/util");
|
|
8
9
|
const mobx_1 = require("mobx");
|
|
9
10
|
/**
|
|
@@ -64,6 +65,7 @@ function modelFactory(configSchema) {
|
|
|
64
65
|
const { showForward, rpcDriverName, showReverse, showTranslation, rowHeight, sequenceHeight, } = self;
|
|
65
66
|
return {
|
|
66
67
|
...superRenderProps(),
|
|
68
|
+
...(0, tracks_1.getParentRenderProps)(self),
|
|
67
69
|
config: self.configuration.renderer,
|
|
68
70
|
rpcDriverName,
|
|
69
71
|
showForward,
|
|
@@ -81,7 +83,7 @@ function modelFactory(configSchema) {
|
|
|
81
83
|
*/
|
|
82
84
|
regionCannotBeRendered( /* region */) {
|
|
83
85
|
const view = (0, util_1.getContainingView)(self);
|
|
84
|
-
return (view === null || view === void 0 ? void 0 : view.bpPerPx)
|
|
86
|
+
return (view === null || view === void 0 ? void 0 : view.bpPerPx) > 3 ? 'Zoom in to see sequence' : undefined;
|
|
85
87
|
},
|
|
86
88
|
/**
|
|
87
89
|
* #getter
|
|
@@ -112,7 +114,7 @@ function modelFactory(configSchema) {
|
|
|
112
114
|
afterAttach() {
|
|
113
115
|
(0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
|
|
114
116
|
const view = (0, util_1.getContainingView)(self);
|
|
115
|
-
if ((view === null || view === void 0 ? void 0 : view.bpPerPx)
|
|
117
|
+
if ((view === null || view === void 0 ? void 0 : view.bpPerPx) > 3) {
|
|
116
118
|
self.setHeight(50);
|
|
117
119
|
}
|
|
118
120
|
else {
|
|
@@ -2,42 +2,54 @@ import React from 'react';
|
|
|
2
2
|
import { createJBrowseTheme } from '@jbrowse/core/ui';
|
|
3
3
|
import { observer } from 'mobx-react';
|
|
4
4
|
import { bpSpanPx, revcom, complement, defaultStarts, defaultStops, defaultCodonTable, generateCodonTable, } from '@jbrowse/core/util';
|
|
5
|
-
function Translation(
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// can otherwise result in effectiveFrame -1
|
|
14
|
-
const effectiveFrame = (frame + tilt + 3) % 3;
|
|
15
|
-
const seqSliced = seq.slice(effectiveFrame);
|
|
5
|
+
function Translation({ codonTable, seq, frame, bpPerPx, colorByCDS, region, seqStart, height, y, reverse = false, theme, }) {
|
|
6
|
+
var _a, _b;
|
|
7
|
+
const normalizedFrame = Math.abs(frame) - 1;
|
|
8
|
+
const seqFrame = seqStart % 3;
|
|
9
|
+
const frameShift = (normalizedFrame - seqFrame + 3) % 3;
|
|
10
|
+
const frameShiftAdjustedSeqLength = seq.length - frameShift;
|
|
11
|
+
const multipleOfThreeLength = frameShiftAdjustedSeqLength - (frameShiftAdjustedSeqLength % 3);
|
|
12
|
+
const seqSliced = seq.slice(frameShift, frameShift + multipleOfThreeLength);
|
|
16
13
|
const translated = [];
|
|
17
14
|
for (let i = 0; i < seqSliced.length; i += 3) {
|
|
18
15
|
const codon = seqSliced.slice(i, i + 3);
|
|
19
16
|
const normalizedCodon = reverse ? revcom(codon) : codon;
|
|
20
17
|
const aminoAcid = codonTable[normalizedCodon] || '';
|
|
21
|
-
translated.push({
|
|
18
|
+
translated.push({
|
|
19
|
+
letter: aminoAcid,
|
|
20
|
+
codon: normalizedCodon.toUpperCase(),
|
|
21
|
+
});
|
|
22
22
|
}
|
|
23
|
-
const w = (1 / scale) * 3;
|
|
24
|
-
const drop = region.start === 0 ? 0 : w;
|
|
25
|
-
const render = 1 / bpPerPx >= 12;
|
|
26
23
|
const width = (region.end - region.start) / bpPerPx;
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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 === null || theme === void 0 ? void 0 : theme.palette.framesCDS.at(frame)) === null || _a === void 0 ? void 0 : _a.main
|
|
31
|
+
: (_b = theme === null || theme === void 0 ? void 0 : theme.palette.frames.at(frame)) === null || _b === void 0 ? void 0 : _b.main;
|
|
32
|
+
return (React.createElement(React.Fragment, null,
|
|
33
|
+
React.createElement("rect", { x: 0, y: y, width: width, height: height, fill: defaultFill }),
|
|
34
|
+
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 === null || theme === void 0 ? void 0 : theme.palette.startCodon
|
|
41
|
+
: defaultStops.includes(codon)
|
|
42
|
+
? theme === null || theme === void 0 ? void 0 : theme.palette.stopCodon
|
|
43
|
+
: undefined;
|
|
44
|
+
if (!(renderLetter || codonFill)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
return (React.createElement(React.Fragment, { key: `${index}-${letter}` },
|
|
48
|
+
React.createElement("rect", { x: x, y: y, width: renderLetter
|
|
49
|
+
? codonWidth
|
|
50
|
+
: codonWidth + 0.7 /* small fudge factor when zoomed out*/, height: height, stroke: renderLetter ? '#555' : 'none', fill: codonFill || 'none' }),
|
|
51
|
+
renderLetter ? (React.createElement("text", { x: x + codonWidth / 2, fontSize: height - 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle" }, letter)) : null));
|
|
52
|
+
})));
|
|
41
53
|
}
|
|
42
54
|
function DNA(props) {
|
|
43
55
|
const { bpPerPx, region, feature, theme, height, seq, y } = props;
|
|
@@ -55,7 +67,7 @@ function DNA(props) {
|
|
|
55
67
|
render ? (React.createElement("text", { x: x + w / 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", fontSize: height - 2, fill: color ? theme.palette.getContrastText(color.main) : 'black' }, letter)) : null));
|
|
56
68
|
})));
|
|
57
69
|
}
|
|
58
|
-
function SequenceSVG({ regions, theme: configTheme, features = new Map(), showReverse = true, showForward = true, showTranslation = true, bpPerPx, rowHeight, }) {
|
|
70
|
+
function SequenceSVG({ regions, theme: configTheme, colorByCDS, features = new Map(), showReverse = true, showForward = true, showTranslation = true, bpPerPx, rowHeight, }) {
|
|
59
71
|
const [region] = regions;
|
|
60
72
|
const theme = createJBrowseTheme(configTheme);
|
|
61
73
|
const codonTable = generateCodonTable(defaultCodonTable);
|
|
@@ -70,23 +82,26 @@ function SequenceSVG({ regions, theme: configTheme, features = new Map(), showRe
|
|
|
70
82
|
// incrementer for the y-position of the current sequence being rendered
|
|
71
83
|
// (applies to both translation rows and dna rows)
|
|
72
84
|
let currY = -rowHeight;
|
|
85
|
+
const showDNA = bpPerPx <= 1;
|
|
86
|
+
const forwardFrames = showTranslation && showForward ? [3, 2, 1] : [];
|
|
87
|
+
const reverseFrames = showTranslation && showReverse ? [-1, -2, -3] : [];
|
|
88
|
+
// if region.reversed, the forward translation is on bottom, reverse on top
|
|
89
|
+
const [topFrames, bottomFrames] = region.reversed
|
|
90
|
+
? [reverseFrames.toReversed(), forwardFrames.toReversed()]
|
|
91
|
+
: [forwardFrames, reverseFrames];
|
|
73
92
|
return (React.createElement(React.Fragment, null,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
showReverse ? (React.createElement(DNA, { height: rowHeight, y: (currY += rowHeight), feature: feature, region: region, seq: region.reversed ? seq : complement(seq), bpPerPx: bpPerPx, theme: theme })) : null,
|
|
79
|
-
showTranslation && (region.reversed ? showForward : showReverse)
|
|
80
|
-
? [0, -1, -2].map(index => (React.createElement(Translation, { key: `rev-translation-${index}`, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, theme: theme, height: rowHeight, reverse: !region.reversed })))
|
|
81
|
-
: null));
|
|
93
|
+
topFrames.map(index => (React.createElement(Translation, { key: `translation-${index}`, colorByCDS: colorByCDS, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, seqStart: feature.get('start'), theme: theme, height: rowHeight, reverse: region.reversed }))),
|
|
94
|
+
showForward && showDNA ? (React.createElement(DNA, { height: rowHeight, y: (currY += rowHeight), feature: feature, region: region, seq: region.reversed ? complement(seq) : seq, bpPerPx: bpPerPx, theme: theme })) : null,
|
|
95
|
+
showReverse && showDNA ? (React.createElement(DNA, { height: rowHeight, y: (currY += rowHeight), feature: feature, region: region, seq: region.reversed ? seq : complement(seq), bpPerPx: bpPerPx, theme: theme })) : null,
|
|
96
|
+
bottomFrames.map(index => (React.createElement(Translation, { key: `rev-translation-${index}`, colorByCDS: colorByCDS, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, seqStart: feature.get('start'), theme: theme, height: rowHeight, reverse: !region.reversed })))));
|
|
82
97
|
}
|
|
83
98
|
function Wrapper({ exportSVG, width, totalHeight, children, }) {
|
|
84
|
-
return exportSVG ? (
|
|
99
|
+
return exportSVG ? (children) : (React.createElement("svg", { "data-testid": "sequence_track", width: width, height: totalHeight, style: {
|
|
100
|
+
// use block because svg by default is inline, which adds a margin
|
|
101
|
+
display: 'block',
|
|
85
102
|
width,
|
|
86
103
|
height: totalHeight,
|
|
87
104
|
userSelect: 'none',
|
|
88
|
-
// use block because svg by default is inline, which adds a margin
|
|
89
|
-
display: 'block',
|
|
90
105
|
} }, children));
|
|
91
106
|
}
|
|
92
107
|
const DivSequenceRendering = observer(function (props) {
|
|
@@ -70,24 +70,31 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
70
70
|
configuration: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
71
71
|
maxFeatureScreenDensity: {
|
|
72
72
|
type: string;
|
|
73
|
-
description: string;
|
|
73
|
+
description: string; /**
|
|
74
|
+
* #property
|
|
75
|
+
*/
|
|
74
76
|
defaultValue: number;
|
|
75
77
|
};
|
|
76
78
|
fetchSizeLimit: {
|
|
77
|
-
type: string;
|
|
79
|
+
type: string; /**
|
|
80
|
+
* #property
|
|
81
|
+
*/
|
|
78
82
|
defaultValue: number;
|
|
79
83
|
description: string;
|
|
80
84
|
};
|
|
81
85
|
height: {
|
|
82
86
|
type: string;
|
|
83
|
-
defaultValue: number;
|
|
84
|
-
description: string; /**
|
|
87
|
+
defaultValue: number; /**
|
|
85
88
|
* #property
|
|
86
89
|
*/
|
|
90
|
+
description: string;
|
|
87
91
|
};
|
|
88
92
|
mouseover: {
|
|
89
93
|
type: string;
|
|
90
94
|
description: string;
|
|
95
|
+
/**
|
|
96
|
+
* #getter
|
|
97
|
+
*/
|
|
91
98
|
defaultValue: string;
|
|
92
99
|
contextVariable: string[];
|
|
93
100
|
};
|
|
@@ -107,13 +114,15 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
107
114
|
model: {
|
|
108
115
|
id: string;
|
|
109
116
|
type: string;
|
|
110
|
-
rpcDriverName: string | undefined;
|
|
111
|
-
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
112
|
-
rendererTypeName: string; /**
|
|
117
|
+
rpcDriverName: string | undefined; /**
|
|
113
118
|
* #property
|
|
114
119
|
*/
|
|
120
|
+
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
121
|
+
rendererTypeName: string;
|
|
115
122
|
error: unknown;
|
|
116
|
-
message: string | undefined;
|
|
123
|
+
message: string | undefined; /**
|
|
124
|
+
* #property
|
|
125
|
+
*/
|
|
117
126
|
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
118
127
|
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
119
128
|
type: import("mobx-state-tree").ISimpleType<string>;
|
|
@@ -161,13 +170,15 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
161
170
|
} & {
|
|
162
171
|
scrollTop: number;
|
|
163
172
|
} & {
|
|
164
|
-
readonly height: number;
|
|
165
|
-
} & {
|
|
166
|
-
setScrollTop(scrollTop: number): void; /**
|
|
173
|
+
readonly height: number; /**
|
|
167
174
|
* #property
|
|
168
175
|
*/
|
|
176
|
+
} & {
|
|
177
|
+
setScrollTop(scrollTop: number): void;
|
|
169
178
|
setHeight(displayHeight: number): number;
|
|
170
|
-
resizeHeight(distance: number): number;
|
|
179
|
+
resizeHeight(distance: number): number; /**
|
|
180
|
+
* #getter
|
|
181
|
+
*/
|
|
171
182
|
} & {
|
|
172
183
|
featureDensityStatsP: Promise<import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats> | undefined;
|
|
173
184
|
featureDensityStats: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined;
|
|
@@ -175,13 +186,13 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
175
186
|
} & {
|
|
176
187
|
readonly currentBytesRequested: number;
|
|
177
188
|
readonly currentFeatureScreenDensity: number;
|
|
178
|
-
readonly maxFeatureScreenDensity: any;
|
|
189
|
+
readonly maxFeatureScreenDensity: any; /**
|
|
190
|
+
* #method
|
|
191
|
+
*/
|
|
179
192
|
readonly featureDensityStatsReady: boolean;
|
|
180
193
|
readonly maxAllowableBytes: number;
|
|
181
194
|
} & {
|
|
182
|
-
afterAttach(): void;
|
|
183
|
-
* #getter
|
|
184
|
-
*/
|
|
195
|
+
afterAttach(): void;
|
|
185
196
|
} & {
|
|
186
197
|
setCurrStatsBpPerPx(n: number): void;
|
|
187
198
|
setFeatureDensityStatsLimit(stats?: import("@jbrowse/core/data_adapters/BaseAdapter").FeatureDensityStats | undefined): void;
|
|
@@ -344,24 +355,31 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
344
355
|
configuration: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
345
356
|
maxFeatureScreenDensity: {
|
|
346
357
|
type: string;
|
|
347
|
-
description: string;
|
|
358
|
+
description: string; /**
|
|
359
|
+
* #property
|
|
360
|
+
*/
|
|
348
361
|
defaultValue: number;
|
|
349
362
|
};
|
|
350
363
|
fetchSizeLimit: {
|
|
351
|
-
type: string;
|
|
364
|
+
type: string; /**
|
|
365
|
+
* #property
|
|
366
|
+
*/
|
|
352
367
|
defaultValue: number;
|
|
353
368
|
description: string;
|
|
354
369
|
};
|
|
355
370
|
height: {
|
|
356
371
|
type: string;
|
|
357
|
-
defaultValue: number;
|
|
358
|
-
description: string; /**
|
|
372
|
+
defaultValue: number; /**
|
|
359
373
|
* #property
|
|
360
374
|
*/
|
|
375
|
+
description: string;
|
|
361
376
|
};
|
|
362
377
|
mouseover: {
|
|
363
378
|
type: string;
|
|
364
379
|
description: string;
|
|
380
|
+
/**
|
|
381
|
+
* #getter
|
|
382
|
+
*/
|
|
365
383
|
defaultValue: string;
|
|
366
384
|
contextVariable: string[];
|
|
367
385
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { addDisposer, types } from 'mobx-state-tree';
|
|
2
2
|
import { BaseLinearDisplay, } from '@jbrowse/plugin-linear-genome-view';
|
|
3
3
|
import { ConfigurationReference, } from '@jbrowse/core/configuration';
|
|
4
|
+
import { getParentRenderProps } from '@jbrowse/core/util/tracks';
|
|
4
5
|
import { getContainingView } from '@jbrowse/core/util';
|
|
5
6
|
import { autorun } from 'mobx';
|
|
6
7
|
/**
|
|
@@ -61,6 +62,7 @@ export function modelFactory(configSchema) {
|
|
|
61
62
|
const { showForward, rpcDriverName, showReverse, showTranslation, rowHeight, sequenceHeight, } = self;
|
|
62
63
|
return {
|
|
63
64
|
...superRenderProps(),
|
|
65
|
+
...getParentRenderProps(self),
|
|
64
66
|
config: self.configuration.renderer,
|
|
65
67
|
rpcDriverName,
|
|
66
68
|
showForward,
|
|
@@ -78,7 +80,7 @@ export function modelFactory(configSchema) {
|
|
|
78
80
|
*/
|
|
79
81
|
regionCannotBeRendered( /* region */) {
|
|
80
82
|
const view = getContainingView(self);
|
|
81
|
-
return (view === null || view === void 0 ? void 0 : view.bpPerPx)
|
|
83
|
+
return (view === null || view === void 0 ? void 0 : view.bpPerPx) > 3 ? 'Zoom in to see sequence' : undefined;
|
|
82
84
|
},
|
|
83
85
|
/**
|
|
84
86
|
* #getter
|
|
@@ -109,7 +111,7 @@ export function modelFactory(configSchema) {
|
|
|
109
111
|
afterAttach() {
|
|
110
112
|
addDisposer(self, autorun(() => {
|
|
111
113
|
const view = getContainingView(self);
|
|
112
|
-
if ((view === null || view === void 0 ? void 0 : view.bpPerPx)
|
|
114
|
+
if ((view === null || view === void 0 ? void 0 : view.bpPerPx) > 3) {
|
|
113
115
|
self.setHeight(50);
|
|
114
116
|
}
|
|
115
117
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-sequence",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.0",
|
|
4
4
|
"description": "JBrowse 2 sequence adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -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": "3d43a820b9274a6160aa4dc15616147f390d9094"
|
|
61
61
|
}
|