Skip to content

Commit

Permalink
Improve visibility of SNPs on alignments track (#3534)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Mar 14, 2023
1 parent 9b8fcc9 commit d8d65aa
Show file tree
Hide file tree
Showing 26 changed files with 296 additions and 287 deletions.
10 changes: 5 additions & 5 deletions packages/core/ui/theme.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { blue, green, red, grey, amber } from '@mui/material/colors'
import { blue, green, red, grey, orange } from '@mui/material/colors'
import { createTheme, ThemeOptions } from '@mui/material/styles'
import type { PaletteAugmentColorOptions } from '@mui/material/styles/createPalette'
import deepmerge from 'deepmerge'
Expand Down Expand Up @@ -50,7 +50,7 @@ function stockTheme() {
bases: {
A: refTheme.palette.augmentColor({ color: green }),
C: refTheme.palette.augmentColor({ color: blue }),
G: refTheme.palette.augmentColor({ color: amber }),
G: refTheme.palette.augmentColor({ color: orange }),
T: refTheme.palette.augmentColor({ color: red }),
},
},
Expand Down Expand Up @@ -98,7 +98,7 @@ function getDarkStockTheme() {
bases: {
A: refTheme.palette.augmentColor({ color: green }),
C: refTheme.palette.augmentColor({ color: blue }),
G: refTheme.palette.augmentColor({ color: amber }),
G: refTheme.palette.augmentColor({ color: orange }),
T: refTheme.palette.augmentColor({ color: red }),
},
},
Expand Down Expand Up @@ -132,7 +132,7 @@ function getDarkMinimalTheme() {
bases: {
A: refTheme.palette.augmentColor({ color: green }),
C: refTheme.palette.augmentColor({ color: blue }),
G: refTheme.palette.augmentColor({ color: amber }),
G: refTheme.palette.augmentColor({ color: orange }),
T: refTheme.palette.augmentColor({ color: red }),
},
},
Expand All @@ -152,7 +152,7 @@ function getMinimalTheme() {
bases: {
A: refTheme.palette.augmentColor({ color: green }),
C: refTheme.palette.augmentColor({ color: blue }),
G: refTheme.palette.augmentColor({ color: amber }),
G: refTheme.palette.augmentColor({ color: orange }),
T: refTheme.palette.augmentColor({ color: red }),
},
},
Expand Down
28 changes: 12 additions & 16 deletions plugins/alignments/src/PileupRenderer/PileupRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,10 @@ export default class PileupRenderer extends BoxRendererType {
}
}
}
const s = feature.get('start') - expansionBefore
const e = feature.get('end') + expansionAfter

const [leftPx, rightPx] = bpSpanPx(
feature.get('start') - expansionBefore,
feature.get('end') + expansionAfter,
region,
bpPerPx,
)
const [leftPx, rightPx] = bpSpanPx(s, e, region, bpPerPx)

if (displayMode === 'compact') {
heightPx /= 3
Expand All @@ -202,13 +199,7 @@ export default class PileupRenderer extends BoxRendererType {
}`,
)
}
const topPx = layout.addRect(
feature.id(),
feature.get('start') - expansionBefore,
feature.get('end') + expansionAfter,
heightPx,
feature,
)
const topPx = layout.addRect(feature.id(), s, e, heightPx, feature)
if (topPx === null) {
return null
}
Expand Down Expand Up @@ -652,6 +643,7 @@ export default class PileupRenderer extends BoxRendererType {
charWidth,
charHeight,
defaultColor,
theme,
canvasWidth,
}: {
ctx: CanvasRenderingContext2D
Expand All @@ -663,9 +655,9 @@ export default class PileupRenderer extends BoxRendererType {
charHeight: number
defaultColor: boolean
canvasWidth: number
theme: Theme
}) {
const { config, bpPerPx, regions, colorBy, colorTagMap = {} } = renderArgs

const { tag = '', type: colorType = '' } = colorBy || {}
const { feature } = feat
const region = regions[0]
Expand Down Expand Up @@ -741,7 +733,7 @@ export default class PileupRenderer extends BoxRendererType {

default: {
ctx.fillStyle = defaultColor
? '#c8c8c8'
? 'lightgrey'
: readConfObject(config, 'color', { feature })
break
}
Expand Down Expand Up @@ -814,6 +806,7 @@ export default class PileupRenderer extends BoxRendererType {
canvasWidth,
drawSNPsMuted,
drawIndels = true,
theme,
}: {
ctx: CanvasRenderingContext2D
feat: LayoutFeature
Expand All @@ -828,6 +821,7 @@ export default class PileupRenderer extends BoxRendererType {
charWidth: number
charHeight: number
canvasWidth: number
theme: Theme
}) {
const { Color, bpPerPx, regions } = renderArgs
const { heightPx, topPx, feature } = feat
Expand Down Expand Up @@ -864,7 +858,7 @@ export default class PileupRenderer extends BoxRendererType {

fillRect(
ctx,
leftPx,
Math.round(leftPx),
topPx,
widthPx,
heightPx,
Expand Down Expand Up @@ -1155,6 +1149,7 @@ export default class PileupRenderer extends BoxRendererType {
charWidth,
charHeight,
canvasWidth,
theme,
})
this.drawMismatches({
ctx,
Expand All @@ -1170,6 +1165,7 @@ export default class PileupRenderer extends BoxRendererType {
colorForBase,
contrastForBase,
canvasWidth,
theme,
})
if (showSoftClip) {
this.drawSoftClipping({
Expand Down
2 changes: 1 addition & 1 deletion plugins/alignments/src/PileupRenderer/configSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const PileupRenderer = ConfigurationSchema(
type: 'number',
description:
'the minimum width in px for a pileup mismatch feature. use for increasing/decreasing mismatch marker widths when zoomed out, e.g. 0 or 1',
defaultValue: 0.7,
defaultValue: 1,
},
/**
* #slot
Expand Down
27 changes: 14 additions & 13 deletions plugins/alignments/src/SNPCoverageRenderer/SNPCoverageRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ interface SNPInfo {
total: number
}

const fudgeFactor = 0.6

export default class SNPCoverageRenderer extends WiggleBaseRenderer {
// note: the snps are drawn on linear scale even if the data is drawn in log
// scape hence the two different scales being used
Expand Down Expand Up @@ -78,6 +80,7 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
scaleType: 'linear',
})
const originY = getOrigin(scaleOpts.scaleType)
const originLinear = getOrigin('linear')

const indicatorThreshold = readConfObject(cfg, 'indicatorThreshold')
const drawInterbaseCounts = readConfObject(cfg, 'drawInterbaseCounts')
Expand All @@ -87,11 +90,9 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
// get the y coordinate that we are plotting at, this can be log scale
const toY = (n: number) => height - (viewScale(n) || 0) + offset
const toHeight = (n: number) => toY(originY) - toY(n)

const indicatorToY = (n: number) =>
height - (indicatorViewScale(n) || 0) + offset
const indicatorToHeight = (n: number) =>
indicatorToY(getOrigin('linear')) - indicatorToY(n)
// used specifically for indicator
const toY2 = (n: number) => height - (indicatorViewScale(n) || 0) + offset
const toHeight2 = (n: number) => toY2(originLinear) - toY2(n)

const { bases } = theme.palette
const colorForBase: { [key: string]: string } = {
Expand All @@ -105,7 +106,6 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
hardclip: 'red',
meth: 'red',
unmeth: 'blue',
ref: 'lightgrey',
}

const feats = [...features.values()]
Expand All @@ -118,7 +118,7 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
for (let i = 0; i < coverage.length; i++) {
const feature = coverage[i]
const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx)
const w = rightPx - leftPx + 0.3
const w = rightPx - leftPx + fudgeFactor
const score = feature.get('score') as number
ctx.fillRect(leftPx, toY(score), w, toHeight(score))
}
Expand All @@ -144,7 +144,7 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {

const score = feature.get('score') as number
const snpinfo = feature.get('snpinfo') as SNPInfo
const w = Math.max(rightPx - leftPx + 0.3, 1)
const w = Math.max(rightPx - leftPx + fudgeFactor, 1)
const totalScore = snpinfo.total
const keys = Object.keys(snpinfo.cov).sort()

Expand All @@ -160,7 +160,7 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
const height = toHeight(score)
const bottom = toY(score) + height
ctx.fillRect(
leftPx,
Math.round(leftPx),
bottom - ((total + curr) / score) * height,
w,
(total / score) * height,
Expand All @@ -175,12 +175,13 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
for (let i = 0; i < interbaseEvents.length; i++) {
const base = interbaseEvents[i]
const { total } = snpinfo.noncov[base]
const r = 0.6
ctx.fillStyle = colorForBase[base]
ctx.fillRect(
leftPx - 0.6 + extraHorizontallyFlippedOffset,
indicatorHeight + indicatorToHeight(curr),
1.2,
indicatorToHeight(total),
leftPx - r + extraHorizontallyFlippedOffset,
indicatorHeight + toHeight2(curr),
r * 2,
toHeight2(total),
)
curr += total
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1571,7 +1571,7 @@ exports[`ConfigurationEditor widget renders with defaults of the PileupTrack sch
class="MuiInputBase-input MuiOutlinedInput-input css-1t8l2tu-MuiInputBase-input-MuiOutlinedInput-input"
id="mui-21"
type="number"
value="0.7"
value="1"
/>
<fieldset
aria-hidden="true"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import React from 'react'
import { AnyConfigurationModel } from '@jbrowse/core/configuration'
import { contrastingTextColor } from '@jbrowse/core/util/color'
import { Feature } from '@jbrowse/core/util'
import { Region } from '@jbrowse/core/util/types'
import { createJBrowseTheme } from '@jbrowse/core/ui'
import { observer } from 'mobx-react'
import {
Feature,
Region,
bpSpanPx,
revcom,
complement,
Expand All @@ -15,17 +14,18 @@ import {
defaultCodonTable,
generateCodonTable,
} from '@jbrowse/core/util'
import { Theme } from '@mui/material'

function Translation(props: {
codonTable: any
codonTable: Record<string, string>
seq: string
frame: number
bpPerPx: number
region: Region
reverse?: boolean
height: number
y: number
theme?: any
theme?: Theme
}) {
const {
codonTable,
Expand Down Expand Up @@ -84,9 +84,9 @@ function Translation(props: {
stroke={render ? '#555' : 'none'}
fill={
defaultStarts.includes(codon)
? theme.palette.startCodon
? theme?.palette.startCodon
: defaultStops.includes(codon)
? theme.palette.stopCodon
? theme?.palette.stopCodon
: map[Math.abs(frame)]
}
/>
Expand Down Expand Up @@ -150,7 +150,9 @@ function DNA(props: {
y={y + height / 2}
dominantBaseline="middle"
textAnchor="middle"
fill={color ? contrastingTextColor(color.main) : 'black'}
fill={
color ? theme.palette.getContrastText(color.main) : 'black'
}
>
{letter}
</text>
Expand Down Expand Up @@ -255,7 +257,17 @@ const SequenceSVG = ({
)
}

const Wrapper = ({ exportSVG, width, totalHeight, children }: any) => {
const Wrapper = ({
exportSVG,
width,
totalHeight,
children,
}: {
exportSVG?: { rasterizeLayers: boolean }
width: number
totalHeight: number
children: React.ReactNode
}) => {
return exportSVG ? (
<>{children}</>
) : (
Expand Down
Loading

0 comments on commit d8d65aa

Please sign in to comment.