@jbrowse/plugin-alignments 3.0.4 → 3.1.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/BamAdapter/configSchema.js +24 -2
- package/dist/CramAdapter/configSchema.js +18 -1
- package/dist/LinearPileupDisplay/doAfterAttach.js +3 -1
- package/dist/PileupRenderer/makeImageData.js +7 -7
- package/dist/PileupRenderer/renderAlignment.d.ts +3 -3
- package/dist/PileupRenderer/renderAlignment.js +3 -3
- package/dist/PileupRenderer/renderMismatches.d.ts +3 -3
- package/dist/PileupRenderer/renderMismatches.js +11 -11
- package/dist/PileupRenderer/renderPerBaseLettering.d.ts +3 -3
- package/dist/PileupRenderer/renderPerBaseLettering.js +3 -3
- package/dist/PileupRenderer/renderSoftClipping.d.ts +2 -2
- package/dist/PileupRenderer/renderSoftClipping.js +2 -2
- package/dist/PileupRenderer/util.d.ts +4 -0
- package/dist/PileupRenderer/util.js +6 -2
- package/dist/SNPCoverageRenderer/makeImage.js +11 -11
- package/dist/shared/getUniqueModifications.d.ts +1 -1
- package/dist/shared/getUniqueModifications.js +4 -1
- package/dist/shared/util.js +1 -1
- package/esm/BamAdapter/configSchema.js +24 -2
- package/esm/CramAdapter/configSchema.js +18 -1
- package/esm/LinearPileupDisplay/doAfterAttach.js +3 -1
- package/esm/PileupRenderer/makeImageData.js +7 -7
- package/esm/PileupRenderer/renderAlignment.d.ts +3 -3
- package/esm/PileupRenderer/renderAlignment.js +3 -3
- package/esm/PileupRenderer/renderMismatches.d.ts +3 -3
- package/esm/PileupRenderer/renderMismatches.js +11 -11
- package/esm/PileupRenderer/renderPerBaseLettering.d.ts +3 -3
- package/esm/PileupRenderer/renderPerBaseLettering.js +3 -3
- package/esm/PileupRenderer/renderSoftClipping.d.ts +2 -2
- package/esm/PileupRenderer/renderSoftClipping.js +2 -2
- package/esm/PileupRenderer/util.d.ts +4 -0
- package/esm/PileupRenderer/util.js +6 -2
- package/esm/SNPCoverageRenderer/makeImage.js +11 -11
- package/esm/shared/getUniqueModifications.d.ts +1 -1
- package/esm/shared/getUniqueModifications.js +4 -1
- package/esm/shared/util.js +1 -1
- package/package.json +6 -6
|
@@ -6,7 +6,10 @@ function x() { }
|
|
|
6
6
|
const configSchema = (0, configuration_1.ConfigurationSchema)('BamAdapter', {
|
|
7
7
|
bamLocation: {
|
|
8
8
|
type: 'fileLocation',
|
|
9
|
-
defaultValue: {
|
|
9
|
+
defaultValue: {
|
|
10
|
+
uri: '/path/to/my.bam',
|
|
11
|
+
locationType: 'UriLocation',
|
|
12
|
+
},
|
|
10
13
|
},
|
|
11
14
|
index: (0, configuration_1.ConfigurationSchema)('BamIndex', {
|
|
12
15
|
indexType: {
|
|
@@ -32,5 +35,24 @@ const configSchema = (0, configuration_1.ConfigurationSchema)('BamAdapter', {
|
|
|
32
35
|
description: 'sequence data adapter, used to calculate SNPs when BAM reads lacking MD tags',
|
|
33
36
|
defaultValue: null,
|
|
34
37
|
},
|
|
35
|
-
}, {
|
|
38
|
+
}, {
|
|
39
|
+
explicitlyTyped: true,
|
|
40
|
+
preProcessSnapshot: snap => {
|
|
41
|
+
return snap.uri
|
|
42
|
+
? {
|
|
43
|
+
...snap,
|
|
44
|
+
bamLocation: {
|
|
45
|
+
uri: snap.uri,
|
|
46
|
+
baseUri: snap.baseUri,
|
|
47
|
+
},
|
|
48
|
+
index: {
|
|
49
|
+
location: {
|
|
50
|
+
uri: `${snap.uri}.bai`,
|
|
51
|
+
baseUri: snap.baseUri,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
: snap;
|
|
56
|
+
},
|
|
57
|
+
});
|
|
36
58
|
exports.default = configSchema;
|
|
@@ -27,5 +27,22 @@ const configSchema = (0, configuration_1.ConfigurationSchema)('CramAdapter', {
|
|
|
27
27
|
description: 'sequence data adapter',
|
|
28
28
|
defaultValue: null,
|
|
29
29
|
},
|
|
30
|
-
}, {
|
|
30
|
+
}, {
|
|
31
|
+
explicitlyTyped: true,
|
|
32
|
+
preProcessSnapshot: snap => {
|
|
33
|
+
return snap.uri
|
|
34
|
+
? {
|
|
35
|
+
...snap,
|
|
36
|
+
cramLocation: {
|
|
37
|
+
uri: snap.uri,
|
|
38
|
+
baseUri: snap.baseUri,
|
|
39
|
+
},
|
|
40
|
+
craiLocation: {
|
|
41
|
+
uri: `${snap.uri}.crai`,
|
|
42
|
+
baseUri: snap.baseUri,
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
: snap;
|
|
46
|
+
},
|
|
47
|
+
});
|
|
31
48
|
exports.default = configSchema;
|
|
@@ -40,7 +40,9 @@ function doAfterAttach(model) {
|
|
|
40
40
|
layoutId: (0, util_1.getContainingTrack)(model).id,
|
|
41
41
|
timeout: 1000000,
|
|
42
42
|
statusCallback: (arg) => {
|
|
43
|
-
|
|
43
|
+
if ((0, mobx_state_tree_1.isAlive)(model)) {
|
|
44
|
+
model.setMessage(arg);
|
|
45
|
+
}
|
|
44
46
|
},
|
|
45
47
|
...model.renderPropsPre(),
|
|
46
48
|
});
|
|
@@ -16,8 +16,8 @@ function makeImageData({ ctx, layoutRecords, canvasWidth, renderArgs, }) {
|
|
|
16
16
|
const hideSmallIndels = (0, configuration_1.readConfObject)(config, 'hideSmallIndels');
|
|
17
17
|
const defaultColor = (0, configuration_1.readConfObject)(config, 'color') === '#f0f';
|
|
18
18
|
const theme = (0, ui_1.createJBrowseTheme)(configTheme);
|
|
19
|
-
const
|
|
20
|
-
const
|
|
19
|
+
const colorMap = (0, util_1.getColorBaseMap)(theme);
|
|
20
|
+
const colorContrastMap = (0, util_1.getContrastBaseMap)(theme);
|
|
21
21
|
ctx.font = 'bold 10px Courier New,monospace';
|
|
22
22
|
const { charWidth, charHeight } = (0, util_1.getCharWidthHeight)();
|
|
23
23
|
const drawSNPsMuted = (0, util_1.shouldDrawSNPsMuted)(colorBy === null || colorBy === void 0 ? void 0 : colorBy.type);
|
|
@@ -33,8 +33,8 @@ function makeImageData({ ctx, layoutRecords, canvasWidth, renderArgs, }) {
|
|
|
33
33
|
feat,
|
|
34
34
|
renderArgs,
|
|
35
35
|
defaultColor,
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
colorMap,
|
|
37
|
+
colorContrastMap,
|
|
38
38
|
charWidth,
|
|
39
39
|
charHeight,
|
|
40
40
|
canvasWidth,
|
|
@@ -51,8 +51,8 @@ function makeImageData({ ctx, layoutRecords, canvasWidth, renderArgs, }) {
|
|
|
51
51
|
minSubfeatureWidth,
|
|
52
52
|
charWidth,
|
|
53
53
|
charHeight,
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
colorMap,
|
|
55
|
+
colorContrastMap,
|
|
56
56
|
canvasWidth,
|
|
57
57
|
});
|
|
58
58
|
if (showSoftClip) {
|
|
@@ -60,7 +60,7 @@ function makeImageData({ ctx, layoutRecords, canvasWidth, renderArgs, }) {
|
|
|
60
60
|
ctx,
|
|
61
61
|
feat,
|
|
62
62
|
renderArgs,
|
|
63
|
-
|
|
63
|
+
colorMap,
|
|
64
64
|
config,
|
|
65
65
|
theme,
|
|
66
66
|
canvasWidth,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ProcessedRenderArgs } from './types';
|
|
2
2
|
import type { LayoutFeature } from './util';
|
|
3
|
-
export declare function renderAlignment({ ctx, feat, renderArgs,
|
|
3
|
+
export declare function renderAlignment({ ctx, feat, renderArgs, colorMap, colorContrastMap, charWidth, charHeight, defaultColor, canvasWidth, }: {
|
|
4
4
|
ctx: CanvasRenderingContext2D;
|
|
5
5
|
feat: LayoutFeature;
|
|
6
6
|
renderArgs: ProcessedRenderArgs;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
colorMap: Record<string, string>;
|
|
8
|
+
colorContrastMap: Record<string, string>;
|
|
9
9
|
charWidth: number;
|
|
10
10
|
charHeight: number;
|
|
11
11
|
defaultColor: boolean;
|
|
@@ -8,7 +8,7 @@ const renderPerBaseLettering_1 = require("./renderPerBaseLettering");
|
|
|
8
8
|
const renderPerBaseQuality_1 = require("./renderPerBaseQuality");
|
|
9
9
|
const MismatchParser_1 = require("../MismatchParser");
|
|
10
10
|
const renderMethylation_1 = require("./renderMethylation");
|
|
11
|
-
function renderAlignment({ ctx, feat, renderArgs,
|
|
11
|
+
function renderAlignment({ ctx, feat, renderArgs, colorMap, colorContrastMap, charWidth, charHeight, defaultColor, canvasWidth, }) {
|
|
12
12
|
const { config, bpPerPx, regions, colorBy, colorTagMap = {} } = renderArgs;
|
|
13
13
|
const { tag = '', type: colorType = '' } = colorBy || {};
|
|
14
14
|
const { feature } = feat;
|
|
@@ -42,8 +42,8 @@ function renderAlignment({ ctx, feat, renderArgs, colorForBase, contrastForBase,
|
|
|
42
42
|
feat,
|
|
43
43
|
region,
|
|
44
44
|
bpPerPx,
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
colorMap,
|
|
46
|
+
colorContrastMap,
|
|
47
47
|
charWidth,
|
|
48
48
|
charHeight,
|
|
49
49
|
canvasWidth,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ProcessedRenderArgs } from './types';
|
|
2
2
|
import type { LayoutFeature } from './util';
|
|
3
|
-
export declare function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInsertionIndicatorScale, mismatchAlpha, charWidth, charHeight,
|
|
3
|
+
export declare function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInsertionIndicatorScale, mismatchAlpha, charWidth, charHeight, colorMap, colorContrastMap, hideSmallIndels, canvasWidth, drawSNPsMuted, drawIndels, }: {
|
|
4
4
|
ctx: CanvasRenderingContext2D;
|
|
5
5
|
feat: LayoutFeature;
|
|
6
6
|
renderArgs: ProcessedRenderArgs;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
colorMap: Record<string, string>;
|
|
8
|
+
colorContrastMap: Record<string, string>;
|
|
9
9
|
mismatchAlpha?: boolean;
|
|
10
10
|
drawIndels?: boolean;
|
|
11
11
|
drawSNPsMuted?: boolean;
|
|
@@ -4,7 +4,7 @@ exports.renderMismatches = renderMismatches;
|
|
|
4
4
|
const util_1 = require("@jbrowse/core/util");
|
|
5
5
|
const colord_1 = require("@jbrowse/core/util/colord");
|
|
6
6
|
const util_2 = require("./util");
|
|
7
|
-
function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInsertionIndicatorScale, mismatchAlpha, charWidth, charHeight,
|
|
7
|
+
function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInsertionIndicatorScale, mismatchAlpha, charWidth, charHeight, colorMap, colorContrastMap, hideSmallIndels, canvasWidth, drawSNPsMuted, drawIndels = true, }) {
|
|
8
8
|
const { bpPerPx, regions } = renderArgs;
|
|
9
9
|
const { heightPx, topPx, feature } = feat;
|
|
10
10
|
const region = regions[0];
|
|
@@ -24,7 +24,7 @@ function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInse
|
|
|
24
24
|
const widthPx = Math.max(minSubfeatureWidth, rightPx - leftPx);
|
|
25
25
|
if (mismatch.type === 'mismatch') {
|
|
26
26
|
if (!drawSNPsMuted) {
|
|
27
|
-
const baseColor =
|
|
27
|
+
const baseColor = colorMap[mismatch.base] || '#888';
|
|
28
28
|
const c = mismatchAlpha && mismatch.qual !== undefined
|
|
29
29
|
? (0, colord_1.colord)(baseColor)
|
|
30
30
|
.alpha(Math.min(1, mismatch.qual / 50))
|
|
@@ -35,7 +35,7 @@ function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInse
|
|
|
35
35
|
if (widthPx >= charWidth && heightPx >= heightLim) {
|
|
36
36
|
const contrastColor = drawSNPsMuted
|
|
37
37
|
? 'black'
|
|
38
|
-
:
|
|
38
|
+
: colorContrastMap[mismatch.base] || 'black';
|
|
39
39
|
ctx.fillStyle =
|
|
40
40
|
mismatchAlpha && mismatch.qual !== undefined
|
|
41
41
|
? (0, colord_1.colord)(contrastColor)
|
|
@@ -48,11 +48,11 @@ function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInse
|
|
|
48
48
|
else if (mismatch.type === 'deletion' && drawIndels) {
|
|
49
49
|
const len = mismatch.length;
|
|
50
50
|
if (!hideSmallIndels || len >= 10) {
|
|
51
|
-
(0, util_2.fillRect)(ctx, leftPx, topPx, Math.abs(leftPx - rightPx), heightPx, canvasWidth,
|
|
51
|
+
(0, util_2.fillRect)(ctx, leftPx, topPx, Math.abs(leftPx - rightPx), heightPx, canvasWidth, colorMap.deletion);
|
|
52
52
|
const txt = `${mismatch.length}`;
|
|
53
53
|
const rwidth = (0, util_1.measureText)(txt, 10);
|
|
54
54
|
if (widthPx >= rwidth && heightPx >= heightLim) {
|
|
55
|
-
ctx.fillStyle =
|
|
55
|
+
ctx.fillStyle = colorContrastMap.deletion;
|
|
56
56
|
ctx.fillText(txt, (leftPx + rightPx) / 2 - rwidth / 2, topPx + heightPx);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -63,7 +63,7 @@ function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInse
|
|
|
63
63
|
const insW = Math.max(0, Math.min(1.2, 1 / bpPerPx));
|
|
64
64
|
if (len < 10) {
|
|
65
65
|
if (!hideSmallIndels) {
|
|
66
|
-
(0, util_2.fillRect)(ctx, pos, topPx, insW, heightPx, canvasWidth,
|
|
66
|
+
(0, util_2.fillRect)(ctx, pos, topPx, insW, heightPx, canvasWidth, colorMap.insertion);
|
|
67
67
|
if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
|
|
68
68
|
const l = Math.round(pos - insW);
|
|
69
69
|
(0, util_2.fillRect)(ctx, l, topPx, insW * 3, 1, canvasWidth);
|
|
@@ -75,7 +75,7 @@ function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInse
|
|
|
75
75
|
}
|
|
76
76
|
else if (mismatch.type === 'hardclip' || mismatch.type === 'softclip') {
|
|
77
77
|
const pos = leftPx + extraHorizontallyFlippedOffset;
|
|
78
|
-
const c = mismatch.type
|
|
78
|
+
const c = colorMap[mismatch.type];
|
|
79
79
|
const clipW = Math.max(minSubfeatureWidth, pxPerBp);
|
|
80
80
|
(0, util_2.fillRect)(ctx, pos, topPx, clipW, heightPx, canvasWidth, c);
|
|
81
81
|
if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
|
|
@@ -92,7 +92,7 @@ function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInse
|
|
|
92
92
|
const t = topPx + heightPx / 2 - 1;
|
|
93
93
|
const w = adjustPx + Math.min(leftPx, 0);
|
|
94
94
|
const h = 1;
|
|
95
|
-
(0, util_2.fillRect)(ctx, l, t, w, h, canvasWidth,
|
|
95
|
+
(0, util_2.fillRect)(ctx, l, t, w, h, canvasWidth, colorMap.skip);
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -105,18 +105,18 @@ function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInse
|
|
|
105
105
|
const [leftPx] = (0, util_1.bpSpanPx)(mstart, mstart + mlen, region, bpPerPx);
|
|
106
106
|
const txt = `${len}`;
|
|
107
107
|
if (bpPerPx > largeInsertionIndicatorScale) {
|
|
108
|
-
(0, util_2.fillRect)(ctx, leftPx - 1, topPx, 2, heightPx, canvasWidth,
|
|
108
|
+
(0, util_2.fillRect)(ctx, leftPx - 1, topPx, 2, heightPx, canvasWidth, colorMap.insertion);
|
|
109
109
|
}
|
|
110
110
|
else if (heightPx > charHeight) {
|
|
111
111
|
const rwidth = (0, util_1.measureText)(txt);
|
|
112
112
|
const padding = 5;
|
|
113
113
|
(0, util_2.fillRect)(ctx, leftPx - rwidth / 2 - padding, topPx, rwidth + 2 * padding, heightPx, canvasWidth, 'purple');
|
|
114
|
-
ctx.fillStyle =
|
|
114
|
+
ctx.fillStyle = colorContrastMap.insertion;
|
|
115
115
|
ctx.fillText(txt, leftPx - rwidth / 2, topPx + heightPx);
|
|
116
116
|
}
|
|
117
117
|
else {
|
|
118
118
|
const padding = 2;
|
|
119
|
-
(0, util_2.fillRect)(ctx, leftPx - padding, topPx, 2 * padding, heightPx, canvasWidth,
|
|
119
|
+
(0, util_2.fillRect)(ctx, leftPx - padding, topPx, 2 * padding, heightPx, canvasWidth, colorMap.insertion);
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { LayoutFeature } from './util';
|
|
2
2
|
import type { Region } from '@jbrowse/core/util';
|
|
3
|
-
export declare function renderPerBaseLettering({ ctx, feat, region, bpPerPx,
|
|
3
|
+
export declare function renderPerBaseLettering({ ctx, feat, region, bpPerPx, colorMap, colorContrastMap, charWidth, charHeight, canvasWidth, cigarOps, }: {
|
|
4
4
|
ctx: CanvasRenderingContext2D;
|
|
5
5
|
feat: LayoutFeature;
|
|
6
6
|
region: Region;
|
|
7
7
|
bpPerPx: number;
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
colorMap: Record<string, string>;
|
|
9
|
+
colorContrastMap: Record<string, string>;
|
|
10
10
|
charWidth: number;
|
|
11
11
|
charHeight: number;
|
|
12
12
|
canvasWidth: number;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.renderPerBaseLettering = renderPerBaseLettering;
|
|
4
4
|
const util_1 = require("@jbrowse/core/util");
|
|
5
5
|
const util_2 = require("./util");
|
|
6
|
-
function renderPerBaseLettering({ ctx, feat, region, bpPerPx,
|
|
6
|
+
function renderPerBaseLettering({ ctx, feat, region, bpPerPx, colorMap, colorContrastMap, charWidth, charHeight, canvasWidth, cigarOps, }) {
|
|
7
7
|
const heightLim = charHeight - 2;
|
|
8
8
|
const { feature, topPx, heightPx } = feat;
|
|
9
9
|
const seq = feature.get('seq');
|
|
@@ -28,10 +28,10 @@ function renderPerBaseLettering({ ctx, feat, region, bpPerPx, colorForBase, cont
|
|
|
28
28
|
const letter = seq[soffset + m];
|
|
29
29
|
const r = start + roffset + m;
|
|
30
30
|
const [leftPx] = (0, util_1.bpSpanPx)(r, r + 1, region, bpPerPx);
|
|
31
|
-
const c =
|
|
31
|
+
const c = colorMap[letter];
|
|
32
32
|
(0, util_2.fillRect)(ctx, leftPx, topPx, w + 0.5, heightPx, canvasWidth, c);
|
|
33
33
|
if (w >= charWidth && heightPx >= heightLim) {
|
|
34
|
-
ctx.fillStyle =
|
|
34
|
+
ctx.fillStyle = colorContrastMap[letter];
|
|
35
35
|
ctx.fillText(letter, leftPx + (w - charWidth) / 2 + 1, topPx + heightPx);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -2,12 +2,12 @@ import type { ProcessedRenderArgs } from './types';
|
|
|
2
2
|
import type { LayoutFeature } from './util';
|
|
3
3
|
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
4
4
|
import type { Theme } from '@mui/material';
|
|
5
|
-
export declare function renderSoftClipping({ ctx, feat, renderArgs, config, theme,
|
|
5
|
+
export declare function renderSoftClipping({ ctx, feat, renderArgs, config, theme, colorMap, canvasWidth, }: {
|
|
6
6
|
ctx: CanvasRenderingContext2D;
|
|
7
7
|
feat: LayoutFeature;
|
|
8
8
|
renderArgs: ProcessedRenderArgs;
|
|
9
9
|
config: AnyConfigurationModel;
|
|
10
|
-
|
|
10
|
+
colorMap: Record<string, string>;
|
|
11
11
|
theme: Theme;
|
|
12
12
|
canvasWidth: number;
|
|
13
13
|
}): void;
|
|
@@ -5,7 +5,7 @@ const configuration_1 = require("@jbrowse/core/configuration");
|
|
|
5
5
|
const util_1 = require("@jbrowse/core/util");
|
|
6
6
|
const util_2 = require("./util");
|
|
7
7
|
const MismatchParser_1 = require("../MismatchParser");
|
|
8
|
-
function renderSoftClipping({ ctx, feat, renderArgs, config, theme,
|
|
8
|
+
function renderSoftClipping({ ctx, feat, renderArgs, config, theme, colorMap, canvasWidth, }) {
|
|
9
9
|
const { feature, topPx, heightPx } = feat;
|
|
10
10
|
const { regions, bpPerPx } = renderArgs;
|
|
11
11
|
const region = regions[0];
|
|
@@ -30,7 +30,7 @@ function renderSoftClipping({ ctx, feat, renderArgs, config, theme, colorForBase
|
|
|
30
30
|
const s0 = feature.get('start') - (i === 0 ? len : 0) + refOffset + k;
|
|
31
31
|
const [leftPx, rightPx] = (0, util_1.bpSpanPx)(s0, s0 + 1, region, bpPerPx);
|
|
32
32
|
const widthPx = Math.max(minFeatWidth, rightPx - leftPx);
|
|
33
|
-
const baseColor =
|
|
33
|
+
const baseColor = colorMap[base] || '#000000';
|
|
34
34
|
ctx.fillStyle = baseColor;
|
|
35
35
|
(0, util_2.fillRect)(ctx, leftPx, topPx, widthPx, heightPx, canvasWidth);
|
|
36
36
|
if (widthPx >= charWidth && heightPx >= heightLim) {
|
|
@@ -7,6 +7,10 @@ export declare function getColorBaseMap(theme: Theme): {
|
|
|
7
7
|
G: string;
|
|
8
8
|
T: string;
|
|
9
9
|
deletion: string;
|
|
10
|
+
insertion: string;
|
|
11
|
+
hardclip: string;
|
|
12
|
+
softclip: string;
|
|
13
|
+
skip: string;
|
|
10
14
|
};
|
|
11
15
|
export declare function getContrastBaseMap(theme: Theme): {
|
|
12
16
|
[k: string]: string;
|
|
@@ -17,13 +17,17 @@ function fillRect(ctx, l, t, w, h, cw, color) {
|
|
|
17
17
|
ctx.fillRect(l, t, w, h);
|
|
18
18
|
}
|
|
19
19
|
function getColorBaseMap(theme) {
|
|
20
|
-
const { bases } = theme.palette;
|
|
20
|
+
const { skip, deletion, insertion, hardclip, softclip, bases } = theme.palette;
|
|
21
21
|
return {
|
|
22
22
|
A: bases.A.main,
|
|
23
23
|
C: bases.C.main,
|
|
24
24
|
G: bases.G.main,
|
|
25
25
|
T: bases.T.main,
|
|
26
|
-
deletion
|
|
26
|
+
deletion,
|
|
27
|
+
insertion,
|
|
28
|
+
hardclip,
|
|
29
|
+
softclip,
|
|
30
|
+
skip,
|
|
27
31
|
};
|
|
28
32
|
}
|
|
29
33
|
function getContrastBaseMap(theme) {
|
|
@@ -42,22 +42,22 @@ async function makeImage(ctx, props) {
|
|
|
42
42
|
const toHeight = (n) => toY(originY) - toY(n);
|
|
43
43
|
const toY2 = (n) => height - (indicatorViewScale(n) || 0) + offset;
|
|
44
44
|
const toHeight2 = (n) => toY2(originLinear) - toY2(n);
|
|
45
|
-
const { bases } = theme.palette;
|
|
46
|
-
const
|
|
45
|
+
const { bases, softclip, hardclip, insertion } = theme.palette;
|
|
46
|
+
const colorMap = {
|
|
47
47
|
A: bases.A.main,
|
|
48
48
|
C: bases.C.main,
|
|
49
49
|
G: bases.G.main,
|
|
50
50
|
T: bases.T.main,
|
|
51
|
-
insertion
|
|
52
|
-
softclip
|
|
53
|
-
hardclip
|
|
51
|
+
insertion,
|
|
52
|
+
softclip,
|
|
53
|
+
hardclip,
|
|
54
54
|
total: (0, configuration_1.readConfObject)(cfg, 'color'),
|
|
55
55
|
mod_NONE: 'blue',
|
|
56
56
|
cpg_meth: 'red',
|
|
57
57
|
cpg_unmeth: 'blue',
|
|
58
58
|
};
|
|
59
59
|
const feats = [...features.values()];
|
|
60
|
-
ctx.fillStyle =
|
|
60
|
+
ctx.fillStyle = colorMap.total;
|
|
61
61
|
let start = performance.now();
|
|
62
62
|
for (const feature of feats) {
|
|
63
63
|
if (feature.get('type') === 'skip') {
|
|
@@ -167,7 +167,7 @@ async function makeImage(ctx, props) {
|
|
|
167
167
|
const { entryDepth } = mods[base];
|
|
168
168
|
const height = toHeight(score0);
|
|
169
169
|
const bottom = toY(score0) + height;
|
|
170
|
-
ctx.fillStyle =
|
|
170
|
+
ctx.fillStyle = colorMap[base] || 'black';
|
|
171
171
|
ctx.fillRect(Math.round(leftPx), bottom - ((entryDepth + curr) / depth) * height, w, (entryDepth / depth) * height);
|
|
172
172
|
curr += entryDepth;
|
|
173
173
|
}
|
|
@@ -175,7 +175,7 @@ async function makeImage(ctx, props) {
|
|
|
175
175
|
const { entryDepth } = nonmods[base];
|
|
176
176
|
const height = toHeight(score0);
|
|
177
177
|
const bottom = toY(score0) + height;
|
|
178
|
-
ctx.fillStyle =
|
|
178
|
+
ctx.fillStyle = colorMap[base] || 'black';
|
|
179
179
|
ctx.fillRect(Math.round(leftPx), bottom - ((entryDepth + curr) / depth) * height, w, (entryDepth / depth) * height);
|
|
180
180
|
curr += entryDepth;
|
|
181
181
|
}
|
|
@@ -187,7 +187,7 @@ async function makeImage(ctx, props) {
|
|
|
187
187
|
const { entryDepth } = snps[base];
|
|
188
188
|
const height = toHeight(score0);
|
|
189
189
|
const bottom = toY(score0) + height;
|
|
190
|
-
ctx.fillStyle =
|
|
190
|
+
ctx.fillStyle = colorMap[base] || 'black';
|
|
191
191
|
ctx.fillRect(Math.round(leftPx), bottom - ((entryDepth + curr) / depth) * height, w, (entryDepth / depth) * height);
|
|
192
192
|
curr += entryDepth;
|
|
193
193
|
}
|
|
@@ -198,7 +198,7 @@ async function makeImage(ctx, props) {
|
|
|
198
198
|
for (const base of interbaseEvents) {
|
|
199
199
|
const { entryDepth } = snpinfo.noncov[base];
|
|
200
200
|
const r = 0.6;
|
|
201
|
-
ctx.fillStyle =
|
|
201
|
+
ctx.fillStyle = colorMap[base];
|
|
202
202
|
ctx.fillRect(leftPx - r + extraHorizontallyFlippedOffset, INTERBASE_INDICATOR_HEIGHT + toHeight2(curr), r * 2, toHeight2(entryDepth));
|
|
203
203
|
curr += entryDepth;
|
|
204
204
|
}
|
|
@@ -218,7 +218,7 @@ async function makeImage(ctx, props) {
|
|
|
218
218
|
const indicatorComparatorScore = Math.max(score0, prevTotal);
|
|
219
219
|
if (accum > indicatorComparatorScore * indicatorThreshold &&
|
|
220
220
|
indicatorComparatorScore > MINIMUM_INTERBASE_INDICATOR_READ_DEPTH) {
|
|
221
|
-
ctx.fillStyle =
|
|
221
|
+
ctx.fillStyle = colorMap[maxBase];
|
|
222
222
|
ctx.beginPath();
|
|
223
223
|
const l = leftPx + extraHorizontallyFlippedOffset;
|
|
224
224
|
ctx.moveTo(l - INTERBASE_INDICATOR_WIDTH / 2, 0);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { type IAnyStateTreeNode } from 'mobx-state-tree';
|
|
1
2
|
import type { ModificationType } from './types';
|
|
2
3
|
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
3
4
|
import type { BlockSet } from '@jbrowse/core/util/blockTypes';
|
|
4
|
-
import type { IAnyStateTreeNode } from 'mobx-state-tree';
|
|
5
5
|
export interface ModificationOpts {
|
|
6
6
|
headers?: Record<string, string>;
|
|
7
7
|
stopToken?: string;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getUniqueModifications = getUniqueModifications;
|
|
4
4
|
const util_1 = require("@jbrowse/core/util");
|
|
5
5
|
const tracks_1 = require("@jbrowse/core/util/tracks");
|
|
6
|
+
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
6
7
|
async function getUniqueModifications({ model, adapterConfig, blocks, opts, }) {
|
|
7
8
|
const { rpcManager } = (0, util_1.getSession)(model);
|
|
8
9
|
const sessionId = (0, tracks_1.getRpcSessionId)(model);
|
|
@@ -11,7 +12,9 @@ async function getUniqueModifications({ model, adapterConfig, blocks, opts, }) {
|
|
|
11
12
|
sessionId,
|
|
12
13
|
regions: blocks.contentBlocks,
|
|
13
14
|
statusCallback: (arg) => {
|
|
14
|
-
|
|
15
|
+
if ((0, mobx_state_tree_1.isAlive)(model)) {
|
|
16
|
+
model.setMessage(arg);
|
|
17
|
+
}
|
|
15
18
|
},
|
|
16
19
|
...opts,
|
|
17
20
|
});
|
package/dist/shared/util.js
CHANGED
|
@@ -4,7 +4,10 @@ function x() { }
|
|
|
4
4
|
const configSchema = ConfigurationSchema('BamAdapter', {
|
|
5
5
|
bamLocation: {
|
|
6
6
|
type: 'fileLocation',
|
|
7
|
-
defaultValue: {
|
|
7
|
+
defaultValue: {
|
|
8
|
+
uri: '/path/to/my.bam',
|
|
9
|
+
locationType: 'UriLocation',
|
|
10
|
+
},
|
|
8
11
|
},
|
|
9
12
|
index: ConfigurationSchema('BamIndex', {
|
|
10
13
|
indexType: {
|
|
@@ -30,5 +33,24 @@ const configSchema = ConfigurationSchema('BamAdapter', {
|
|
|
30
33
|
description: 'sequence data adapter, used to calculate SNPs when BAM reads lacking MD tags',
|
|
31
34
|
defaultValue: null,
|
|
32
35
|
},
|
|
33
|
-
}, {
|
|
36
|
+
}, {
|
|
37
|
+
explicitlyTyped: true,
|
|
38
|
+
preProcessSnapshot: snap => {
|
|
39
|
+
return snap.uri
|
|
40
|
+
? {
|
|
41
|
+
...snap,
|
|
42
|
+
bamLocation: {
|
|
43
|
+
uri: snap.uri,
|
|
44
|
+
baseUri: snap.baseUri,
|
|
45
|
+
},
|
|
46
|
+
index: {
|
|
47
|
+
location: {
|
|
48
|
+
uri: `${snap.uri}.bai`,
|
|
49
|
+
baseUri: snap.baseUri,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
: snap;
|
|
54
|
+
},
|
|
55
|
+
});
|
|
34
56
|
export default configSchema;
|
|
@@ -25,5 +25,22 @@ const configSchema = ConfigurationSchema('CramAdapter', {
|
|
|
25
25
|
description: 'sequence data adapter',
|
|
26
26
|
defaultValue: null,
|
|
27
27
|
},
|
|
28
|
-
}, {
|
|
28
|
+
}, {
|
|
29
|
+
explicitlyTyped: true,
|
|
30
|
+
preProcessSnapshot: snap => {
|
|
31
|
+
return snap.uri
|
|
32
|
+
? {
|
|
33
|
+
...snap,
|
|
34
|
+
cramLocation: {
|
|
35
|
+
uri: snap.uri,
|
|
36
|
+
baseUri: snap.baseUri,
|
|
37
|
+
},
|
|
38
|
+
craiLocation: {
|
|
39
|
+
uri: `${snap.uri}.crai`,
|
|
40
|
+
baseUri: snap.baseUri,
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
: snap;
|
|
44
|
+
},
|
|
45
|
+
});
|
|
29
46
|
export default configSchema;
|
|
@@ -37,7 +37,9 @@ export function doAfterAttach(model) {
|
|
|
37
37
|
layoutId: getContainingTrack(model).id,
|
|
38
38
|
timeout: 1000000,
|
|
39
39
|
statusCallback: (arg) => {
|
|
40
|
-
model
|
|
40
|
+
if (isAlive(model)) {
|
|
41
|
+
model.setMessage(arg);
|
|
42
|
+
}
|
|
41
43
|
},
|
|
42
44
|
...model.renderPropsPre(),
|
|
43
45
|
});
|
|
@@ -13,8 +13,8 @@ export function makeImageData({ ctx, layoutRecords, canvasWidth, renderArgs, })
|
|
|
13
13
|
const hideSmallIndels = readConfObject(config, 'hideSmallIndels');
|
|
14
14
|
const defaultColor = readConfObject(config, 'color') === '#f0f';
|
|
15
15
|
const theme = createJBrowseTheme(configTheme);
|
|
16
|
-
const
|
|
17
|
-
const
|
|
16
|
+
const colorMap = getColorBaseMap(theme);
|
|
17
|
+
const colorContrastMap = getContrastBaseMap(theme);
|
|
18
18
|
ctx.font = 'bold 10px Courier New,monospace';
|
|
19
19
|
const { charWidth, charHeight } = getCharWidthHeight();
|
|
20
20
|
const drawSNPsMuted = shouldDrawSNPsMuted(colorBy === null || colorBy === void 0 ? void 0 : colorBy.type);
|
|
@@ -30,8 +30,8 @@ export function makeImageData({ ctx, layoutRecords, canvasWidth, renderArgs, })
|
|
|
30
30
|
feat,
|
|
31
31
|
renderArgs,
|
|
32
32
|
defaultColor,
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
colorMap,
|
|
34
|
+
colorContrastMap,
|
|
35
35
|
charWidth,
|
|
36
36
|
charHeight,
|
|
37
37
|
canvasWidth,
|
|
@@ -48,8 +48,8 @@ export function makeImageData({ ctx, layoutRecords, canvasWidth, renderArgs, })
|
|
|
48
48
|
minSubfeatureWidth,
|
|
49
49
|
charWidth,
|
|
50
50
|
charHeight,
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
colorMap,
|
|
52
|
+
colorContrastMap,
|
|
53
53
|
canvasWidth,
|
|
54
54
|
});
|
|
55
55
|
if (showSoftClip) {
|
|
@@ -57,7 +57,7 @@ export function makeImageData({ ctx, layoutRecords, canvasWidth, renderArgs, })
|
|
|
57
57
|
ctx,
|
|
58
58
|
feat,
|
|
59
59
|
renderArgs,
|
|
60
|
-
|
|
60
|
+
colorMap,
|
|
61
61
|
config,
|
|
62
62
|
theme,
|
|
63
63
|
canvasWidth,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ProcessedRenderArgs } from './types';
|
|
2
2
|
import type { LayoutFeature } from './util';
|
|
3
|
-
export declare function renderAlignment({ ctx, feat, renderArgs,
|
|
3
|
+
export declare function renderAlignment({ ctx, feat, renderArgs, colorMap, colorContrastMap, charWidth, charHeight, defaultColor, canvasWidth, }: {
|
|
4
4
|
ctx: CanvasRenderingContext2D;
|
|
5
5
|
feat: LayoutFeature;
|
|
6
6
|
renderArgs: ProcessedRenderArgs;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
colorMap: Record<string, string>;
|
|
8
|
+
colorContrastMap: Record<string, string>;
|
|
9
9
|
charWidth: number;
|
|
10
10
|
charHeight: number;
|
|
11
11
|
defaultColor: boolean;
|
|
@@ -5,7 +5,7 @@ import { renderPerBaseLettering } from './renderPerBaseLettering';
|
|
|
5
5
|
import { renderPerBaseQuality } from './renderPerBaseQuality';
|
|
6
6
|
import { parseCigar } from '../MismatchParser';
|
|
7
7
|
import { renderMethylation } from './renderMethylation';
|
|
8
|
-
export function renderAlignment({ ctx, feat, renderArgs,
|
|
8
|
+
export function renderAlignment({ ctx, feat, renderArgs, colorMap, colorContrastMap, charWidth, charHeight, defaultColor, canvasWidth, }) {
|
|
9
9
|
const { config, bpPerPx, regions, colorBy, colorTagMap = {} } = renderArgs;
|
|
10
10
|
const { tag = '', type: colorType = '' } = colorBy || {};
|
|
11
11
|
const { feature } = feat;
|
|
@@ -39,8 +39,8 @@ export function renderAlignment({ ctx, feat, renderArgs, colorForBase, contrastF
|
|
|
39
39
|
feat,
|
|
40
40
|
region,
|
|
41
41
|
bpPerPx,
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
colorMap,
|
|
43
|
+
colorContrastMap,
|
|
44
44
|
charWidth,
|
|
45
45
|
charHeight,
|
|
46
46
|
canvasWidth,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ProcessedRenderArgs } from './types';
|
|
2
2
|
import type { LayoutFeature } from './util';
|
|
3
|
-
export declare function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInsertionIndicatorScale, mismatchAlpha, charWidth, charHeight,
|
|
3
|
+
export declare function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInsertionIndicatorScale, mismatchAlpha, charWidth, charHeight, colorMap, colorContrastMap, hideSmallIndels, canvasWidth, drawSNPsMuted, drawIndels, }: {
|
|
4
4
|
ctx: CanvasRenderingContext2D;
|
|
5
5
|
feat: LayoutFeature;
|
|
6
6
|
renderArgs: ProcessedRenderArgs;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
colorMap: Record<string, string>;
|
|
8
|
+
colorContrastMap: Record<string, string>;
|
|
9
9
|
mismatchAlpha?: boolean;
|
|
10
10
|
drawIndels?: boolean;
|
|
11
11
|
drawSNPsMuted?: boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { bpSpanPx, measureText } from '@jbrowse/core/util';
|
|
2
2
|
import { colord } from '@jbrowse/core/util/colord';
|
|
3
3
|
import { fillRect } from './util';
|
|
4
|
-
export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInsertionIndicatorScale, mismatchAlpha, charWidth, charHeight,
|
|
4
|
+
export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, largeInsertionIndicatorScale, mismatchAlpha, charWidth, charHeight, colorMap, colorContrastMap, hideSmallIndels, canvasWidth, drawSNPsMuted, drawIndels = true, }) {
|
|
5
5
|
const { bpPerPx, regions } = renderArgs;
|
|
6
6
|
const { heightPx, topPx, feature } = feat;
|
|
7
7
|
const region = regions[0];
|
|
@@ -21,7 +21,7 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
|
|
|
21
21
|
const widthPx = Math.max(minSubfeatureWidth, rightPx - leftPx);
|
|
22
22
|
if (mismatch.type === 'mismatch') {
|
|
23
23
|
if (!drawSNPsMuted) {
|
|
24
|
-
const baseColor =
|
|
24
|
+
const baseColor = colorMap[mismatch.base] || '#888';
|
|
25
25
|
const c = mismatchAlpha && mismatch.qual !== undefined
|
|
26
26
|
? colord(baseColor)
|
|
27
27
|
.alpha(Math.min(1, mismatch.qual / 50))
|
|
@@ -32,7 +32,7 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
|
|
|
32
32
|
if (widthPx >= charWidth && heightPx >= heightLim) {
|
|
33
33
|
const contrastColor = drawSNPsMuted
|
|
34
34
|
? 'black'
|
|
35
|
-
:
|
|
35
|
+
: colorContrastMap[mismatch.base] || 'black';
|
|
36
36
|
ctx.fillStyle =
|
|
37
37
|
mismatchAlpha && mismatch.qual !== undefined
|
|
38
38
|
? colord(contrastColor)
|
|
@@ -45,11 +45,11 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
|
|
|
45
45
|
else if (mismatch.type === 'deletion' && drawIndels) {
|
|
46
46
|
const len = mismatch.length;
|
|
47
47
|
if (!hideSmallIndels || len >= 10) {
|
|
48
|
-
fillRect(ctx, leftPx, topPx, Math.abs(leftPx - rightPx), heightPx, canvasWidth,
|
|
48
|
+
fillRect(ctx, leftPx, topPx, Math.abs(leftPx - rightPx), heightPx, canvasWidth, colorMap.deletion);
|
|
49
49
|
const txt = `${mismatch.length}`;
|
|
50
50
|
const rwidth = measureText(txt, 10);
|
|
51
51
|
if (widthPx >= rwidth && heightPx >= heightLim) {
|
|
52
|
-
ctx.fillStyle =
|
|
52
|
+
ctx.fillStyle = colorContrastMap.deletion;
|
|
53
53
|
ctx.fillText(txt, (leftPx + rightPx) / 2 - rwidth / 2, topPx + heightPx);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -60,7 +60,7 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
|
|
|
60
60
|
const insW = Math.max(0, Math.min(1.2, 1 / bpPerPx));
|
|
61
61
|
if (len < 10) {
|
|
62
62
|
if (!hideSmallIndels) {
|
|
63
|
-
fillRect(ctx, pos, topPx, insW, heightPx, canvasWidth,
|
|
63
|
+
fillRect(ctx, pos, topPx, insW, heightPx, canvasWidth, colorMap.insertion);
|
|
64
64
|
if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
|
|
65
65
|
const l = Math.round(pos - insW);
|
|
66
66
|
fillRect(ctx, l, topPx, insW * 3, 1, canvasWidth);
|
|
@@ -72,7 +72,7 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
|
|
|
72
72
|
}
|
|
73
73
|
else if (mismatch.type === 'hardclip' || mismatch.type === 'softclip') {
|
|
74
74
|
const pos = leftPx + extraHorizontallyFlippedOffset;
|
|
75
|
-
const c = mismatch.type
|
|
75
|
+
const c = colorMap[mismatch.type];
|
|
76
76
|
const clipW = Math.max(minSubfeatureWidth, pxPerBp);
|
|
77
77
|
fillRect(ctx, pos, topPx, clipW, heightPx, canvasWidth, c);
|
|
78
78
|
if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
|
|
@@ -89,7 +89,7 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
|
|
|
89
89
|
const t = topPx + heightPx / 2 - 1;
|
|
90
90
|
const w = adjustPx + Math.min(leftPx, 0);
|
|
91
91
|
const h = 1;
|
|
92
|
-
fillRect(ctx, l, t, w, h, canvasWidth,
|
|
92
|
+
fillRect(ctx, l, t, w, h, canvasWidth, colorMap.skip);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -102,18 +102,18 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
|
|
|
102
102
|
const [leftPx] = bpSpanPx(mstart, mstart + mlen, region, bpPerPx);
|
|
103
103
|
const txt = `${len}`;
|
|
104
104
|
if (bpPerPx > largeInsertionIndicatorScale) {
|
|
105
|
-
fillRect(ctx, leftPx - 1, topPx, 2, heightPx, canvasWidth,
|
|
105
|
+
fillRect(ctx, leftPx - 1, topPx, 2, heightPx, canvasWidth, colorMap.insertion);
|
|
106
106
|
}
|
|
107
107
|
else if (heightPx > charHeight) {
|
|
108
108
|
const rwidth = measureText(txt);
|
|
109
109
|
const padding = 5;
|
|
110
110
|
fillRect(ctx, leftPx - rwidth / 2 - padding, topPx, rwidth + 2 * padding, heightPx, canvasWidth, 'purple');
|
|
111
|
-
ctx.fillStyle =
|
|
111
|
+
ctx.fillStyle = colorContrastMap.insertion;
|
|
112
112
|
ctx.fillText(txt, leftPx - rwidth / 2, topPx + heightPx);
|
|
113
113
|
}
|
|
114
114
|
else {
|
|
115
115
|
const padding = 2;
|
|
116
|
-
fillRect(ctx, leftPx - padding, topPx, 2 * padding, heightPx, canvasWidth,
|
|
116
|
+
fillRect(ctx, leftPx - padding, topPx, 2 * padding, heightPx, canvasWidth, colorMap.insertion);
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { LayoutFeature } from './util';
|
|
2
2
|
import type { Region } from '@jbrowse/core/util';
|
|
3
|
-
export declare function renderPerBaseLettering({ ctx, feat, region, bpPerPx,
|
|
3
|
+
export declare function renderPerBaseLettering({ ctx, feat, region, bpPerPx, colorMap, colorContrastMap, charWidth, charHeight, canvasWidth, cigarOps, }: {
|
|
4
4
|
ctx: CanvasRenderingContext2D;
|
|
5
5
|
feat: LayoutFeature;
|
|
6
6
|
region: Region;
|
|
7
7
|
bpPerPx: number;
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
colorMap: Record<string, string>;
|
|
9
|
+
colorContrastMap: Record<string, string>;
|
|
10
10
|
charWidth: number;
|
|
11
11
|
charHeight: number;
|
|
12
12
|
canvasWidth: number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { bpSpanPx } from '@jbrowse/core/util';
|
|
2
2
|
import { fillRect } from './util';
|
|
3
|
-
export function renderPerBaseLettering({ ctx, feat, region, bpPerPx,
|
|
3
|
+
export function renderPerBaseLettering({ ctx, feat, region, bpPerPx, colorMap, colorContrastMap, charWidth, charHeight, canvasWidth, cigarOps, }) {
|
|
4
4
|
const heightLim = charHeight - 2;
|
|
5
5
|
const { feature, topPx, heightPx } = feat;
|
|
6
6
|
const seq = feature.get('seq');
|
|
@@ -25,10 +25,10 @@ export function renderPerBaseLettering({ ctx, feat, region, bpPerPx, colorForBas
|
|
|
25
25
|
const letter = seq[soffset + m];
|
|
26
26
|
const r = start + roffset + m;
|
|
27
27
|
const [leftPx] = bpSpanPx(r, r + 1, region, bpPerPx);
|
|
28
|
-
const c =
|
|
28
|
+
const c = colorMap[letter];
|
|
29
29
|
fillRect(ctx, leftPx, topPx, w + 0.5, heightPx, canvasWidth, c);
|
|
30
30
|
if (w >= charWidth && heightPx >= heightLim) {
|
|
31
|
-
ctx.fillStyle =
|
|
31
|
+
ctx.fillStyle = colorContrastMap[letter];
|
|
32
32
|
ctx.fillText(letter, leftPx + (w - charWidth) / 2 + 1, topPx + heightPx);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -2,12 +2,12 @@ import type { ProcessedRenderArgs } from './types';
|
|
|
2
2
|
import type { LayoutFeature } from './util';
|
|
3
3
|
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
4
4
|
import type { Theme } from '@mui/material';
|
|
5
|
-
export declare function renderSoftClipping({ ctx, feat, renderArgs, config, theme,
|
|
5
|
+
export declare function renderSoftClipping({ ctx, feat, renderArgs, config, theme, colorMap, canvasWidth, }: {
|
|
6
6
|
ctx: CanvasRenderingContext2D;
|
|
7
7
|
feat: LayoutFeature;
|
|
8
8
|
renderArgs: ProcessedRenderArgs;
|
|
9
9
|
config: AnyConfigurationModel;
|
|
10
|
-
|
|
10
|
+
colorMap: Record<string, string>;
|
|
11
11
|
theme: Theme;
|
|
12
12
|
canvasWidth: number;
|
|
13
13
|
}): void;
|
|
@@ -2,7 +2,7 @@ import { readConfObject } from '@jbrowse/core/configuration';
|
|
|
2
2
|
import { bpSpanPx } from '@jbrowse/core/util';
|
|
3
3
|
import { fillRect, getCharWidthHeight } from './util';
|
|
4
4
|
import { parseCigar } from '../MismatchParser';
|
|
5
|
-
export function renderSoftClipping({ ctx, feat, renderArgs, config, theme,
|
|
5
|
+
export function renderSoftClipping({ ctx, feat, renderArgs, config, theme, colorMap, canvasWidth, }) {
|
|
6
6
|
const { feature, topPx, heightPx } = feat;
|
|
7
7
|
const { regions, bpPerPx } = renderArgs;
|
|
8
8
|
const region = regions[0];
|
|
@@ -27,7 +27,7 @@ export function renderSoftClipping({ ctx, feat, renderArgs, config, theme, color
|
|
|
27
27
|
const s0 = feature.get('start') - (i === 0 ? len : 0) + refOffset + k;
|
|
28
28
|
const [leftPx, rightPx] = bpSpanPx(s0, s0 + 1, region, bpPerPx);
|
|
29
29
|
const widthPx = Math.max(minFeatWidth, rightPx - leftPx);
|
|
30
|
-
const baseColor =
|
|
30
|
+
const baseColor = colorMap[base] || '#000000';
|
|
31
31
|
ctx.fillStyle = baseColor;
|
|
32
32
|
fillRect(ctx, leftPx, topPx, widthPx, heightPx, canvasWidth);
|
|
33
33
|
if (widthPx >= charWidth && heightPx >= heightLim) {
|
|
@@ -7,6 +7,10 @@ export declare function getColorBaseMap(theme: Theme): {
|
|
|
7
7
|
G: string;
|
|
8
8
|
T: string;
|
|
9
9
|
deletion: string;
|
|
10
|
+
insertion: string;
|
|
11
|
+
hardclip: string;
|
|
12
|
+
softclip: string;
|
|
13
|
+
skip: string;
|
|
10
14
|
};
|
|
11
15
|
export declare function getContrastBaseMap(theme: Theme): {
|
|
12
16
|
[k: string]: string;
|
|
@@ -9,13 +9,17 @@ export function fillRect(ctx, l, t, w, h, cw, color) {
|
|
|
9
9
|
ctx.fillRect(l, t, w, h);
|
|
10
10
|
}
|
|
11
11
|
export function getColorBaseMap(theme) {
|
|
12
|
-
const { bases } = theme.palette;
|
|
12
|
+
const { skip, deletion, insertion, hardclip, softclip, bases } = theme.palette;
|
|
13
13
|
return {
|
|
14
14
|
A: bases.A.main,
|
|
15
15
|
C: bases.C.main,
|
|
16
16
|
G: bases.G.main,
|
|
17
17
|
T: bases.T.main,
|
|
18
|
-
deletion
|
|
18
|
+
deletion,
|
|
19
|
+
insertion,
|
|
20
|
+
hardclip,
|
|
21
|
+
softclip,
|
|
22
|
+
skip,
|
|
19
23
|
};
|
|
20
24
|
}
|
|
21
25
|
export function getContrastBaseMap(theme) {
|
|
@@ -39,22 +39,22 @@ export async function makeImage(ctx, props) {
|
|
|
39
39
|
const toHeight = (n) => toY(originY) - toY(n);
|
|
40
40
|
const toY2 = (n) => height - (indicatorViewScale(n) || 0) + offset;
|
|
41
41
|
const toHeight2 = (n) => toY2(originLinear) - toY2(n);
|
|
42
|
-
const { bases } = theme.palette;
|
|
43
|
-
const
|
|
42
|
+
const { bases, softclip, hardclip, insertion } = theme.palette;
|
|
43
|
+
const colorMap = {
|
|
44
44
|
A: bases.A.main,
|
|
45
45
|
C: bases.C.main,
|
|
46
46
|
G: bases.G.main,
|
|
47
47
|
T: bases.T.main,
|
|
48
|
-
insertion
|
|
49
|
-
softclip
|
|
50
|
-
hardclip
|
|
48
|
+
insertion,
|
|
49
|
+
softclip,
|
|
50
|
+
hardclip,
|
|
51
51
|
total: readConfObject(cfg, 'color'),
|
|
52
52
|
mod_NONE: 'blue',
|
|
53
53
|
cpg_meth: 'red',
|
|
54
54
|
cpg_unmeth: 'blue',
|
|
55
55
|
};
|
|
56
56
|
const feats = [...features.values()];
|
|
57
|
-
ctx.fillStyle =
|
|
57
|
+
ctx.fillStyle = colorMap.total;
|
|
58
58
|
let start = performance.now();
|
|
59
59
|
for (const feature of feats) {
|
|
60
60
|
if (feature.get('type') === 'skip') {
|
|
@@ -164,7 +164,7 @@ export async function makeImage(ctx, props) {
|
|
|
164
164
|
const { entryDepth } = mods[base];
|
|
165
165
|
const height = toHeight(score0);
|
|
166
166
|
const bottom = toY(score0) + height;
|
|
167
|
-
ctx.fillStyle =
|
|
167
|
+
ctx.fillStyle = colorMap[base] || 'black';
|
|
168
168
|
ctx.fillRect(Math.round(leftPx), bottom - ((entryDepth + curr) / depth) * height, w, (entryDepth / depth) * height);
|
|
169
169
|
curr += entryDepth;
|
|
170
170
|
}
|
|
@@ -172,7 +172,7 @@ export async function makeImage(ctx, props) {
|
|
|
172
172
|
const { entryDepth } = nonmods[base];
|
|
173
173
|
const height = toHeight(score0);
|
|
174
174
|
const bottom = toY(score0) + height;
|
|
175
|
-
ctx.fillStyle =
|
|
175
|
+
ctx.fillStyle = colorMap[base] || 'black';
|
|
176
176
|
ctx.fillRect(Math.round(leftPx), bottom - ((entryDepth + curr) / depth) * height, w, (entryDepth / depth) * height);
|
|
177
177
|
curr += entryDepth;
|
|
178
178
|
}
|
|
@@ -184,7 +184,7 @@ export async function makeImage(ctx, props) {
|
|
|
184
184
|
const { entryDepth } = snps[base];
|
|
185
185
|
const height = toHeight(score0);
|
|
186
186
|
const bottom = toY(score0) + height;
|
|
187
|
-
ctx.fillStyle =
|
|
187
|
+
ctx.fillStyle = colorMap[base] || 'black';
|
|
188
188
|
ctx.fillRect(Math.round(leftPx), bottom - ((entryDepth + curr) / depth) * height, w, (entryDepth / depth) * height);
|
|
189
189
|
curr += entryDepth;
|
|
190
190
|
}
|
|
@@ -195,7 +195,7 @@ export async function makeImage(ctx, props) {
|
|
|
195
195
|
for (const base of interbaseEvents) {
|
|
196
196
|
const { entryDepth } = snpinfo.noncov[base];
|
|
197
197
|
const r = 0.6;
|
|
198
|
-
ctx.fillStyle =
|
|
198
|
+
ctx.fillStyle = colorMap[base];
|
|
199
199
|
ctx.fillRect(leftPx - r + extraHorizontallyFlippedOffset, INTERBASE_INDICATOR_HEIGHT + toHeight2(curr), r * 2, toHeight2(entryDepth));
|
|
200
200
|
curr += entryDepth;
|
|
201
201
|
}
|
|
@@ -215,7 +215,7 @@ export async function makeImage(ctx, props) {
|
|
|
215
215
|
const indicatorComparatorScore = Math.max(score0, prevTotal);
|
|
216
216
|
if (accum > indicatorComparatorScore * indicatorThreshold &&
|
|
217
217
|
indicatorComparatorScore > MINIMUM_INTERBASE_INDICATOR_READ_DEPTH) {
|
|
218
|
-
ctx.fillStyle =
|
|
218
|
+
ctx.fillStyle = colorMap[maxBase];
|
|
219
219
|
ctx.beginPath();
|
|
220
220
|
const l = leftPx + extraHorizontallyFlippedOffset;
|
|
221
221
|
ctx.moveTo(l - INTERBASE_INDICATOR_WIDTH / 2, 0);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { type IAnyStateTreeNode } from 'mobx-state-tree';
|
|
1
2
|
import type { ModificationType } from './types';
|
|
2
3
|
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
3
4
|
import type { BlockSet } from '@jbrowse/core/util/blockTypes';
|
|
4
|
-
import type { IAnyStateTreeNode } from 'mobx-state-tree';
|
|
5
5
|
export interface ModificationOpts {
|
|
6
6
|
headers?: Record<string, string>;
|
|
7
7
|
stopToken?: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getSession } from '@jbrowse/core/util';
|
|
2
2
|
import { getRpcSessionId } from '@jbrowse/core/util/tracks';
|
|
3
|
+
import { isAlive } from 'mobx-state-tree';
|
|
3
4
|
export async function getUniqueModifications({ model, adapterConfig, blocks, opts, }) {
|
|
4
5
|
const { rpcManager } = getSession(model);
|
|
5
6
|
const sessionId = getRpcSessionId(model);
|
|
@@ -8,7 +9,9 @@ export async function getUniqueModifications({ model, adapterConfig, blocks, opt
|
|
|
8
9
|
sessionId,
|
|
9
10
|
regions: blocks.contentBlocks,
|
|
10
11
|
statusCallback: (arg) => {
|
|
11
|
-
model
|
|
12
|
+
if (isAlive(model)) {
|
|
13
|
+
model.setMessage(arg);
|
|
14
|
+
}
|
|
12
15
|
},
|
|
13
16
|
...opts,
|
|
14
17
|
});
|
package/esm/shared/util.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-alignments",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "JBrowse 2 alignments adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@gmod/bam": "^5.0.0",
|
|
40
40
|
"@gmod/cram": "^4.0.1",
|
|
41
|
-
"@jbrowse/core": "^3.0
|
|
42
|
-
"@jbrowse/plugin-linear-genome-view": "^3.0
|
|
43
|
-
"@jbrowse/plugin-wiggle": "^3.0
|
|
44
|
-
"@jbrowse/sv-core": "^3.0
|
|
41
|
+
"@jbrowse/core": "^3.1.0",
|
|
42
|
+
"@jbrowse/plugin-linear-genome-view": "^3.1.0",
|
|
43
|
+
"@jbrowse/plugin-wiggle": "^3.1.0",
|
|
44
|
+
"@jbrowse/sv-core": "^3.1.0",
|
|
45
45
|
"@mui/icons-material": "^6.0.0",
|
|
46
46
|
"@mui/material": "^6.0.0",
|
|
47
47
|
"canvas2svg": "^1.0.16",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"distModule": "esm/index.js",
|
|
64
64
|
"srcModule": "src/index.ts",
|
|
65
65
|
"module": "esm/index.js",
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "91492049ddea0aed90eb24d3c066c2d9f5a6b189"
|
|
67
67
|
}
|