@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.
@@ -8,6 +8,7 @@ declare const DivSequenceRendering: (props: {
8
8
  };
9
9
  features: Map<string, Feature>;
10
10
  regions: Region[];
11
+ colorByCDS: boolean;
11
12
  bpPerPx: number;
12
13
  rowHeight: number;
13
14
  sequenceHeight: number;
@@ -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(props) {
11
- const { codonTable, seq, frame, bpPerPx, region, height, y, reverse = false, theme, } = props;
12
- const scale = bpPerPx;
13
- // the tilt variable normalizes the frame to where we are starting from,
14
- // which increases consistency across blocks
15
- const tilt = 3 - (region.start % 3);
16
- // the effectiveFrame incorporates tilt and the frame to say what the
17
- // effective frame that is plotted. The +3 is for when frame is -2 and this
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({ letter: aminoAcid, codon: normalizedCodon.toUpperCase() });
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 map = ['#d8d8d8', '#adadad', '#8f8f8f'].reverse();
33
- return (react_1.default.createElement(react_1.default.Fragment, null, translated.map((element, index) => {
34
- const x = region.reversed
35
- ? width - (w * (index + 1) + effectiveFrame / scale - drop)
36
- : w * index + effectiveFrame / scale - drop;
37
- const { letter, codon } = element;
38
- return (react_1.default.createElement(react_1.default.Fragment, { key: `${index}-${letter}` },
39
- react_1.default.createElement("rect", { x: x, y: y, width: render ? w : w + 0.7 /* small fudge factor when zoomed out*/, height: height, stroke: render ? '#555' : 'none', fill: util_1.defaultStarts.includes(codon)
40
- ? theme === null || theme === void 0 ? void 0 : theme.palette.startCodon
41
- : util_1.defaultStops.includes(codon)
42
- ? theme === null || theme === void 0 ? void 0 : theme.palette.stopCodon
43
- : map[Math.abs(frame)] }),
44
- render ? (react_1.default.createElement("text", { x: x + w / 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", fontSize: height - 2 }, letter)) : null));
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
- showTranslation && (region.reversed ? showReverse : showForward)
80
- ? [2, 1, 0].map(index => (react_1.default.createElement(Translation, { key: `translation-${index}`, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, theme: theme, height: rowHeight, reverse: region.reversed })))
81
- : null,
82
- showForward ? (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,
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 ? (react_1.default.createElement(react_1.default.Fragment, null, children)) : (react_1.default.createElement("svg", { "data-testid": "sequence_track", width: width, height: totalHeight, style: {
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) >= 1 ? 'Zoom in to see sequence' : undefined;
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) >= 1) {
117
+ if ((view === null || view === void 0 ? void 0 : view.bpPerPx) > 3) {
116
118
  self.setHeight(50);
117
119
  }
118
120
  else {
@@ -8,6 +8,7 @@ declare const DivSequenceRendering: (props: {
8
8
  };
9
9
  features: Map<string, Feature>;
10
10
  regions: Region[];
11
+ colorByCDS: boolean;
11
12
  bpPerPx: number;
12
13
  rowHeight: number;
13
14
  sequenceHeight: number;
@@ -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(props) {
6
- const { codonTable, seq, frame, bpPerPx, region, height, y, reverse = false, theme, } = props;
7
- const scale = bpPerPx;
8
- // the tilt variable normalizes the frame to where we are starting from,
9
- // which increases consistency across blocks
10
- const tilt = 3 - (region.start % 3);
11
- // the effectiveFrame incorporates tilt and the frame to say what the
12
- // effective frame that is plotted. The +3 is for when frame is -2 and this
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({ letter: aminoAcid, codon: normalizedCodon.toUpperCase() });
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 map = ['#d8d8d8', '#adadad', '#8f8f8f'].reverse();
28
- return (React.createElement(React.Fragment, null, translated.map((element, index) => {
29
- const x = region.reversed
30
- ? width - (w * (index + 1) + effectiveFrame / scale - drop)
31
- : w * index + effectiveFrame / scale - drop;
32
- const { letter, codon } = element;
33
- return (React.createElement(React.Fragment, { key: `${index}-${letter}` },
34
- React.createElement("rect", { x: x, y: y, width: render ? w : w + 0.7 /* small fudge factor when zoomed out*/, height: height, stroke: render ? '#555' : 'none', fill: defaultStarts.includes(codon)
35
- ? theme === null || theme === void 0 ? void 0 : theme.palette.startCodon
36
- : defaultStops.includes(codon)
37
- ? theme === null || theme === void 0 ? void 0 : theme.palette.stopCodon
38
- : map[Math.abs(frame)] }),
39
- render ? (React.createElement("text", { x: x + w / 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", fontSize: height - 2 }, letter)) : null));
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
- showTranslation && (region.reversed ? showReverse : showForward)
75
- ? [2, 1, 0].map(index => (React.createElement(Translation, { key: `translation-${index}`, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, theme: theme, height: rowHeight, reverse: region.reversed })))
76
- : null,
77
- showForward ? (React.createElement(DNA, { height: rowHeight, y: (currY += rowHeight), feature: feature, region: region, seq: region.reversed ? complement(seq) : seq, bpPerPx: bpPerPx, theme: theme })) : null,
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 ? (React.createElement(React.Fragment, null, children)) : (React.createElement("svg", { "data-testid": "sequence_track", width: width, height: totalHeight, style: {
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) >= 1 ? 'Zoom in to see sequence' : undefined;
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) >= 1) {
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.10.3",
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": "c8fc800cd17decd72b2e971c7a6add3b95214e72"
60
+ "gitHead": "3d43a820b9274a6160aa4dc15616147f390d9094"
61
61
  }