Skip to content

Commit

Permalink
Reduce some readConfObject calls
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Nov 16, 2021
1 parent 3e6a202 commit e35e33c
Showing 1 changed file with 48 additions and 56 deletions.
104 changes: 48 additions & 56 deletions plugins/alignments/src/PileupRenderer/PileupRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -596,21 +596,25 @@ export default class PileupRenderer extends BoxRendererType {
mismatchAlpha?: boolean
drawSNPs?: boolean
drawIndels?: boolean
minSubfeatureWidth: number
largeInsertionIndicatorScale: number
},
) {
const { mismatchAlpha, drawSNPs = true, drawIndels = true } = opts
const { config, bpPerPx, regions } = props
const {
minSubfeatureWidth: minWidth,
largeInsertionIndicatorScale,
mismatchAlpha,
drawSNPs = true,
drawIndels = true,
} = opts
const { bpPerPx, regions } = props
const { heightPx, topPx, feature } = feat
const { charWidth, charHeight } = this.getCharWidthHeight(ctx)
const [region] = regions
const start = feature.get('start')
const minFeatWidth = readConfObject(config, 'minSubfeatureWidth')
const insertionScale = readConfObject(
config,
'largeInsertionIndicatorScale',
)

const pxPerBp = Math.min(1 / bpPerPx, 2)
const w = Math.max(minFeatWidth, pxPerBp)
const w = Math.max(minWidth, pxPerBp)
const mismatches: Mismatch[] = feature.get('mismatches')
const heightLim = charHeight - 2

Expand All @@ -629,50 +633,45 @@ export default class PileupRenderer extends BoxRendererType {
// insertion markers
for (let i = 0; i < mismatches.length; i += 1) {
const mismatch = mismatches[i]
const [mismatchLeftPx, mismatchRightPx] = bpSpanPx(
start + mismatch.start,
start + mismatch.start + mismatch.length,
region,
bpPerPx,
)
const mismatchWidthPx = Math.max(
minFeatWidth,
Math.abs(mismatchLeftPx - mismatchRightPx),
)
const mstart = start + mismatch.start
const mlen = mismatch.length
const mbase = mismatch.base
const [leftPx, rightPx] = bpSpanPx(mstart, mstart + mlen, region, bpPerPx)
const widthPx = Math.max(minWidth, Math.abs(leftPx - rightPx))
if (mismatch.type === 'mismatch' && drawSNPs) {
const baseColor = colorForBase[mismatch.base] || '#888'

ctx.fillStyle = getAlphaColor(baseColor, mismatch)

ctx.fillRect(mismatchLeftPx, topPx, mismatchWidthPx, heightPx)
ctx.fillRect(leftPx, topPx, widthPx, heightPx)

if (mismatchWidthPx >= charWidth && heightPx >= heightLim) {
if (widthPx >= charWidth && heightPx >= heightLim) {
// normal SNP coloring
ctx.fillStyle = getAlphaColor(
theme.palette.getContrastText(baseColor),
mismatch,
)
ctx.fillText(
mismatch.base,
mismatchLeftPx + (mismatchWidthPx - charWidth) / 2 + 1,
mbase,
leftPx + (widthPx - charWidth) / 2 + 1,
topPx + heightPx,
)
}
} else if (mismatch.type === 'deletion' && drawIndels) {
const baseColor = colorForBase.deletion
ctx.fillStyle = baseColor
ctx.fillRect(mismatchLeftPx, topPx, mismatchWidthPx, heightPx)
if (mismatchWidthPx >= charWidth && heightPx >= heightLim) {
ctx.fillRect(leftPx, topPx, widthPx, heightPx)
if (widthPx >= charWidth && heightPx >= heightLim) {
ctx.fillStyle = theme.palette.getContrastText(baseColor)
ctx.fillText(
mismatch.base,
mismatchLeftPx + (mismatchWidthPx - charWidth) / 2 + 1,
mbase,
leftPx + (widthPx - charWidth) / 2 + 1,
topPx + heightPx,
)
}
} else if (mismatch.type === 'insertion' && drawIndels) {
ctx.fillStyle = 'purple'
const pos = mismatchLeftPx - 1
const pos = leftPx - 1
const len = +mismatch.base || mismatch.length
if (len < 10) {
ctx.fillRect(pos, topPx, w, heightPx)
Expand All @@ -681,76 +680,65 @@ export default class PileupRenderer extends BoxRendererType {
ctx.fillRect(pos - w, topPx + heightPx - 1, w * 3, 1)
}
if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
ctx.fillText(
`(${mismatch.base})`,
mismatchLeftPx + 2,
topPx + heightPx,
)
ctx.fillText(`(${mismatch.base})`, leftPx + 2, topPx + heightPx)
}
}
} else if (mismatch.type === 'hardclip' || mismatch.type === 'softclip') {
ctx.fillStyle = mismatch.type === 'hardclip' ? 'red' : 'blue'
const pos = mismatchLeftPx - 1
const pos = leftPx - 1
ctx.fillRect(pos, topPx + 1, w, heightPx - 2)
ctx.fillRect(pos - w, topPx, w * 3, 1)
ctx.fillRect(pos - w, topPx + heightPx - 1, w * 3, 1)
if (mismatchWidthPx >= charWidth && heightPx >= heightLim) {
ctx.fillText(
`(${mismatch.base})`,
mismatchLeftPx + 2,
topPx + heightPx,
)
if (widthPx >= charWidth && heightPx >= heightLim) {
ctx.fillText(`(${mismatch.base})`, leftPx + 2, topPx + heightPx)
}
} else if (mismatch.type === 'skip') {
// fix to avoid bad rendering
// note that this was also related to chrome bug https://bugs.chromium.org/p/chro>
// ref #1236
if (mismatchLeftPx + mismatchWidthPx > 0) {
if (leftPx + widthPx > 0) {
// make small exons more visible when zoomed far out
ctx.clearRect(
mismatchLeftPx,
leftPx,
topPx,
// make small exons more visible when zoomed far out
mismatchWidthPx - (bpPerPx > 10 ? 1.5 : 0),
widthPx - (bpPerPx > 10 ? 1.5 : 0),
heightPx,
)
}
ctx.fillStyle = '#333'
ctx.fillRect(mismatchLeftPx, topPx + heightPx / 2, mismatchWidthPx, 2)
ctx.fillRect(leftPx, topPx + heightPx / 2, widthPx, 2)
}
}

// second pass, draw wide insertion markers on top
if (drawIndels) {
for (let i = 0; i < mismatches.length; i += 1) {
const mismatch = mismatches[i]
const [mismatchLeftPx] = bpSpanPx(
feature.get('start') + mismatch.start,
feature.get('start') + mismatch.start + mismatch.length,
region,
bpPerPx,
)
const mstart = start + mismatch.start
const mlen = mismatch.length
const [leftPx] = bpSpanPx(mstart, mstart + mlen, region, bpPerPx)
const len = +mismatch.base || mismatch.length
const txt = `${len}`
if (mismatch.type === 'insertion' && len >= 10) {
if (bpPerPx > insertionScale) {
if (bpPerPx > largeInsertionIndicatorScale) {
ctx.fillStyle = 'purple'
ctx.fillRect(mismatchLeftPx - 1, topPx, 2, heightPx)
ctx.fillRect(leftPx - 1, topPx, 2, heightPx)
} else if (heightPx > charHeight) {
const rect = ctx.measureText(txt)
const padding = 5
ctx.fillStyle = 'purple'
ctx.fillRect(
mismatchLeftPx - rect.width / 2 - padding,
leftPx - rect.width / 2 - padding,
topPx,
rect.width + 2 * padding,
heightPx,
)
ctx.fillStyle = 'white'
ctx.fillText(txt, mismatchLeftPx - rect.width / 2, topPx + heightPx)
ctx.fillText(txt, leftPx - rect.width / 2, topPx + heightPx)
} else {
const padding = 2
ctx.fillStyle = 'purple'
ctx.fillRect(mismatchLeftPx - padding, topPx, 2 * padding, heightPx)
ctx.fillRect(leftPx - padding, topPx, 2 * padding, heightPx)
}
}
}
Expand Down Expand Up @@ -836,6 +824,9 @@ export default class PileupRenderer extends BoxRendererType {
) {
const { layout, config, showSoftClip, colorBy, theme: configTheme } = props
const mismatchAlpha = readConfObject(config, 'mismatchAlpha')
const minSubfeatureWidth = readConfObject(config, 'minSubfeatureWidth')
const insertScale = readConfObject(config, 'largeInsertionIndicatorScale')

const theme = createJBrowseTheme(configTheme)
const colorForBase = getColorBaseMap(theme)
if (!layout) {
Expand All @@ -857,9 +848,10 @@ export default class PileupRenderer extends BoxRendererType {
this.drawAlignmentRect(ctx, { feature, topPx, heightPx }, props)
this.drawMismatches(ctx, feat, props, theme, colorForBase, {
mismatchAlpha,

drawSNPs: shouldDrawMismatches(colorBy?.type),
drawIndels: shouldDrawMismatches(colorBy?.type),
largeInsertionIndicatorScale: insertScale,
minSubfeatureWidth,
})
if (showSoftClip) {
this.drawSoftClipping(ctx, feat, props, config, theme)
Expand Down

0 comments on commit e35e33c

Please sign in to comment.