@jbrowse/plugin-alignments 1.6.7 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +216 -0
- package/dist/AlignmentsFeatureDetail/index.js +63 -0
- package/dist/AlignmentsFeatureDetail/index.test.js +60 -0
- package/dist/AlignmentsTrack/index.js +37 -0
- package/dist/BamAdapter/BamAdapter.js +598 -0
- package/dist/BamAdapter/BamAdapter.test.js +177 -0
- package/dist/BamAdapter/BamSlightlyLazyFeature.d.ts +1 -10
- package/dist/BamAdapter/BamSlightlyLazyFeature.js +176 -0
- package/dist/BamAdapter/MismatchParser.d.ts +3 -5
- package/dist/BamAdapter/MismatchParser.js +384 -0
- package/dist/BamAdapter/MismatchParser.test.js +259 -0
- package/dist/BamAdapter/configSchema.js +48 -0
- package/dist/BamAdapter/index.js +36 -0
- package/dist/CramAdapter/CramAdapter.js +660 -0
- package/dist/CramAdapter/CramAdapter.test.js +138 -0
- package/dist/CramAdapter/CramSlightlyLazyFeature.d.ts +1 -2
- package/dist/CramAdapter/CramSlightlyLazyFeature.js +447 -0
- package/dist/CramAdapter/CramTestAdapters.js +234 -0
- package/dist/CramAdapter/configSchema.js +40 -0
- package/dist/CramAdapter/index.js +36 -0
- package/dist/HtsgetBamAdapter/HtsgetBamAdapter.js +97 -0
- package/dist/HtsgetBamAdapter/configSchema.js +31 -0
- package/dist/HtsgetBamAdapter/index.js +42 -0
- package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +69 -0
- package/dist/LinearAlignmentsDisplay/index.js +31 -0
- package/dist/LinearAlignmentsDisplay/models/configSchema.js +25 -0
- package/dist/LinearAlignmentsDisplay/models/configSchema.test.js +83 -0
- package/dist/LinearAlignmentsDisplay/models/model.js +250 -0
- package/dist/LinearPileupDisplay/components/ColorByModifications.js +123 -0
- package/dist/LinearPileupDisplay/components/ColorByTag.js +98 -0
- package/dist/LinearPileupDisplay/components/FilterByTag.js +203 -0
- package/dist/LinearPileupDisplay/components/LinearPileupDisplayBlurb.js +32 -0
- package/dist/LinearPileupDisplay/components/SetFeatureHeight.js +99 -0
- package/dist/LinearPileupDisplay/components/SetMaxHeight.js +90 -0
- package/dist/LinearPileupDisplay/components/SortByTag.js +95 -0
- package/dist/LinearPileupDisplay/configSchema.js +47 -0
- package/dist/LinearPileupDisplay/configSchema.test.js +92 -0
- package/dist/LinearPileupDisplay/index.js +30 -0
- package/dist/LinearPileupDisplay/model.js +602 -0
- package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +63 -0
- package/dist/LinearSNPCoverageDisplay/index.js +30 -0
- package/dist/LinearSNPCoverageDisplay/models/configSchema.js +57 -0
- package/dist/LinearSNPCoverageDisplay/models/configSchema.test.js +62 -0
- package/dist/LinearSNPCoverageDisplay/models/model.d.ts +2 -2
- package/dist/LinearSNPCoverageDisplay/models/model.js +237 -0
- package/dist/NestedFrequencyTable.js +152 -0
- package/dist/PileupRPC/rpcMethods.js +285 -0
- package/dist/PileupRenderer/PileupLayoutSession.js +79 -0
- package/dist/PileupRenderer/PileupRenderer.d.ts +20 -6
- package/dist/PileupRenderer/PileupRenderer.js +1220 -0
- package/dist/PileupRenderer/components/PileupRendering.js +270 -0
- package/dist/PileupRenderer/components/PileupRendering.test.js +36 -0
- package/dist/PileupRenderer/configSchema.js +72 -0
- package/dist/PileupRenderer/index.js +25 -0
- package/dist/PileupRenderer/sortUtil.js +112 -0
- package/dist/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +3 -11
- package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js +606 -0
- package/dist/SNPCoverageAdapter/configSchema.js +22 -0
- package/dist/SNPCoverageAdapter/index.js +45 -0
- package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +296 -0
- package/dist/SNPCoverageRenderer/configSchema.js +40 -0
- package/dist/SNPCoverageRenderer/index.js +34 -0
- package/dist/declare.d.js +1 -0
- package/dist/index.js +154 -6
- package/dist/index.test.js +26 -0
- package/dist/plugin-alignments.cjs.development.js +591 -552
- package/dist/plugin-alignments.cjs.development.js.map +1 -1
- package/dist/plugin-alignments.cjs.production.min.js +1 -1
- package/dist/plugin-alignments.cjs.production.min.js.map +1 -1
- package/dist/plugin-alignments.esm.js +594 -555
- package/dist/plugin-alignments.esm.js.map +1 -1
- package/dist/shared.js +96 -0
- package/dist/util.d.ts +4 -0
- package/dist/util.js +135 -0
- package/package.json +5 -9
- package/src/BamAdapter/BamAdapter.ts +45 -15
- package/src/BamAdapter/BamSlightlyLazyFeature.ts +11 -79
- package/src/BamAdapter/MismatchParser.test.ts +53 -297
- package/src/BamAdapter/MismatchParser.ts +54 -116
- package/src/BamAdapter/configSchema.ts +0 -4
- package/src/CramAdapter/CramAdapter.ts +42 -15
- package/src/CramAdapter/CramSlightlyLazyFeature.ts +3 -10
- package/src/LinearPileupDisplay/components/ColorByModifications.tsx +76 -80
- package/src/LinearPileupDisplay/components/ColorByTag.tsx +24 -23
- package/src/LinearPileupDisplay/components/FilterByTag.tsx +73 -68
- package/src/LinearPileupDisplay/components/SetFeatureHeight.tsx +28 -26
- package/src/LinearPileupDisplay/components/SetMaxHeight.tsx +24 -13
- package/src/LinearPileupDisplay/components/SortByTag.tsx +29 -21
- package/src/LinearPileupDisplay/model.ts +8 -22
- package/src/LinearSNPCoverageDisplay/models/model.ts +6 -36
- package/src/PileupRenderer/PileupRenderer.tsx +178 -60
- package/src/SNPCoverageAdapter/SNPCoverageAdapter.ts +189 -244
- package/src/SNPCoverageRenderer/SNPCoverageRenderer.ts +12 -11
- package/src/util.ts +25 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { toArray } from 'rxjs/operators'
|
|
1
|
+
import Color from 'color'
|
|
3
2
|
import BoxRendererType, {
|
|
4
3
|
RenderArgs,
|
|
5
4
|
RenderArgsSerialized,
|
|
@@ -10,14 +9,20 @@ import BoxRendererType, {
|
|
|
10
9
|
} from '@jbrowse/core/pluggableElementTypes/renderers/BoxRendererType'
|
|
11
10
|
import { Theme } from '@material-ui/core'
|
|
12
11
|
import { createJBrowseTheme } from '@jbrowse/core/ui'
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
import {
|
|
13
|
+
bpSpanPx,
|
|
14
|
+
iterMap,
|
|
15
|
+
measureText,
|
|
16
|
+
Region,
|
|
17
|
+
Feature,
|
|
18
|
+
} from '@jbrowse/core/util'
|
|
17
19
|
import { renderToAbstractCanvas } from '@jbrowse/core/util/offscreenCanvasUtils'
|
|
18
20
|
import { BaseLayout } from '@jbrowse/core/util/layouts/BaseLayout'
|
|
19
21
|
import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache'
|
|
20
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
readConfObject,
|
|
24
|
+
AnyConfigurationModel,
|
|
25
|
+
} from '@jbrowse/core/configuration'
|
|
21
26
|
|
|
22
27
|
// locals
|
|
23
28
|
import {
|
|
@@ -27,7 +32,12 @@ import {
|
|
|
27
32
|
getNextRefPos,
|
|
28
33
|
} from '../BamAdapter/MismatchParser'
|
|
29
34
|
import { sortFeature } from './sortUtil'
|
|
30
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
getTagAlt,
|
|
37
|
+
orientationTypes,
|
|
38
|
+
fetchSequence,
|
|
39
|
+
shouldFetchReferenceSequence,
|
|
40
|
+
} from '../util'
|
|
31
41
|
import {
|
|
32
42
|
PileupLayoutSession,
|
|
33
43
|
PileupLayoutSessionProps,
|
|
@@ -44,6 +54,15 @@ function getColorBaseMap(theme: Theme) {
|
|
|
44
54
|
}
|
|
45
55
|
}
|
|
46
56
|
|
|
57
|
+
function getContrastBaseMap(theme: Theme) {
|
|
58
|
+
return Object.fromEntries(
|
|
59
|
+
Object.entries(getColorBaseMap(theme)).map(([key, value]) => [
|
|
60
|
+
key,
|
|
61
|
+
theme.palette.getContrastText(value),
|
|
62
|
+
]),
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
47
66
|
export interface RenderArgsDeserialized extends BoxRenderArgsDeserialized {
|
|
48
67
|
colorBy?: { type: string; tag?: string }
|
|
49
68
|
colorTagMap?: Record<string, string>
|
|
@@ -263,6 +282,64 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
263
282
|
return strand === 1 ? 'color_fwd_strand' : 'color_rev_strand'
|
|
264
283
|
}
|
|
265
284
|
|
|
285
|
+
colorByPerBaseLettering(
|
|
286
|
+
ctx: CanvasRenderingContext2D,
|
|
287
|
+
feat: LayoutFeature,
|
|
288
|
+
_config: AnyConfigurationModel,
|
|
289
|
+
region: Region,
|
|
290
|
+
bpPerPx: number,
|
|
291
|
+
props: {
|
|
292
|
+
colorForBase: Record<string, string>
|
|
293
|
+
contrastForBase: Record<string, string>
|
|
294
|
+
charWidth: number
|
|
295
|
+
charHeight: number
|
|
296
|
+
},
|
|
297
|
+
) {
|
|
298
|
+
const { colorForBase, contrastForBase, charWidth, charHeight } = props
|
|
299
|
+
const heightLim = charHeight - 2
|
|
300
|
+
const { feature, topPx, heightPx } = feat
|
|
301
|
+
const seq = feature.get('seq') as string
|
|
302
|
+
const cigarOps = parseCigar(feature.get('CIGAR'))
|
|
303
|
+
const widthPx = 1 / bpPerPx
|
|
304
|
+
const start = feature.get('start')
|
|
305
|
+
let soffset = 0 // sequence offset
|
|
306
|
+
let roffset = 0 // reference offset
|
|
307
|
+
|
|
308
|
+
for (let i = 0; i < cigarOps.length; i += 2) {
|
|
309
|
+
const len = +cigarOps[i]
|
|
310
|
+
const op = cigarOps[i + 1]
|
|
311
|
+
if (op === 'S' || op === 'I') {
|
|
312
|
+
soffset += len
|
|
313
|
+
} else if (op === 'D' || op === 'N') {
|
|
314
|
+
roffset += len
|
|
315
|
+
} else if (op === 'M' || op === 'X' || op === '=') {
|
|
316
|
+
for (let m = 0; m < len; m++) {
|
|
317
|
+
const letter = seq[soffset + m]
|
|
318
|
+
ctx.fillStyle = colorForBase[letter]
|
|
319
|
+
const [leftPx] = bpSpanPx(
|
|
320
|
+
start + roffset + m,
|
|
321
|
+
start + roffset + m + 1,
|
|
322
|
+
region,
|
|
323
|
+
bpPerPx,
|
|
324
|
+
)
|
|
325
|
+
ctx.fillRect(leftPx, topPx, widthPx + 0.5, heightPx)
|
|
326
|
+
|
|
327
|
+
if (widthPx >= charWidth && heightPx >= heightLim) {
|
|
328
|
+
// normal SNP coloring
|
|
329
|
+
ctx.fillStyle = contrastForBase[letter]
|
|
330
|
+
|
|
331
|
+
ctx.fillText(
|
|
332
|
+
letter,
|
|
333
|
+
leftPx + (widthPx - charWidth) / 2 + 1,
|
|
334
|
+
topPx + heightPx,
|
|
335
|
+
)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
soffset += len
|
|
339
|
+
roffset += len
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
266
343
|
colorByPerBaseQuality(
|
|
267
344
|
ctx: CanvasRenderingContext2D,
|
|
268
345
|
feat: LayoutFeature,
|
|
@@ -276,27 +353,30 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
276
353
|
const cigarOps = parseCigar(feature.get('CIGAR'))
|
|
277
354
|
const width = 1 / bpPerPx
|
|
278
355
|
const start = feature.get('start')
|
|
356
|
+
let soffset = 0 // sequence offset
|
|
357
|
+
let roffset = 0 // reference offset
|
|
279
358
|
|
|
280
|
-
for (let i = 0
|
|
359
|
+
for (let i = 0; i < cigarOps.length; i += 2) {
|
|
281
360
|
const len = +cigarOps[i]
|
|
282
361
|
const op = cigarOps[i + 1]
|
|
283
362
|
if (op === 'S' || op === 'I') {
|
|
284
|
-
|
|
363
|
+
soffset += len
|
|
285
364
|
} else if (op === 'D' || op === 'N') {
|
|
286
|
-
|
|
365
|
+
roffset += len
|
|
287
366
|
} else if (op === 'M' || op === 'X' || op === '=') {
|
|
288
367
|
for (let m = 0; m < len; m++) {
|
|
289
|
-
const score = scores[
|
|
368
|
+
const score = scores[soffset + m]
|
|
290
369
|
ctx.fillStyle = `hsl(${score === 255 ? 150 : score * 1.5},55%,50%)`
|
|
291
370
|
const [leftPx] = bpSpanPx(
|
|
292
|
-
start +
|
|
293
|
-
start +
|
|
371
|
+
start + roffset + m,
|
|
372
|
+
start + roffset + m + 1,
|
|
294
373
|
region,
|
|
295
374
|
bpPerPx,
|
|
296
375
|
)
|
|
297
376
|
ctx.fillRect(leftPx, topPx, width + 0.5, heightPx)
|
|
298
377
|
}
|
|
299
|
-
|
|
378
|
+
soffset += len
|
|
379
|
+
roffset += len
|
|
300
380
|
}
|
|
301
381
|
}
|
|
302
382
|
}
|
|
@@ -372,8 +452,8 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
372
452
|
}
|
|
373
453
|
|
|
374
454
|
// Color by methylation is slightly modified version of color by
|
|
375
|
-
// modifications
|
|
376
|
-
//
|
|
455
|
+
// modifications that focuses on CpG sites, with non-methylated CpG colored
|
|
456
|
+
// blue
|
|
377
457
|
colorByMethylation(
|
|
378
458
|
ctx: CanvasRenderingContext2D,
|
|
379
459
|
layoutFeature: LayoutFeature,
|
|
@@ -503,6 +583,10 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
503
583
|
ctx: CanvasRenderingContext2D,
|
|
504
584
|
feat: LayoutFeature,
|
|
505
585
|
props: RenderArgsDeserializedWithFeaturesAndLayout & {
|
|
586
|
+
colorForBase: Record<string, string>
|
|
587
|
+
contrastForBase: Record<string, string>
|
|
588
|
+
charWidth: number
|
|
589
|
+
charHeight: number
|
|
506
590
|
defaultColor: boolean
|
|
507
591
|
},
|
|
508
592
|
) {
|
|
@@ -513,6 +597,10 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
513
597
|
regions,
|
|
514
598
|
colorBy,
|
|
515
599
|
colorTagMap = {},
|
|
600
|
+
colorForBase,
|
|
601
|
+
contrastForBase,
|
|
602
|
+
charWidth,
|
|
603
|
+
charHeight,
|
|
516
604
|
} = props
|
|
517
605
|
const { tag = '', type: colorType = '' } = colorBy || {}
|
|
518
606
|
const { feature } = feat
|
|
@@ -577,6 +665,18 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
577
665
|
case 'insertSizeAndPairOrientation':
|
|
578
666
|
break
|
|
579
667
|
|
|
668
|
+
case 'modifications':
|
|
669
|
+
case 'methylation':
|
|
670
|
+
// this coloring is similar to igv.js, and is helpful to color negative
|
|
671
|
+
// strand reads differently because their c-g will be flipped (e.g. g-c
|
|
672
|
+
// read right to left)
|
|
673
|
+
if (feature.get('flags') & 16) {
|
|
674
|
+
ctx.fillStyle = '#c8dcc8'
|
|
675
|
+
} else {
|
|
676
|
+
ctx.fillStyle = '#c8c8c8'
|
|
677
|
+
}
|
|
678
|
+
break
|
|
679
|
+
|
|
580
680
|
case 'normal':
|
|
581
681
|
default:
|
|
582
682
|
if (defaultColor) {
|
|
@@ -597,6 +697,15 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
597
697
|
this.colorByPerBaseQuality(ctx, feat, config, region, bpPerPx)
|
|
598
698
|
break
|
|
599
699
|
|
|
700
|
+
case 'perBaseLettering':
|
|
701
|
+
this.colorByPerBaseLettering(ctx, feat, config, region, bpPerPx, {
|
|
702
|
+
colorForBase,
|
|
703
|
+
contrastForBase,
|
|
704
|
+
charWidth,
|
|
705
|
+
charHeight,
|
|
706
|
+
})
|
|
707
|
+
break
|
|
708
|
+
|
|
600
709
|
case 'modifications':
|
|
601
710
|
this.colorByModifications(ctx, feat, config, region, bpPerPx, props)
|
|
602
711
|
break
|
|
@@ -611,9 +720,9 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
611
720
|
ctx: CanvasRenderingContext2D,
|
|
612
721
|
feat: LayoutFeature,
|
|
613
722
|
props: RenderArgsDeserializedWithFeaturesAndLayout,
|
|
614
|
-
theme: Theme,
|
|
615
|
-
colorForBase: { [key: string]: string },
|
|
616
723
|
opts: {
|
|
724
|
+
colorForBase: { [key: string]: string }
|
|
725
|
+
contrastForBase: { [key: string]: string }
|
|
617
726
|
mismatchAlpha?: boolean
|
|
618
727
|
drawSNPs?: boolean
|
|
619
728
|
drawIndels?: boolean
|
|
@@ -624,13 +733,15 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
624
733
|
},
|
|
625
734
|
) {
|
|
626
735
|
const {
|
|
627
|
-
minSubfeatureWidth
|
|
736
|
+
minSubfeatureWidth,
|
|
628
737
|
largeInsertionIndicatorScale,
|
|
629
738
|
mismatchAlpha,
|
|
630
739
|
drawSNPs = true,
|
|
631
740
|
drawIndels = true,
|
|
632
741
|
charWidth,
|
|
633
742
|
charHeight,
|
|
743
|
+
colorForBase,
|
|
744
|
+
contrastForBase,
|
|
634
745
|
} = opts
|
|
635
746
|
const { bpPerPx, regions } = props
|
|
636
747
|
const { heightPx, topPx, feature } = feat
|
|
@@ -638,7 +749,7 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
638
749
|
const start = feature.get('start')
|
|
639
750
|
|
|
640
751
|
const pxPerBp = Math.min(1 / bpPerPx, 2)
|
|
641
|
-
const w = Math.max(
|
|
752
|
+
const w = Math.max(minSubfeatureWidth, pxPerBp)
|
|
642
753
|
const mismatches: Mismatch[] = feature.get('mismatches')
|
|
643
754
|
const heightLim = charHeight - 2
|
|
644
755
|
|
|
@@ -667,7 +778,7 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
667
778
|
const mlen = mismatch.length
|
|
668
779
|
const mbase = mismatch.base
|
|
669
780
|
const [leftPx, rightPx] = bpSpanPx(mstart, mstart + mlen, region, bpPerPx)
|
|
670
|
-
const widthPx = Math.max(
|
|
781
|
+
const widthPx = Math.max(minSubfeatureWidth, Math.abs(leftPx - rightPx))
|
|
671
782
|
if (mismatch.type === 'mismatch' && drawSNPs) {
|
|
672
783
|
const baseColor = colorForBase[mismatch.base] || '#888'
|
|
673
784
|
|
|
@@ -677,10 +788,8 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
677
788
|
|
|
678
789
|
if (widthPx >= charWidth && heightPx >= heightLim) {
|
|
679
790
|
// normal SNP coloring
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
mismatch,
|
|
683
|
-
)
|
|
791
|
+
const contrast = contrastForBase[mismatch.base] || 'black'
|
|
792
|
+
ctx.fillStyle = getAlphaColor(contrast, mismatch)
|
|
684
793
|
ctx.fillText(
|
|
685
794
|
mbase,
|
|
686
795
|
leftPx + (widthPx - charWidth) / 2 + 1,
|
|
@@ -692,12 +801,12 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
692
801
|
ctx.fillStyle = baseColor
|
|
693
802
|
ctx.fillRect(leftPx, topPx, widthPx, heightPx)
|
|
694
803
|
const txt = `${mismatch.length}`
|
|
695
|
-
const
|
|
696
|
-
if (widthPx >=
|
|
697
|
-
ctx.fillStyle =
|
|
804
|
+
const rwidth = measureText(txt, 10)
|
|
805
|
+
if (widthPx >= rwidth && heightPx >= heightLim) {
|
|
806
|
+
ctx.fillStyle = contrastForBase.deletion
|
|
698
807
|
ctx.fillText(
|
|
699
808
|
txt,
|
|
700
|
-
leftPx +
|
|
809
|
+
(leftPx + rightPx) / 2 - rwidth / 2,
|
|
701
810
|
topPx + heightPx,
|
|
702
811
|
)
|
|
703
812
|
}
|
|
@@ -705,14 +814,12 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
705
814
|
ctx.fillStyle = 'purple'
|
|
706
815
|
const pos = leftPx + extraHorizontallyFlippedOffset
|
|
707
816
|
const len = +mismatch.base || mismatch.length
|
|
708
|
-
const insW = Math.max(
|
|
817
|
+
const insW = Math.max(minSubfeatureWidth, Math.min(1.2, 1 / bpPerPx))
|
|
709
818
|
if (len < 10) {
|
|
710
819
|
ctx.fillRect(pos, topPx, insW, heightPx)
|
|
711
|
-
if (1 / bpPerPx >= charWidth) {
|
|
820
|
+
if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
|
|
712
821
|
ctx.fillRect(pos - insW, topPx, insW * 3, 1)
|
|
713
822
|
ctx.fillRect(pos - insW, topPx + heightPx - 1, insW * 3, 1)
|
|
714
|
-
}
|
|
715
|
-
if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
|
|
716
823
|
ctx.fillText(`(${mismatch.base})`, pos + 3, topPx + heightPx)
|
|
717
824
|
}
|
|
718
825
|
}
|
|
@@ -720,11 +827,9 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
720
827
|
ctx.fillStyle = mismatch.type === 'hardclip' ? 'red' : 'blue'
|
|
721
828
|
const pos = leftPx + extraHorizontallyFlippedOffset
|
|
722
829
|
ctx.fillRect(pos, topPx, w, heightPx)
|
|
723
|
-
if (1 / bpPerPx >= charWidth) {
|
|
830
|
+
if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
|
|
724
831
|
ctx.fillRect(pos - w, topPx, w * 3, 1)
|
|
725
832
|
ctx.fillRect(pos - w, topPx + heightPx - 1, w * 3, 1)
|
|
726
|
-
}
|
|
727
|
-
if (widthPx >= charWidth && heightPx >= heightLim) {
|
|
728
833
|
ctx.fillText(`(${mismatch.base})`, pos + 3, topPx + heightPx)
|
|
729
834
|
}
|
|
730
835
|
} else if (mismatch.type === 'skip') {
|
|
@@ -865,6 +970,7 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
865
970
|
|
|
866
971
|
const theme = createJBrowseTheme(configTheme)
|
|
867
972
|
const colorForBase = getColorBaseMap(theme)
|
|
973
|
+
const contrastForBase = getContrastBaseMap(theme)
|
|
868
974
|
if (!layout) {
|
|
869
975
|
throw new Error(`layout required`)
|
|
870
976
|
}
|
|
@@ -882,8 +988,12 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
882
988
|
this.drawAlignmentRect(ctx, feat, {
|
|
883
989
|
...props,
|
|
884
990
|
defaultColor,
|
|
991
|
+
colorForBase,
|
|
992
|
+
contrastForBase,
|
|
993
|
+
charWidth,
|
|
994
|
+
charHeight,
|
|
885
995
|
})
|
|
886
|
-
this.drawMismatches(ctx, feat, props,
|
|
996
|
+
this.drawMismatches(ctx, feat, props, {
|
|
887
997
|
mismatchAlpha,
|
|
888
998
|
drawSNPs: shouldDrawMismatches(colorBy?.type),
|
|
889
999
|
drawIndels: shouldDrawMismatches(colorBy?.type),
|
|
@@ -891,6 +1001,8 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
891
1001
|
minSubfeatureWidth,
|
|
892
1002
|
charWidth,
|
|
893
1003
|
charHeight,
|
|
1004
|
+
colorForBase,
|
|
1005
|
+
contrastForBase,
|
|
894
1006
|
})
|
|
895
1007
|
if (showSoftClip) {
|
|
896
1008
|
this.drawSoftClipping(ctx, feat, props, config, theme)
|
|
@@ -942,34 +1054,40 @@ export default class PileupRenderer extends BoxRendererType {
|
|
|
942
1054
|
return layoutRecords
|
|
943
1055
|
}
|
|
944
1056
|
|
|
945
|
-
async
|
|
946
|
-
const { sessionId,
|
|
1057
|
+
async fetchSequence(renderProps: RenderArgsDeserialized) {
|
|
1058
|
+
const { sessionId, regions, adapterConfig } = renderProps
|
|
947
1059
|
const { sequenceAdapter } = adapterConfig
|
|
1060
|
+
if (!sequenceAdapter) {
|
|
1061
|
+
return undefined
|
|
1062
|
+
}
|
|
1063
|
+
const { dataAdapter } = await getAdapter(
|
|
1064
|
+
this.pluginManager,
|
|
1065
|
+
sessionId,
|
|
1066
|
+
sequenceAdapter,
|
|
1067
|
+
)
|
|
1068
|
+
const [region] = regions
|
|
1069
|
+
return fetchSequence(region, dataAdapter as BaseFeatureDataAdapter)
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
async render(renderProps: RenderArgsDeserialized) {
|
|
948
1073
|
const features = await this.getFeatures(renderProps)
|
|
949
1074
|
const layout = this.createLayoutInWorker(renderProps)
|
|
1075
|
+
const { regions, bpPerPx } = renderProps
|
|
950
1076
|
|
|
951
|
-
const layoutRecords = this.layoutFeats({
|
|
1077
|
+
const layoutRecords = this.layoutFeats({
|
|
1078
|
+
...renderProps,
|
|
1079
|
+
features,
|
|
1080
|
+
layout,
|
|
1081
|
+
})
|
|
952
1082
|
const [region] = regions
|
|
953
|
-
let regionSequence: string | undefined
|
|
954
|
-
const { end, start, originalRefName, refName } = region
|
|
955
|
-
|
|
956
|
-
if (sequenceAdapter) {
|
|
957
|
-
const { dataAdapter } = await getAdapter(
|
|
958
|
-
this.pluginManager,
|
|
959
|
-
sessionId,
|
|
960
|
-
sequenceAdapter,
|
|
961
|
-
)
|
|
962
1083
|
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
.toPromise()
|
|
971
|
-
regionSequence = feats[0]?.get('seq')
|
|
972
|
-
}
|
|
1084
|
+
// only need reference sequence if there are features and only for some
|
|
1085
|
+
// cases
|
|
1086
|
+
const regionSequence =
|
|
1087
|
+
features.size && shouldFetchReferenceSequence(renderProps.colorBy?.type)
|
|
1088
|
+
? await this.fetchSequence(renderProps)
|
|
1089
|
+
: undefined
|
|
1090
|
+
const { end, start } = region
|
|
973
1091
|
|
|
974
1092
|
const width = (end - start) / bpPerPx
|
|
975
1093
|
const height = Math.max(layout.getTotalHeight(), 1)
|