diff --git a/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts b/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts index 90fbdb57e5..fae674fc81 100644 --- a/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts +++ b/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts @@ -1,7 +1,12 @@ import deepEqual from 'fast-deep-equal' + +// layouts import GranularRectLayout from '../../util/layouts/GranularRectLayout' import MultiLayout from '../../util/layouts/MultiLayout' +import { SerializedLayout, BaseLayout } from '../../util/layouts/BaseLayout' import PrecomputedLayout from '../../util/layouts/PrecomputedLayout' + +// other import FeatureRendererType, { RenderArgs as FeatureRenderArgs, RenderArgsSerialized as FeatureRenderArgsSerialized, @@ -11,7 +16,6 @@ import FeatureRendererType, { ResultsDeserialized as FeatureResultsDeserialized, } from './FeatureRendererType' import { getLayoutId, Region, Feature } from '../../util' -import { SerializedLayout, BaseLayout } from '../../util/layouts/BaseLayout' import { readConfObject, AnyConfigurationModel } from '../../configuration' import SerializableFilterChain from './util/serializableFilterChain' import RpcManager from '../../rpc/RpcManager' diff --git a/packages/core/util/layouts/GranularRectLayout.ts b/packages/core/util/layouts/GranularRectLayout.ts index 340395baa0..b94193f08e 100644 --- a/packages/core/util/layouts/GranularRectLayout.ts +++ b/packages/core/util/layouts/GranularRectLayout.ts @@ -34,30 +34,19 @@ interface RowState { } // a single row in the layout class LayoutRow { - private padding: number + private padding = 1 private allFilled?: Record | string - private widthLimit: number + private widthLimit = 1_000_000 private rowState?: RowState - constructor() { - this.padding = 1 - this.widthLimit = 1000000 - - // this.rowState.offset is the offset of the bits array relative to the genomic coordinates - // (modified by pitchX, but we don't know that in this class) - // this.rowState.bits is the array of items in the layout row, indexed by (x - this.offset) - // this.rowState.min is the leftmost edge of all the rectangles we have in the layout - // this.rowState.max is the rightmost edge of all the rectangles we have in the layout - } - - // log(msg: string): void { - // // if (this.rowNumber === 0) - // // eslint-disable-next-line no-console - // console.log(`r${this.rowNumber}: ${msg}`) - // } + // this.rowState.bits is the array of items in the layout row, indexed by (x - this.offset) + // this.rowState.min is the leftmost edge of all the rectangles we have in the layout + // this.rowState.max is the rightmost edge of all the rectangles we have in the layout + // this.rowState.offset is the offset of the bits array relative to the genomic coordinates + // (modified by pitchX, but we don't know that in this class) setAllFilled(data: Record | string): void { this.allFilled = data @@ -67,56 +56,42 @@ class LayoutRow { if (this.allFilled) { return this.allFilled } - if (!this.rowState) { - return undefined - } - - if (this.rowState.min === undefined) { - return undefined - } - if (x < this.rowState.min) { - return undefined - } - if (x >= this.rowState.max) { + if ( + this.rowState?.min === undefined || + x < this.rowState.min || + x >= this.rowState.max + ) { return undefined } - const offset = x - this.rowState.offset - // if (offset < 0) - // debugger - // if (offset >= this.rowState.bits.length) - // debugger - return this.rowState.bits[offset] + return this.rowState.bits[x - this.rowState.offset] } - isRangeClear(left: number, right: number): boolean { + isRangeClear(left: number, right: number) { if (this.allFilled) { return false } - if (!this.rowState) { - return true - } - - const { min, max } = this.rowState - - if (right <= min || left >= max) { + if ( + this.rowState === undefined || + right <= this.rowState.min || + left >= this.rowState.max + ) { return true } + const { min, max, offset, bits } = this.rowState - // TODO: check right and middle before looping - const maxX = Math.min(max, right) - let x = Math.max(min, left) - for (; x < right && x < maxX; x += 1) { - if (this.getItemAt(x)) { - return false - } + const maxX = Math.min(max, right) - offset + let flag = true + for (let x = Math.max(min, left) - offset; x < maxX && flag; x++) { + flag = bits[x] === undefined } - return true + return flag } + // NOTE: this.rowState.min, this.rowState.max, and this.rowState.offset are + // interbase coordinates initialize(left: number, right: number): RowState { - // NOTE: this.rowState.min, this.rowState.max, and this.rowState.offset are interbase coordinates const rectWidth = right - left return { offset: left - rectWidth, @@ -124,7 +99,6 @@ class LayoutRow { max: right, bits: new Array(3 * rectWidth), } - // this.log(`initialize ${this.rowState.min} - ${this.rowState.max} (${this.rowState.bits.length})`) } addRect(rect: Rectangle, data: Record | string): void { @@ -415,13 +389,13 @@ export default class GranularRectLayout implements BaseLayout { return top * this.pitchY } - collides(rect: Rectangle, top: number): boolean { + collides(rect: Rectangle, top: number) { const { bitmap } = this const maxY = top + rect.h for (let y = top; y < maxY; y += 1) { const row = bitmap[y] - if (row && !row.isRangeClear(rect.l, rect.r)) { + if (row !== undefined && !row.isRangeClear(rect.l, rect.r)) { return true } } @@ -432,7 +406,7 @@ export default class GranularRectLayout implements BaseLayout { /** * make a subarray if it does not exist */ - private autovivifyRow(bitmap: LayoutRow[], y: number): LayoutRow { + private autovivifyRow(bitmap: LayoutRow[], y: number) { let row = bitmap[y] if (!row) { if (y > this.hardRowLimit) { @@ -448,7 +422,7 @@ export default class GranularRectLayout implements BaseLayout { return row } - addRectToBitmap(rect: Rectangle): void { + addRectToBitmap(rect: Rectangle) { if (rect.top === null) { return } @@ -475,7 +449,7 @@ export default class GranularRectLayout implements BaseLayout { * Given a range of X coordinates, deletes all data dealing with * the features. */ - discardRange(left: number, right: number): void { + discardRange(left: number, right: number) { // console.log( 'discard', left, right ); const pLeft = Math.floor(left / this.pitchX) const pRight = Math.floor(right / this.pitchX) @@ -488,11 +462,11 @@ export default class GranularRectLayout implements BaseLayout { } } - hasSeen(id: string): boolean { + hasSeen(id: string) { return this.rectangles.has(id) } - getByCoord(x: number, y: number): Record | string | undefined { + getByCoord(x: number, y: number) { const pY = Math.floor(y / this.pitchY) const row = this.bitmap[pY] if (!row) { @@ -502,23 +476,28 @@ export default class GranularRectLayout implements BaseLayout { return row.getItemAt(pX) } - getByID(id: string): RectTuple | undefined { + getByID(id: string) { const r = this.rectangles.get(id) if (r) { const t = (r.top as number) * this.pitchY - return [r.l * this.pitchX, t, r.r * this.pitchX, t + r.originalHeight] + return [ + r.l * this.pitchX, + t, + r.r * this.pitchX, + t + r.originalHeight, + ] as RectTuple } return undefined } - getDataByID(id: string): unknown { + getDataByID(id: string) { return this.rectangles.get(id)?.data } - cleanup(): void {} + cleanup() {} - getTotalHeight(): number { + getTotalHeight() { return this.pTotalHeight * this.pitchY } diff --git a/packages/core/util/layouts/MultiLayout.ts b/packages/core/util/layouts/MultiLayout.ts index 7c037871f1..f8c87066ff 100644 --- a/packages/core/util/layouts/MultiLayout.ts +++ b/packages/core/util/layouts/MultiLayout.ts @@ -4,8 +4,6 @@ import { BaseLayout, SerializedLayout } from './BaseLayout' export default class MultiLayout, T> { subLayouts: Map = new Map() - subLayoutConstructorArgs: Record = {} - /** * layout class that just keeps a number of named sub-layouts. * basically just a fancier @@ -13,11 +11,8 @@ export default class MultiLayout, T> { */ constructor( public SubLayoutClass: new (...args: any[]) => SUB_LAYOUT_CLASS, - layoutArgs: Record = {}, - ) { - this.subLayouts = new Map() - this.subLayoutConstructorArgs = layoutArgs - } + public subLayoutConstructorArgs: Record = {}, + ) {} getDataByID(id: string): unknown { for (const layout of this.subLayouts.values()) { @@ -53,8 +48,7 @@ export default class MultiLayout, T> { } discardRange(layoutName: string, left: number, right: number) { - const layout = this.subLayouts.get(layoutName) - return layout && layout.discardRange(left, right) + return this.subLayouts.get(layoutName)?.discardRange(left, right) } toJSON() { diff --git a/plugins/alignments/src/BamAdapter/BamAdapter.ts b/plugins/alignments/src/BamAdapter/BamAdapter.ts index 7e312345df..d35c2107d0 100644 --- a/plugins/alignments/src/BamAdapter/BamAdapter.ts +++ b/plugins/alignments/src/BamAdapter/BamAdapter.ts @@ -9,7 +9,6 @@ import { openLocation } from '@jbrowse/core/util/io' import { ObservableCreate } from '@jbrowse/core/util/rxjs' import { Feature } from '@jbrowse/core/util/simpleFeature' import { toArray } from 'rxjs/operators' -import { readConfObject } from '@jbrowse/core/configuration' import BamSlightlyLazyFeature from './BamSlightlyLazyFeature' interface Header { @@ -21,51 +20,52 @@ export default class BamAdapter extends BaseFeatureDataAdapter { private samHeader?: Header private setupP?: Promise
- - protected configured?: Promise<{ + private configureP?: Promise<{ bam: BamFile sequenceAdapter?: BaseFeatureDataAdapter }> // derived classes may not use the same configuration so a custom // configure method allows derived classes to override this behavior - protected async configure() { - if (!this.configured) { - const bamLocation = readConfObject(this.config, 'bamLocation') - const location = readConfObject(this.config, ['index', 'location']) - const indexType = readConfObject(this.config, ['index', 'indexType']) - const bam = new BamFile({ - bamFilehandle: openLocation(bamLocation, this.pluginManager), - csiFilehandle: - indexType === 'CSI' - ? openLocation(location, this.pluginManager) - : undefined, - baiFilehandle: - indexType !== 'CSI' - ? openLocation(location, this.pluginManager) - : undefined, - - // chunkSizeLimit and fetchSizeLimit are more troublesome than - // helpful, and have given overly large values on the ultra long - // nanopore reads even with 500MB limits, so disabled with infinity - chunkSizeLimit: Infinity, - fetchSizeLimit: Infinity, - yieldThreadTime: Infinity, - }) + protected async configurePre() { + const bamLocation = this.getConf('bamLocation') + const location = this.getConf(['index', 'location']) + const indexType = this.getConf(['index', 'indexType']) + const pm = this.pluginManager + const csi = indexType === 'CSI' + const bam = new BamFile({ + bamFilehandle: openLocation(bamLocation, pm), + csiFilehandle: csi ? openLocation(location, pm) : undefined, + baiFilehandle: !csi ? openLocation(location, pm) : undefined, + + // chunkSizeLimit and fetchSizeLimit are more troublesome than + // helpful, and have given overly large values on the ultra long + // nanopore reads even with 500MB limits, so disabled with infinity + chunkSizeLimit: Infinity, + fetchSizeLimit: Infinity, + yieldThreadTime: Infinity, + }) - const adapterConfig = readConfObject(this.config, 'sequenceAdapter') - if (adapterConfig && this.getSubAdapter) { - this.configured = this.getSubAdapter(adapterConfig).then( - ({ dataAdapter }) => ({ - bam, - sequenceAdapter: dataAdapter as BaseFeatureDataAdapter, - }), - ) - } else { - this.configured = Promise.resolve({ bam }) + const adapterConfig = this.getConf('sequenceAdapter') + if (adapterConfig && this.getSubAdapter) { + const { dataAdapter } = await this.getSubAdapter(adapterConfig) + return { + bam, + sequenceAdapter: dataAdapter as BaseFeatureDataAdapter, } + } else { + return { bam } + } + } + + protected async configure() { + if (!this.configureP) { + this.configureP = this.configurePre().catch(e => { + this.configureP = undefined + throw e + }) } - return this.configured + return this.configureP } async getHeader(opts?: BaseOptions) { @@ -231,7 +231,7 @@ export default class BamAdapter extends BaseFeatureDataAdapter { // @ts-ignore if (bam.index.filehandle !== '?') { const bytes = await bytesForRegions(regions, bam) - const fetchSizeLimit = readConfObject(this.config, 'fetchSizeLimit') + const fetchSizeLimit = this.getConf('fetchSizeLimit') return { bytes, fetchSizeLimit } } else { return super.estimateRegionsStats(regions, opts) @@ -241,7 +241,7 @@ export default class BamAdapter extends BaseFeatureDataAdapter { freeResources(/* { region } */): void {} // depends on setup being called before the BAM constructor - refIdToName(refId: number): string | undefined { + refIdToName(refId: number) { return this.samHeader?.idToName[refId] } } diff --git a/plugins/alignments/src/CramAdapter/CramAdapter.ts b/plugins/alignments/src/CramAdapter/CramAdapter.ts index 8f94becaeb..59d4a43154 100644 --- a/plugins/alignments/src/CramAdapter/CramAdapter.ts +++ b/plugins/alignments/src/CramAdapter/CramAdapter.ts @@ -2,6 +2,7 @@ import { CraiIndex, IndexedCramFile } from '@gmod/cram' import { BaseFeatureDataAdapter, BaseOptions, + BaseSequenceAdapter, } from '@jbrowse/core/data_adapters/BaseAdapter' import { checkAbortSignal, Region, Feature } from '@jbrowse/core/util' import { openLocation } from '@jbrowse/core/util/io' @@ -33,7 +34,12 @@ export default class CramAdapter extends BaseFeatureDataAdapter { private setupP?: Promise<{ samHeader: Header cram: any // eslint-disable-line @typescript-eslint/no-explicit-any - sequenceAdapter: any // eslint-disable-line @typescript-eslint/no-explicit-any + sequenceAdapter: BaseSequenceAdapter + }> + + private configureP?: Promise<{ + cram: any // eslint-disable-line @typescript-eslint/no-explicit-any + sequenceAdapter: BaseSequenceAdapter }> // maps a refname to an id @@ -42,7 +48,7 @@ export default class CramAdapter extends BaseFeatureDataAdapter { // maps a seqId to original refname, passed specially to render args, to a seqid private seqIdToOriginalRefName: string[] = [] - public async configure() { + public async configurePre() { const cramLocation = this.getConf('cramLocation') const craiLocation = this.getConf('craiLocation') if (!cramLocation) { @@ -51,34 +57,38 @@ export default class CramAdapter extends BaseFeatureDataAdapter { if (!craiLocation) { throw new Error('missing craiLocation argument') } + const pm = this.pluginManager // eslint-disable-next-line @typescript-eslint/no-explicit-any const cram: any = new IndexedCramFile({ - cramFilehandle: openLocation(cramLocation, this.pluginManager), - index: new CraiIndex({ - filehandle: openLocation(craiLocation, this.pluginManager), - }), + cramFilehandle: openLocation(cramLocation, pm), + index: new CraiIndex({ filehandle: openLocation(craiLocation, pm) }), seqFetch: this.seqFetch.bind(this), checkSequenceMD5: false, fetchSizeLimit: 200_000_000, // just make this a large size to avoid hitting it }) - // instantiate the sequence adapter - const sequenceAdapterType = this.getConf(['sequenceAdapter', 'type']) if (!this.getSubAdapter) { throw new Error('Error getting subadapter') } const seqConf = this.getConf('sequenceAdapter') - const { dataAdapter: sequenceAdapter } = await this.getSubAdapter(seqConf) + const subadapter = await this.getSubAdapter(seqConf) - if (!(sequenceAdapter instanceof BaseFeatureDataAdapter)) { - throw new Error( - `CRAM feature adapters cannot use sequence adapters of type '${sequenceAdapterType}'`, - ) + return { + cram, + sequenceAdapter: subadapter.dataAdapter as BaseSequenceAdapter, } + } - return { cram, sequenceAdapter } + public async configure() { + if (!this.configureP) { + this.configureP = this.configurePre().catch(e => { + this.configureP = undefined + throw e + }) + } + return this.configureP } async getHeader(opts?: BaseOptions) { @@ -132,9 +142,9 @@ export default class CramAdapter extends BaseFeatureDataAdapter { private async setupPre(opts?: BaseOptions) { const { statusCallback = () => {} } = opts || {} - const configured = await this.configure() + const conf = await this.configure() statusCallback('Downloading index') - const { cram } = configured + const { cram } = conf const samHeader: HeaderLine[] = await cram.cram.getSamHeader(opts?.signal) // use the @SQ lines in the header to figure out the @@ -161,7 +171,7 @@ export default class CramAdapter extends BaseFeatureDataAdapter { const data = { idToName, nameToId, readGroups } statusCallback('') this.samHeader = data - return { samHeader: data, ...configured } + return { samHeader: data, ...conf } } private async setup(opts?: BaseOptions) { @@ -197,13 +207,7 @@ export default class CramAdapter extends BaseFeatureDataAdapter { // use info from the SAM header if possible, but fall back to using // the ref seq order from when the browser's refseqs were loaded refIdToName(refId: number) { - if (this.samHeader.idToName) { - return this.samHeader.idToName[refId] - } - if (this.seqIdToRefName) { - return this.seqIdToRefName[refId] - } - return undefined + return this.samHeader.idToName?.[refId] || this.seqIdToRefName?.[refId] } refIdToOriginalName(refId: number) { @@ -220,53 +224,53 @@ export default class CramAdapter extends BaseFeatureDataAdapter { const { refName, start, end, originalRefName } = region return ObservableCreate(async observer => { - const { cram, sequenceAdapter } = await this.setup(opts) - statusCallback('Downloading alignments') - if (!this.seqIdToRefName) { - this.seqIdToRefName = await sequenceAdapter.getRefNames(opts) - } + const { cram } = await this.setup(opts) + const refId = this.refNameToId(refName) - if (refId !== undefined) { - if (originalRefName) { - this.seqIdToOriginalRefName[refId] = originalRefName - } - const records = await cram.getRecordsForRange(refId, start, end, opts) - checkAbortSignal(signal) - const { - flagInclude = 0, - flagExclude = 0, - tagFilter, - readName, - } = filterBy || {} + if (refId === undefined) { + console.warn('Unknown refName', refName) + observer.complete() + return + } + + if (originalRefName) { + this.seqIdToOriginalRefName[refId] = originalRefName + } + statusCallback('Downloading alignments') + const records = await cram.getRecordsForRange(refId, start, end, opts) + checkAbortSignal(signal) + const { + flagInclude = 0, + flagExclude = 0, + tagFilter, + readName, + } = filterBy || {} + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let filtered = records.filter((record: any) => { + const flags = record.flags + return (flags & flagInclude) === flagInclude && !(flags & flagExclude) + }) + if (tagFilter) { // eslint-disable-next-line @typescript-eslint/no-explicit-any - let filtered = records.filter((record: any) => { - const flags = record.flags - return (flags & flagInclude) === flagInclude && !(flags & flagExclude) + filtered = filtered.filter((record: any) => { + const val = record[tagFilter.tag] + return val === '*' ? val !== undefined : val === tagFilter.value }) + } - if (tagFilter) { + if (readName) { + filtered = filtered.filter( // eslint-disable-next-line @typescript-eslint/no-explicit-any - filtered = filtered.filter((record: any) => { - const val = record[tagFilter.tag] - return val === '*' ? val !== undefined : val === tagFilter.value - }) - } - - if (readName) { - filtered = filtered.filter( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (record: any) => record.readName === readName, - ) - } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - filtered.forEach((record: any) => { - observer.next(this.cramRecordToFeature(record)) - }) - } else { - console.warn('Unknown refName', refName) + (record: any) => record.readName === readName, + ) } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + filtered.forEach((record: any) => { + observer.next(this.cramRecordToFeature(record)) + }) statusCallback('') observer.complete() }, signal) diff --git a/plugins/alignments/src/HtsgetBamAdapter/HtsgetBamAdapter.ts b/plugins/alignments/src/HtsgetBamAdapter/HtsgetBamAdapter.ts index 5ae9382f06..7344b998fb 100644 --- a/plugins/alignments/src/HtsgetBamAdapter/HtsgetBamAdapter.ts +++ b/plugins/alignments/src/HtsgetBamAdapter/HtsgetBamAdapter.ts @@ -4,28 +4,23 @@ import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter' import BamAdapter from '../BamAdapter/BamAdapter' export default class HtsgetBamAdapter extends BamAdapter { - protected async configure() { - if (!this.configured) { - const htsgetBase = readConfObject(this.config, 'htsgetBase') - const htsgetTrackId = readConfObject(this.config, 'htsgetTrackId') - const bam = new HtsgetFile({ - baseUrl: htsgetBase, - trackId: htsgetTrackId, - }) as unknown as BamFile + protected async configurePre() { + const htsgetBase = readConfObject(this.config, 'htsgetBase') + const htsgetTrackId = readConfObject(this.config, 'htsgetTrackId') + const bam = new HtsgetFile({ + baseUrl: htsgetBase, + trackId: htsgetTrackId, + }) as unknown as BamFile - const adapterConfig = readConfObject(this.config, 'sequenceAdapter') - if (adapterConfig && this.getSubAdapter) { - this.configured = this.getSubAdapter(adapterConfig).then( - ({ dataAdapter }) => { - return { - bam, - sequenceAdapter: dataAdapter as BaseFeatureDataAdapter, - } - }, - ) - } - this.configured = Promise.resolve({ bam }) + const adapterConfig = readConfObject(this.config, 'sequenceAdapter') + if (adapterConfig && this.getSubAdapter) { + return this.getSubAdapter(adapterConfig).then(({ dataAdapter }) => { + return { + bam, + sequenceAdapter: dataAdapter as BaseFeatureDataAdapter, + } + }) } - return this.configured + return { bam } } } diff --git a/plugins/alignments/src/PileupRenderer/PileupRenderer.tsx b/plugins/alignments/src/PileupRenderer/PileupRenderer.tsx index a1cc8b9f9f..bf70107fd4 100644 --- a/plugins/alignments/src/PileupRenderer/PileupRenderer.tsx +++ b/plugins/alignments/src/PileupRenderer/PileupRenderer.tsx @@ -150,7 +150,7 @@ export default class PileupRenderer extends BoxRendererType { // get width and height of chars the height is an approximation: width // letter M is approximately the height - getCharWidthHeight(ctx: CanvasRenderingContext2D) { + getCharWidthHeight() { const charWidth = measureText('A') const charHeight = measureText('M') - 2 return { charWidth, charHeight } @@ -237,11 +237,7 @@ export default class PileupRenderer extends BoxRendererType { const maxClippingSize = readConfObject(config, 'maxClippingSize') const { start, end } = region - const len = end - start - const bpExpansion = Math.max( - len, - showSoftClip ? Math.round(maxClippingSize) : 0, - ) + const bpExpansion = showSoftClip ? Math.round(maxClippingSize) : 0 return { // xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit @@ -1058,7 +1054,7 @@ export default class PileupRenderer extends BoxRendererType { const minFeatWidth = readConfObject(config, 'minSubfeatureWidth') const mismatches: Mismatch[] = feature.get('mismatches') const seq = feature.get('seq') - const { charWidth, charHeight } = this.getCharWidthHeight(ctx) + const { charWidth, charHeight } = this.getCharWidthHeight() const { bases } = theme.palette const colorForBase: { [key: string]: string } = { A: bases.A.main, @@ -1161,7 +1157,7 @@ export default class PileupRenderer extends BoxRendererType { } ctx.font = 'bold 10px Courier New,monospace' - const { charWidth, charHeight } = this.getCharWidthHeight(ctx) + const { charWidth, charHeight } = this.getCharWidthHeight() const drawSNPsMuted = shouldDrawSNPsMuted(colorBy?.type) const drawIndels = shouldDrawIndels(colorBy?.type) for (let i = 0; i < layoutRecords.length; i++) { @@ -1271,13 +1267,13 @@ export default class PileupRenderer extends BoxRendererType { const features = await this.getFeatures(renderProps) const layout = this.createLayoutInWorker(renderProps) const { regions, bpPerPx } = renderProps + const [region] = regions const layoutRecords = this.layoutFeats({ ...renderProps, features, layout, }) - const [region] = regions // only need reference sequence if there are features and only for some // cases diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/alignments-features-test-tsx-color-by-tag-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/alignments-features-test-tsx-color-by-tag-1-snap.png index 27ad37fbeb..850d794f68 100644 Binary files a/products/jbrowse-web/src/tests/__image_snapshots__/alignments-features-test-tsx-color-by-tag-1-snap.png and b/products/jbrowse-web/src/tests/__image_snapshots__/alignments-features-test-tsx-color-by-tag-1-snap.png differ diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-bam-404-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-bam-404-1-snap.png index 2ade875d39..ea3817c5dc 100644 Binary files a/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-bam-404-1-snap.png and b/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-bam-404-1-snap.png differ diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-crai-404-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-crai-404-1-snap.png index 2ade875d39..ea3817c5dc 100644 Binary files a/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-crai-404-1-snap.png and b/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-crai-404-1-snap.png differ diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/snapshot.svg b/products/jbrowse-web/src/tests/__image_snapshots__/snapshot.svg index 735cd8c58b..04da9107e3 100644 --- a/products/jbrowse-web/src/tests/__image_snapshots__/snapshot.svg +++ b/products/jbrowse-web/src/tests/__image_snapshots__/snapshot.svg @@ -1 +1 @@ -volvox80bpctgA020406080volvox-sorted.bam (ctgA, canvas)001111GTACAGAGTGACGCTCAAAGCCATTGTCGGAAGT \ No newline at end of file +volvox80bpctgA020406080volvox-sorted.bam (ctgA, canvas)001111GTACAGAGTGACGCTCAAAGC \ No newline at end of file diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-force-load-to-see-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-force-load-to-see-1-snap.png index 2741adbc2d..d9d7afcf90 100644 Binary files a/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-force-load-to-see-1-snap.png and b/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-force-load-to-see-1-snap.png differ diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-zoom-in-to-see-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-zoom-in-to-see-1-snap.png index 164b55eeb2..c89c51d646 100644 Binary files a/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-zoom-in-to-see-1-snap.png and b/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-zoom-in-to-see-1-snap.png differ diff --git a/products/jbrowse-web/src/tests/__snapshots__/ExportSvg.test.tsx.snap b/products/jbrowse-web/src/tests/__snapshots__/ExportSvg.test.tsx.snap index 4be5d104ac..14e2c9693b 100644 --- a/products/jbrowse-web/src/tests/__snapshots__/ExportSvg.test.tsx.snap +++ b/products/jbrowse-web/src/tests/__snapshots__/ExportSvg.test.tsx.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`export svg 1`] = `"volvox80bpctgA020406080volvox-sorted.bam (ctgA, canvas)001111GTACAGAGTGACGCTCAAAGCCATTGTCGGAAGT"`; +exports[`export svg 1`] = `"volvox80bpctgA020406080volvox-sorted.bam (ctgA, canvas)001111GTACAGAGTGACGCTCAAAGC"`;