Skip to content

Commit

Permalink
[skip ci] Matrix
Browse files Browse the repository at this point in the history
Updates

Small updates + minor allele frequency

[skip ci] Test

T1

T5

Bump yarn.lock

Fix some types

Update snap

Render block

Add autogen docs

Misc
  • Loading branch information
cmdcolin committed Nov 4, 2024
1 parent c5ba32e commit 9358657
Show file tree
Hide file tree
Showing 17 changed files with 876 additions and 373 deletions.
27 changes: 27 additions & 0 deletions plugins/variants/src/LinearVariantMatrixDisplay/configSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ConfigurationSchema } from '@jbrowse/core/configuration'
import PluginManager from '@jbrowse/core/PluginManager'
import { linearBasicDisplayConfigSchemaFactory } from '@jbrowse/plugin-linear-genome-view'

// locals
import configSchema from '../LinearVariantMatrixRenderer/configSchema'

/**
* #config LinearVariantMatrixDisplay
*/
function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars

export default function configSchemaF(pluginManager: PluginManager) {
return ConfigurationSchema(
'LinearVariantMatrixDisplay',
{
renderer: configSchema,
},
{
/**
* #baseConfiguration
*/
baseConfiguration: linearBasicDisplayConfigSchemaFactory(pluginManager),
explicitlyTyped: true,
},
)
}
22 changes: 22 additions & 0 deletions plugins/variants/src/LinearVariantMatrixDisplay/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import PluginManager from '@jbrowse/core/PluginManager'
import { BaseLinearDisplayComponent } from '@jbrowse/plugin-linear-genome-view'
import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'

// locals
import stateModelFactory from './model'
import configSchemaF from './configSchema'

export default (pluginManager: PluginManager) => {
pluginManager.addDisplayType(() => {
const configSchema = configSchemaF(pluginManager)
return new DisplayType({
name: 'LinearVariantMatrixDisplay',
displayName: 'Matrix display',
configSchema,
stateModel: stateModelFactory(configSchema),
trackType: 'VariantTrack',
viewType: 'LinearGenomeView',
ReactComponent: BaseLinearDisplayComponent,
})
})
}
77 changes: 77 additions & 0 deletions plugins/variants/src/LinearVariantMatrixDisplay/model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { ConfigurationReference } from '@jbrowse/core/configuration'

import { linearBasicDisplayModelFactory } from '@jbrowse/plugin-linear-genome-view'
import { Instance, types } from 'mobx-state-tree'

// locals
import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration'

/**
* #stateModel LinearVariantMatrixDisplay
* extends `LinearBasicDisplay`
*/
export default function stateModelFactory(
configSchema: AnyConfigurationSchemaType,
) {
return types
.compose(
'LinearVariantMatrixDisplay',
linearBasicDisplayModelFactory(configSchema),
types.model({
/**
* #property
*/
type: types.literal('LinearVariantMatrixDisplay'),
/**
* #property
*/
configuration: ConfigurationReference(configSchema),
}),
)
.volatile(() => ({
samples: undefined as string[] | undefined,
}))
.views(() => ({
/**
* #getter
*/
get blockType() {
return 'dynamicBlocks'
},
/**
* #getter
*/
get renderDelay() {
return 1000
},
}))
.actions(self => ({
/**
* #action
*/
setSamples(arg: string[]) {
self.samples = arg
},
}))
.views(self => {
const { renderProps: superRenderProps } = self
return {
/**
* #method
*/
renderProps() {
const superProps = superRenderProps()
return {
...superProps,
height: self.height,
}
},
}
})
}

export type LinearVariantMatrixDisplayStateModel = ReturnType<
typeof stateModelFactory
>
export type LinearVariantMatrixDisplayModel =
Instance<LinearVariantMatrixDisplayStateModel>
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import BoxRendererType, {
RenderArgs,
RenderArgsSerialized,
RenderArgsDeserialized as BoxRenderArgsDeserialized,
RenderResults,
ResultsSerialized,
ResultsDeserialized,
} from '@jbrowse/core/pluggableElementTypes/renderers/BoxRendererType'
import { Feature, renderToAbstractCanvas } from '@jbrowse/core/util'

export interface SortParams {
type: string
pos: number
refName: string
assemblyName: string
tag?: string
}

export interface RenderArgsDeserialized extends BoxRenderArgsDeserialized {
highResolutionScaling: number
height: number
}

export interface RenderArgsDeserializedWithFeaturesAndLayout
extends RenderArgsDeserialized {
features: Map<string, Feature>
}

const fudgeFactor = 0.6
const f2 = fudgeFactor / 2

export default class LinearVariantMatrixRenderer extends BoxRendererType {
supportsSVG = true

makeImageData({
ctx,
canvasWidth,
canvasHeight,
renderArgs,
}: {
ctx: CanvasRenderingContext2D
canvasWidth: number
canvasHeight: number
renderArgs: RenderArgsDeserializedWithFeaturesAndLayout
}) {
const { features } = renderArgs
const feats = [...features.values()]
if (!feats.length) {
return
}
const samples = feats[0].get('samples')
const keys = Object.keys(samples)
const h = canvasHeight / keys.length

const mafs = [] as number[]
for (let i = 0; i < feats.length; i++) {
let c = 0
let c2 = 0
for (let j = 0; j < keys.length; j++) {
const key = keys[j]
const samp = feats[i].get('samples')
const s = samp[key].GT[0]
if (s === '0|0') {
} else if (s === '1|0' || s === '0|1') {
c++
} else if (s === '1|1') {
c++
c2++
} else {
c++
}
}
if (c / keys.length > 0.15 && c2 / keys.length < 0.85) {
mafs.push(i)
}
}

const w = canvasWidth / mafs.length
for (let i = 0; i < mafs.length; i++) {
const m = mafs[i]
const f = feats[m]
const x = (i / mafs.length) * canvasWidth
for (let j = 0; j < keys.length; j++) {
const y = (j / keys.length) * canvasHeight
const key = keys[j]
const samp = f.get('samples')
const s = samp[key].GT[0]
if (s === '0|0') {
ctx.fillStyle = 'grey'
} else if (s === '1|0' || s === '0|1') {
ctx.fillStyle = 'teal'
} else if (s === '1|1') {
ctx.fillStyle = 'blue'
} else {
ctx.fillStyle = 'purple'
}
ctx.fillRect(x - f2, y - f2, w + f2, h + f2)
}
}
return { samples: Object.keys(samples) }
}

async render(renderProps: RenderArgsDeserialized) {
const features = await this.getFeatures(renderProps)
const { height, regions, bpPerPx } = renderProps
const [region] = regions

const { end, start } = region

const width = (end - start) / bpPerPx
const res = await renderToAbstractCanvas(width, height, renderProps, ctx =>
this.makeImageData({
ctx,
canvasWidth: width,
canvasHeight: height,
renderArgs: {
...renderProps,
features,
},
}),
)

const results = await super.render({
...renderProps,
...res,
features,
height,
width,
})

return {
...results,
...res,
features: new Map(),
height,
width,
}
}
}

export type {
RenderArgs,
RenderArgsSerialized,
RenderResults,
ResultsSerialized,
ResultsDeserialized,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React, { useEffect } from 'react'
import { PrerenderedCanvas } from '@jbrowse/core/ui'
import { Region } from '@jbrowse/core/util'
import { observer } from 'mobx-react'
import { LinearVariantMatrixDisplayModel } from '../../LinearVariantMatrixDisplay/model'

export default observer(function LinearVariantMatrixRendering(props: {
blockKey: string
displayModel: LinearVariantMatrixDisplayModel
width: number
height: number
regions: Region[]
bpPerPx: number
onMouseMove?: (event: React.MouseEvent, featureId?: string) => void
samples: string[]
}) {
const { displayModel, width, height, samples } = props

useEffect(() => {
displayModel.setSamples(samples)
}, [samples, displayModel])
const canvasWidth = Math.ceil(width)

return (
<div style={{ position: 'relative', width: canvasWidth, height }}>
<PrerenderedCanvas
{...props}
style={{ position: 'absolute', left: 0, top: 0 }}
/>
</div>
)
})
13 changes: 13 additions & 0 deletions plugins/variants/src/LinearVariantMatrixRenderer/configSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ConfigurationSchema } from '@jbrowse/core/configuration'

/**
* #config LinearVariantMatrixRenderer
*/
function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars

const LinearVariantMatrixRenderer = ConfigurationSchema(
'LinearVariantMatrixRenderer',
{},
{ explicitlyTyped: true },
)
export default LinearVariantMatrixRenderer
16 changes: 16 additions & 0 deletions plugins/variants/src/LinearVariantMatrixRenderer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import PluginManager from '@jbrowse/core/PluginManager'
import LinearVariantMatrixRenderer from './LinearVariantMatrixRenderer'
import ReactComponent from './components/LinearVariantMatrixRendering'
import configSchema from './configSchema'

export default function register(pluginManager: PluginManager) {
pluginManager.addRendererType(() => {
return new LinearVariantMatrixRenderer({
name: 'LinearVariantMatrixRenderer',
displayName: 'Linear variant matrix renderer',
ReactComponent,
configSchema,
pluginManager,
})
})
}
9 changes: 3 additions & 6 deletions plugins/variants/src/VariantTrack/configSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ import PluginManager from '@jbrowse/core/PluginManager'
* Mostly similar to feature track, but has `ChordDisplayType` registered to it,
* and custom feature details in `LinearVariantDisplay`
*/
function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars

const configSchema = (pluginManager: PluginManager) =>
ConfigurationSchema(
export default function (pluginManager: PluginManager) {
return ConfigurationSchema(
'VariantTrack',
{},
{
Expand All @@ -20,5 +18,4 @@ const configSchema = (pluginManager: PluginManager) =>
baseConfiguration: createBaseTrackConfig(pluginManager),
},
)

export default configSchema
}
4 changes: 4 additions & 0 deletions plugins/variants/src/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ exports[`plugin in a stock JBrowse 2`] = `
"displayId": "trackId0-LinearVariantDisplay",
"type": "LinearVariantDisplay",
},
{
"displayId": "trackId0-LinearVariantMatrixDisplay",
"type": "LinearVariantMatrixDisplay",
},
{
"displayId": "trackId0-ChordVariantDisplay",
"type": "ChordVariantDisplay",
Expand Down
4 changes: 4 additions & 0 deletions plugins/variants/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import Plugin from '@jbrowse/core/Plugin'
import PluginManager from '@jbrowse/core/PluginManager'
import ChordVariantDisplayF from './ChordVariantDisplay'
import LinearVariantDisplayF from './LinearVariantDisplay'
import LinearVariantMatrixDisplayF from './LinearVariantMatrixDisplay'
import LinearVariantMatrixRendererF from './LinearVariantMatrixRenderer'
import StructuralVariantChordRendererF from './StructuralVariantChordRenderer'
import VariantFeatureWidgetF from './VariantFeatureWidget'

Expand All @@ -19,6 +21,8 @@ export default class VariantsPlugin extends Plugin {
VariantTrackF(pluginManager)
ExtensionPointsF(pluginManager)
LinearVariantDisplayF(pluginManager)
LinearVariantMatrixDisplayF(pluginManager)
LinearVariantMatrixRendererF(pluginManager)
StructuralVariantChordRendererF(pluginManager)
ChordVariantDisplayF(pluginManager)
}
Expand Down
Loading

0 comments on commit 9358657

Please sign in to comment.