Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { ElementId } from '@jbrowse/core/util/types/mst'
import { autorun } from 'mobx'
import { Instance, SnapshotIn, addDisposer, types } from 'mobx-state-tree'

import { ChangeManager } from '../ChangeManager'
import { ApolloSessionModel } from '../session'

export const ApolloFeatureDetailsWidgetModel = types
Expand Down Expand Up @@ -86,7 +85,6 @@ export const ApolloTranscriptDetailsModel = types
),
assembly: types.string,
refName: types.string,
changeManager: types.frozen<ChangeManager>(),
})
.volatile(() => ({
tryReload: undefined as string | undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@
} from '@jbrowse/core/util'
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
import ErrorIcon from '@mui/icons-material/Error'
import { Alert, Avatar, Tooltip, useTheme } from '@mui/material'
import {

Check warning on line 12 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx#L12

Added line #L12 was not covered by tests
Alert,
Avatar,
CircularProgress,
Tooltip,
useTheme,
} from '@mui/material'
import { observer } from 'mobx-react'
import React, { useEffect, useState } from 'react'
import { makeStyles } from 'tss-react/mui'
Expand Down Expand Up @@ -39,6 +45,13 @@
color: theme.palette.warning.light,
backgroundColor: theme.palette.warning.contrastText,
},
loading: {
position: 'absolute',
right: theme.spacing(3),
zIndex: 10,
pointerEvents: 'none',
textAlign: 'right',
},
}))

export const LinearApolloDisplay = observer(function LinearApolloDisplay(
Expand All @@ -47,6 +60,7 @@
const theme = useTheme()
const { model } = props
const {
loading,
apolloRowHeight,
contextMenuItems: getContextMenuItems,
cursor,
Expand Down Expand Up @@ -128,6 +142,11 @@
}
}}
>
{loading ? (
<div className={classes.loading}>

Check warning on line 146 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx#L146

Added line #L146 was not covered by tests
<CircularProgress size="18px" />
</div>
) : null}

Check warning on line 149 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx#L149

Added line #L149 was not covered by tests
{message ? (
<Alert severity="warning" classes={{ message: classes.ellipses }}>
<Tooltip title={message}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
),
),
filteredFeatureTypes: types.array(types.string),
loadingState: false,
})
.views((self) => {
const { configuration, renderProps: superRenderProps } = self
Expand Down Expand Up @@ -76,6 +77,9 @@
}
return 300
},
get loading() {
return self.loadingState

Check warning on line 81 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/base.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/base.ts#L80-L81

Added lines #L80 - L81 were not covered by tests
},
}))
.views((self) => ({
get rendererTypeName() {
Expand Down Expand Up @@ -167,6 +171,9 @@
updateFilteredFeatureTypes(types: string[]) {
self.filteredFeatureTypes = cast(types)
},
setLoading(loading: boolean) {
self.loadingState = loading

Check warning on line 175 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/base.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/base.ts#L174-L175

Added lines #L174 - L175 were not covered by tests
},
}))
.views((self) => {
const { filteredFeatureTypes, trackMenuItems: superTrackMenuItems } = self
Expand Down Expand Up @@ -244,9 +251,16 @@
if (!self.lgv.initialized || self.regionCannotBeRendered()) {
return
}
self.setLoading(true)

Check warning on line 254 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/base.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/base.ts#L254

Added line #L254 was not covered by tests
void (
self.session as unknown as ApolloSessionModel
).apolloDataStore.loadFeatures(self.regions)
).apolloDataStore
.loadFeatures(self.regions)
.then(() => {
setTimeout(() => {
self.setLoading(false)

Check warning on line 261 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/base.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/base.ts#L259-L261

Added lines #L259 - L261 were not covered by tests
}, 1000)
})
if (self.lgv.bpPerPx <= 3) {
void (
self.session as unknown as ApolloSessionModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,39 @@
import { baseModelFactory } from './base'
import { boxGlyph, geneGlyph, genericChildGlyph } from '../glyphs'

function getRowsForFeature(
startingRow: number,
rowCount: number,
filledRowLocations: Map<number, [number, number][]>,

Check warning on line 17 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L17

Added line #L17 was not covered by tests
) {
const rowsForFeature = []
for (let i = startingRow; i < startingRow + rowCount; i++) {
const row = filledRowLocations.get(i)

Check warning on line 21 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L19-L21

Added lines #L19 - L21 were not covered by tests
if (row) {
rowsForFeature.push(row)

Check warning on line 23 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L23

Added line #L23 was not covered by tests
}
}
return rowsForFeature

Check warning on line 26 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L26

Added line #L26 was not covered by tests
}

function canPlaceFeatureInRows(
rowsForFeature: [number, number][][],
feature: AnnotationFeature,

Check warning on line 31 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L31

Added line #L31 was not covered by tests
) {
for (const rowForFeature of rowsForFeature) {
for (const [rowStart, rowEnd] of rowForFeature) {

Check warning on line 34 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L33-L34

Added lines #L33 - L34 were not covered by tests
if (
doesIntersect2(feature.min, feature.max, rowStart, rowEnd) ||
doesIntersect2(rowStart, rowEnd, feature.min, feature.max)

Check warning on line 37 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L37

Added line #L37 was not covered by tests
) {
return false

Check warning on line 39 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L39

Added line #L39 was not covered by tests
}
}
}

return true

Check warning on line 44 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L44

Added line #L44 was not covered by tests
}

export function layoutsModelFactory(
pluginManager: PluginManager,
configSchema: AnyConfigurationSchemaType,
Expand All @@ -19,48 +52,14 @@

return BaseLinearApolloDisplay.named('LinearApolloDisplayLayouts')
.props({
featuresMinMaxLimit: 500_000,
cleanupBoundary: 200_000,
})
.volatile(() => ({
seenFeatures: observable.map<string, AnnotationFeature>(),
}))
.views((self) => ({
get featuresMinMax() {
const { assemblyManager } =
self.session as unknown as AbstractSessionModel
return self.lgv.displayedRegions.map((region) => {
const assembly = assemblyManager.get(region.assemblyName)
let min: number | undefined
let max: number | undefined
const { end, refName, start } = region
for (const [, feature] of self.seenFeatures) {
if (
refName !== assembly?.getCanonicalRefName(feature.refSeq) ||
!doesIntersect2(start, end, feature.min, feature.max) ||
feature.length > self.featuresMinMaxLimit ||
(self.filteredFeatureTypes.length > 0 &&
!self.filteredFeatureTypes.includes(feature.type))
) {
continue
}
if (min === undefined) {
;({ min } = feature)
}
if (max === undefined) {
;({ max } = feature)
}
if (feature.minWithChildren < min) {
;({ min } = feature)
}
if (feature.maxWithChildren > max) {
;({ max } = feature)
}
}
if (min !== undefined && max !== undefined) {
return [min, max]
}
return
})
getAnnotationFeatureById(id: string) {
return self.seenFeatures.get(id)

Check warning on line 62 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L61-L62

Added lines #L61 - L62 were not covered by tests
},
getGlyph(feature: AnnotationFeature) {
if (this.looksLikeGene(feature)) {
Expand Down Expand Up @@ -111,15 +110,11 @@
get featureLayouts() {
const { assemblyManager } =
self.session as unknown as AbstractSessionModel
return self.lgv.displayedRegions.map((region, idx) => {
return self.lgv.displayedRegions.map((region) => {

Check warning on line 113 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L113

Added line #L113 was not covered by tests
const assembly = assemblyManager.get(region.assemblyName)
const featureLayout = new Map<number, [number, AnnotationFeature][]>()
const minMax = self.featuresMinMax[idx]
if (!minMax) {
return featureLayout
}
const [min, max] = minMax
const rows: boolean[][] = []
const featureLayout = new Map<number, [number, string][]>()

Check warning on line 115 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L115

Added line #L115 was not covered by tests
// Track the occupied coordinates in each row
const filledRowLocations = new Map<number, [number, number][]>()

Check warning on line 117 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L117

Added line #L117 was not covered by tests
const { end, refName, start } = region
for (const [id, feature] of self.seenFeatures.entries()) {
if (!isAlive(feature)) {
Expand All @@ -145,36 +140,24 @@
let startingRow = 0
let placed = false
while (!placed) {
let rowsForFeature = rows.slice(
let rowsForFeature = getRowsForFeature(

Check warning on line 143 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L143

Added line #L143 was not covered by tests
startingRow,
startingRow + rowCount,
rowCount,
filledRowLocations,
)
if (rowsForFeature.length < rowCount) {
for (let i = 0; i < rowCount - rowsForFeature.length; i++) {
const newRowNumber = rows.length
rows[newRowNumber] = Array.from({ length: max - min })
const newRowNumber = filledRowLocations.size
filledRowLocations.set(newRowNumber, [])

Check warning on line 151 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L150-L151

Added lines #L150 - L151 were not covered by tests
featureLayout.set(newRowNumber, [])
}
rowsForFeature = rows.slice(startingRow, startingRow + rowCount)
rowsForFeature = getRowsForFeature(

Check warning on line 154 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L154

Added line #L154 was not covered by tests
startingRow,
rowCount,
filledRowLocations,
)
}
if (
rowsForFeature
.map((rowForFeature) => {
// zero-length features are allowed in the spec
const featureMax =
feature.max - feature.min === 0
? feature.min + 1
: feature.max
let start = feature.min - min,
end = featureMax - min
if (feature.min - min < 0) {
start = 0
end = featureMax - feature.min
}
return rowForFeature.slice(start, end).some(Boolean)
})
.some(Boolean)
) {
if (!canPlaceFeatureInRows(rowsForFeature, feature)) {
startingRow += 1
continue
}
Expand All @@ -183,16 +166,9 @@
rowNum < startingRow + rowCount;
rowNum++
) {
const row = rows[rowNum]
let start = feature.min - min,
end = feature.max - min
if (feature.min - min < 0) {
start = 0
end = feature.max - feature.min
}
row.fill(true, start, end)
filledRowLocations.get(rowNum)?.push([feature.min, feature.max])
const layoutRow = featureLayout.get(rowNum)
layoutRow?.push([rowNum - startingRow, feature])
layoutRow?.push([rowNum - startingRow, feature._id])
}
placed = true
}
Expand All @@ -206,12 +182,17 @@
self.session.apolloDataStore.ontologyManager
for (const [idx, layout] of featureLayouts.entries()) {
for (const [layoutRowNum, layoutRow] of layout) {
for (const [featureRowNum, layoutFeature] of layoutRow) {
for (const [featureRowNum, layoutFeatureId] of layoutRow) {

Check warning on line 185 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L185

Added line #L185 was not covered by tests
if (featureRowNum !== 0) {
// Same top-level feature in all feature rows, so only need to
// check the first one
continue
}
const layoutFeature =
self.getAnnotationFeatureById(layoutFeatureId)

Check warning on line 192 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L192

Added line #L192 was not covered by tests
if (!layoutFeature) {
continue

Check warning on line 194 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L194

Added line #L194 was not covered by tests
}
if (feature._id === layoutFeature._id) {
return {
layoutIndex: idx,
Expand Down Expand Up @@ -257,6 +238,30 @@
if (!self.lgv.initialized || self.regionCannotBeRendered()) {
return
}
// Clear out features that are no longer in the view and out of the cleanup boundary
// cleanup boundary + region boundary + cleanup boundary
for (const [id, feature] of self.seenFeatures.entries()) {
let shouldKeep = false
for (const region of self.regions) {
const extendedStart = region.start - self.cleanupBoundary
const extendedEnd = region.end + self.cleanupBoundary

Check warning on line 247 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L243-L247

Added lines #L243 - L247 were not covered by tests
if (
doesIntersect2(
extendedStart,
extendedEnd,
feature.min,
feature.max,
)
) {
shouldKeep = true
break

Check warning on line 257 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L256-L257

Added lines #L256 - L257 were not covered by tests
}
}
if (!shouldKeep) {
self.deleteSeenFeature(id)

Check warning on line 261 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/layouts.ts#L261

Added line #L261 was not covered by tests
}
}
// Add features that are in the current view
for (const region of self.regions) {
const assembly = (
self.session as unknown as ApolloSessionModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,18 @@
if (!layoutRow) {
return mousePosition
}
const foundFeature = layoutRow.find(
(f) => bp >= f[1].min && bp <= f[1].max,
)
const foundFeature = layoutRow.find((f) => {
const feature = self.getAnnotationFeatureById(f[1])

Check warning on line 143 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/mouseEvents.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/mouseEvents.ts#L142-L143

Added lines #L142 - L143 were not covered by tests
return feature && bp >= feature.min && bp <= feature.max
})
if (!foundFeature) {
return mousePosition
}
const [featureRow, topLevelFeature] = foundFeature
const [featureRow, topLevelFeatureId] = foundFeature
const topLevelFeature = self.getAnnotationFeatureById(topLevelFeatureId)

Check warning on line 150 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/mouseEvents.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/mouseEvents.ts#L149-L150

Added lines #L149 - L150 were not covered by tests
if (!topLevelFeature) {
return mousePosition

Check warning on line 152 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/mouseEvents.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/mouseEvents.ts#L152

Added line #L152 was not covered by tests
}
const glyph = self.getGlyph(topLevelFeature)
const { featureTypeOntology } =
self.session.apolloDataStore.ontologyManager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,9 @@
for (const [idx, featureLayout] of featureLayouts.entries()) {
const displayedRegion = displayedRegions[idx]
for (const [row, featureLayoutRow] of featureLayout.entries()) {
for (const [featureRow, feature] of featureLayoutRow) {
if (featureRow > 0) {
for (const [featureRow, featureId] of featureLayoutRow) {
const feature = self.getAnnotationFeatureById(featureId)

Check warning on line 417 in packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/rendering.ts

View check run for this annotation

Codecov / codecov/patch

packages/jbrowse-plugin-apollo/src/LinearApolloDisplay/stateModel/rendering.ts#L416-L417

Added lines #L416 - L417 were not covered by tests
if (featureRow > 0 || !feature) {
continue
}
if (
Expand Down
Loading