Skip to content

Commit

Permalink
Use an autorun to run feature formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Jun 6, 2022
1 parent 2d42604 commit f08d936
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 91 deletions.
4 changes: 1 addition & 3 deletions packages/core/BaseFeatureWidget/BaseFeatureDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -565,9 +565,7 @@ export const FeatureDetails = (props: {
{sequenceTypes.includes(feature.type) ? (
<ErrorBoundary
FallbackComponent={({ error }) => (
<Typography color="error">
Failed to fetch sequence for feature: {`${error}`}
</Typography>
<Typography color="error">{`${error}`}</Typography>
)}
>
<SequenceFeatureDetails {...props} />
Expand Down
88 changes: 58 additions & 30 deletions packages/core/BaseFeatureWidget/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { types } from 'mobx-state-tree'
import { types, addDisposer } from 'mobx-state-tree'
import { autorun } from 'mobx'
import PluginManager from '../PluginManager'
import { getConf, ConfigurationSchema } from '../configuration'
import clone from 'clone'
import { ElementId } from '../util/types/mst'

const configSchema = ConfigurationSchema('BaseFeatureWidget', {})
Expand Down Expand Up @@ -42,6 +44,7 @@ export default function stateModelFactory(pluginManager: PluginManager) {
id: ElementId,
type: types.literal('BaseFeatureWidget'),
featureData: types.frozen(),
unformattedFeatureData: types.frozen(),
view: types.safeReference(
pluginManager.pluggableMstType('view', 'stateModel'),
),
Expand All @@ -52,42 +55,67 @@ export default function stateModelFactory(pluginManager: PluginManager) {
pluginManager.pluggableMstType('display', 'stateModel'),
),
})
.volatile(() => ({}))
.actions(self => ({
setFeatureData(feature: Record<string, unknown>) {
let trackExtra = {}
setFeatureData(featureData: Record<string, unknown>) {
self.unformattedFeatureData = featureData
},
clearFeatureData() {
self.featureData = undefined
},
setFormattedFeatureData(feat: Record<string, unknown>) {
self.featureData = feat
},
}))
.actions(self => ({
afterCreate() {
addDisposer(
self,
autorun(() => {
if (self.unformattedFeatureData) {
const feature = clone(self.unformattedFeatureData)
let trackExtra = {}

iterate(feature, (key, val, obj) => {
if (key === 'id') {
obj.origId = val
}
if (key === 'name') {
obj.origName = val
}
if (key === 'type') {
obj.origType = val
}
})
iterate(feature, (key, val, obj) => {
if (key === 'id') {
obj.origId = val
}
if (key === 'name') {
obj.origName = val
}
if (key === 'type') {
obj.origType = val
}
})

if (self.track) {
const ret = getConf(self.track, ['formatFields'], { feature })
if (ret) {
trackExtra = ret
}
if (self.track) {
const ret = getConf(self.track, ['formatFields'], { feature })
if (ret) {
trackExtra = ret
}

iterateSubfeatures(feature, obj => {
const r = getConf(self.track, ['formatFieldsNested'], {
feature: obj,
})
return r ? { ...obj, ...r } : obj
})
}
iterateSubfeatures(feature, obj => {
const r = getConf(self.track, ['formatFieldsNested'], {
feature: obj,
})
return r ? { ...obj, ...r } : obj
})
}

self.featureData = { ...feature, ...trackExtra }
},
clearFeatureData() {
self.featureData = undefined
self.setFormattedFeatureData({ ...feature, ...trackExtra })
}
}),
)
},
}))
.preProcessSnapshot(snap => {
const { featureData, ...rest } = snap
return { unformattedFeatureData: featureData, ...rest }
})
.postProcessSnapshot(snap => {
const { unformattedFeatureData, ...rest } = snap
return rest
})
}

export { configSchema, stateModelFactory }
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"canvas": "^2.8.0",
"canvas-sequencer": "^3.1.0",
"canvas2svg": "^1.0.16",
"clone": "^2.1.2",
"clsx": "^1.0.4",
"color": "^3.1.3",
"copy-to-clipboard": "^3.3.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React, { useState } from 'react'
import {
Button,
Typography,
Link,
Paper,
Checkbox,
FormControlLabel,
FormGroup,
Link,
Paper,
Typography,
makeStyles,
} from '@material-ui/core'
import { observer } from 'mobx-react'
Expand Down Expand Up @@ -82,20 +81,12 @@ function Formatter({ value }: { value: unknown }) {
if (display.length > 100) {
return (
<>
<Button
style={{ margin: 2 }}
variant="contained"
onClick={() => copy(display)}
>
<button type="button" onClick={() => copy(display)}>
Copy
</Button>
<Button
style={{ margin: 2 }}
variant="contained"
onClick={() => setShow(val => !val)}
>
</button>
<button type="button" onClick={() => setShow(val => !val)}>
{show ? 'Show less' : 'Show more'}
</Button>
</button>
<div>{show ? display : `${display.slice(0, 100)}...`}</div>
</>
)
Expand All @@ -117,14 +108,6 @@ function getLengthOnRef(cigar: string) {
return lengthOnRef
}

function toP(n: number) {
n.toLocaleString('en-US')
}

function makeStr(ref: string, start: number, end: number) {
return `${ref}:${toP(start)}-${toP(end)}`
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function SupplementaryAlignments(props: { tag: string; model: any }) {
const { tag, model } = props
Expand All @@ -142,11 +125,12 @@ function SupplementaryAlignments(props: { tag: string; model: any }) {
const extra = Math.floor(saLength / 5)
const start = +saStart
const end = +saStart + saLength
const locString = makeStr(
saRef,
Math.max(1, start - extra),
end + extra,
)
const locString = `${saRef}:${Math.max(1, start - extra)}-${
end + extra
}`
const displayStart = start.toLocaleString('en-US')
const displayEnd = end.toLocaleString('en-US')
const displayString = `${saRef}:${displayStart}-${displayEnd} (${saStrand})`
return (
<li key={`${locString}-${index}`}>
<Link
Expand All @@ -168,7 +152,7 @@ function SupplementaryAlignments(props: { tag: string; model: any }) {
}}
href="#"
>
{makeStr(saRef, start, end)} ({saStrand})
{displayString}
</Link>
</li>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,11 +338,10 @@ export const BaseLinearDisplay = types
view: getContainingView(self),
display: self,
track: getContainingTrack(self),
featureData: feature.toJSON(),
},
)

// @ts-ignore
featureWidget.setFeatureData(feature.toJSON())
session.showWidget(featureWidget)
}
if (isSelectionContainer(session)) {
Expand Down
26 changes: 0 additions & 26 deletions plugins/variants/src/VariantFeatureWidget/index.js

This file was deleted.

17 changes: 17 additions & 0 deletions plugins/variants/src/VariantFeatureWidget/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ConfigurationSchema } from '@jbrowse/core/configuration'
import PluginManager from '@jbrowse/core/PluginManager'
import { types } from 'mobx-state-tree'
import { stateModelFactory as baseModelFactory } from '@jbrowse/core/BaseFeatureWidget'

export const configSchema = ConfigurationSchema('VariantFeatureWidget', {})

export function stateModelFactory(pluginManager: PluginManager) {
const baseModel = baseModelFactory(pluginManager)
return types.compose(
baseModel,
types.model('VariantFeatureWidget', {
type: types.literal('VariantFeatureWidget'),
descriptions: types.frozen(),
}),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -1721,6 +1721,7 @@ Object {
"type": "LinearArcDisplay",
},
],
"formatFields": "jexl:{link:\\"https://google.com/?q=\\"+feature.name}",
"name": "GFF3Tabix genes",
"trackId": "gff3tabix_genes",
"type": "FeatureTrack",
Expand Down
1 change: 1 addition & 0 deletions test_data/volvox/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,7 @@
"trackId": "gff3tabix_genes",
"assemblyNames": ["volvox"],
"name": "GFF3Tabix genes",
"formatFields": "jexl:{link:\"https://google.com/?q=\"+feature.name}",
"category": ["Miscellaneous"],
"adapter": {
"type": "Gff3TabixAdapter",
Expand Down

0 comments on commit f08d936

Please sign in to comment.