Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example of defining and using a plugin with the embedded component #2437

Merged
merged 1 commit into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
/* eslint-disable no-console */
import React, { useEffect, useState } from 'react'
import { PluginRecord } from '@jbrowse/core/PluginLoader'
import { observer } from 'mobx-react'
import { PluginRecord } from '@jbrowse/core/PluginLoader'
import { Region } from '@jbrowse/core/util/types'
import { createViewState, JBrowseLinearGenomeView, loadPlugins } from '../src'
import ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'
import PluginManager from '@jbrowse/core/PluginManager'
import Plugin from '@jbrowse/core/Plugin'

// locals
import { createViewState, loadPlugins, JBrowseLinearGenomeView } from '../src'

// configs
import volvoxConfig from '../public/test_data/volvox/config.json'
import volvoxSession from '../public/volvox-session.json'
import nextstrainConfig from '../public/nextstrain_covid.json'
Expand Down Expand Up @@ -52,7 +60,6 @@ export const OneLinearGenomeView = () => {
// use 1-based coordinates for locstring
location: 'ctgA:1105..1221',
onChange: patch => {
// eslint-disable-next-line no-console
console.log('patch', patch)
},
})
Expand Down Expand Up @@ -124,122 +131,6 @@ export const TwoLinearGenomeViews = () => {
)
}

export const WithPlugins = () => {
// usage with buildtime plugins
// this plugins array is then passed to the createViewState constructor
// import UCSCPlugin from 'jbrowse-plugin-ucsc'
// const plugins = [UCSCPlugin]

// usage with runtime plugins
// this plugins array is then passed to the createViewState constructor
const [plugins, setPlugins] = useState<PluginRecord[]>()
useEffect(() => {
async function getPlugins() {
const loadedPlugins = await loadPlugins([
{
name: 'UCSC',
url: 'https://unpkg.com/jbrowse-plugin-ucsc@^1/dist/jbrowse-plugin-ucsc.umd.production.min.js',
},
])
setPlugins(loadedPlugins)
}
getPlugins()
}, [setPlugins])

if (!plugins) {
return null
}

const state = createViewState({
assembly: {
name: 'hg19',
aliases: ['GRCh37'],
sequence: {
type: 'ReferenceSequenceTrack',
trackId: 'Pd8Wh30ei9R',
adapter: {
type: 'BgzipFastaAdapter',
fastaLocation: {
uri: 'https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz',
locationType: 'UriLocation',
},
faiLocation: {
uri: 'https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.fai',
locationType: 'UriLocation',
},
gziLocation: {
uri: 'https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.gzi',
locationType: 'UriLocation',
},
},
},
refNameAliases: {
adapter: {
type: 'RefNameAliasAdapter',
location: {
uri: 'https://s3.amazonaws.com/jbrowse.org/genomes/hg19/hg19_aliases.txt',
locationType: 'UriLocation',
},
},
},
},
plugins: plugins.map(p => p.plugin),
tracks: [
{
type: 'FeatureTrack',
trackId: 'segdups_ucsc_hg19',
name: 'UCSC SegDups',
category: ['Annotation'],
assemblyNames: ['hg19'],
adapter: {
type: 'UCSCAdapter',
track: 'genomicSuperDups',
},
},
],
location: '1:2,467,681..2,667,681',
defaultSession: {
name: 'Runtime plugins',
view: {
id: 'aU9Nqje1U',
type: 'LinearGenomeView',
offsetPx: 22654,
bpPerPx: 108.93300653594771,
displayedRegions: [
{
refName: '1',
start: 0,
end: 249250621,
reversed: false,
assemblyName: 'hg19',
},
],
tracks: [
{
id: 'MbiRphmDa',
type: 'FeatureTrack',
configuration: 'segdups_ucsc_hg19',
displays: [
{
id: '8ovhuA5cFM',
type: 'LinearBasicDisplay',
height: 100,
configuration: 'segdups_ucsc_hg19-LinearBasicDisplay',
},
],
},
],
hideHeader: false,
hideHeaderOverview: false,
trackSelectorType: 'hierarchical',
trackLabels: 'overlapping',
showCenterLine: false,
},
},
})
return <JBrowseLinearGenomeView viewState={state} />
}

export const WithTextSearching = () => {
const textSearchConfig = {
assembly,
Expand Down Expand Up @@ -454,7 +345,6 @@ export const NextstrainExample = () => {
defaultSession,
location: 'SARS-CoV-2:1..29,903',
onChange: patch => {
// eslint-disable-next-line no-console
console.log('patch', patch)
},
configuration: {
Expand Down Expand Up @@ -502,6 +392,183 @@ export const VisibleRegionsExample = () => {
)
}

export const WithInlinePlugin = () => {
// you don't have to necessarily define this inside your react component, it
// just helps so that you can see the source code in the storybook to have it
// here
class HighlightRegionPlugin extends Plugin {
name = 'HighlightRegionPlugin'

install(pluginManager: PluginManager) {
pluginManager.addToExtensionPoint(
'Core-extendPluggableElement',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(pluggableElement: any) => {
if (pluggableElement.name === 'LinearGenomeView') {
const { stateModel } = pluggableElement as ViewType
const newStateModel = stateModel.extend(self => {
const superRubberBandMenuItems = self.rubberBandMenuItems
return {
views: {
rubberBandMenuItems() {
return [
...superRubberBandMenuItems(),
{
label: 'Console log selected region',
onClick: () => {
const { leftOffset, rightOffset } = self
const selectedRegions = self.getSelectedRegions(
leftOffset,
rightOffset,
)
// console log the list of potentially multiple
// regions that were selected
console.log(selectedRegions)
},
},
]
},
},
}
})

pluggableElement.stateModel = newStateModel
}
return pluggableElement
},
)
}

configure() {}
}

const state = createViewState({
assembly,
plugins: [HighlightRegionPlugin],
tracks,
defaultSession,
location: 'ctgA:1105..1221',
})

return <JBrowseLinearGenomeView viewState={state} />
}

export const WithExternalPlugins = () => {
// usage with buildtime plugins
// this plugins array is then passed to the createViewState constructor
// import UCSCPlugin from 'jbrowse-plugin-ucsc'
// const plugins = [UCSCPlugin]

// usage with runtime plugins
// this plugins array is then passed to the createViewState constructor
const [plugins, setPlugins] = useState<PluginRecord[]>()
useEffect(() => {
async function getPlugins() {
const loadedPlugins = await loadPlugins([
{
name: 'UCSC',
url: 'https://unpkg.com/jbrowse-plugin-ucsc@^1/dist/jbrowse-plugin-ucsc.umd.production.min.js',
},
])
setPlugins(loadedPlugins)
}
getPlugins()
}, [setPlugins])

if (!plugins) {
return null
}

const state = createViewState({
assembly: {
name: 'hg19',
aliases: ['GRCh37'],
sequence: {
type: 'ReferenceSequenceTrack',
trackId: 'Pd8Wh30ei9R',
adapter: {
type: 'BgzipFastaAdapter',
fastaLocation: {
uri: 'https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz',
locationType: 'UriLocation',
},
faiLocation: {
uri: 'https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.fai',
locationType: 'UriLocation',
},
gziLocation: {
uri: 'https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.gzi',
locationType: 'UriLocation',
},
},
},
refNameAliases: {
adapter: {
type: 'RefNameAliasAdapter',
location: {
uri: 'https://s3.amazonaws.com/jbrowse.org/genomes/hg19/hg19_aliases.txt',
locationType: 'UriLocation',
},
},
},
},
plugins: plugins.map(p => p.plugin),
tracks: [
{
type: 'FeatureTrack',
trackId: 'segdups_ucsc_hg19',
name: 'UCSC SegDups',
category: ['Annotation'],
assemblyNames: ['hg19'],
adapter: {
type: 'UCSCAdapter',
track: 'genomicSuperDups',
},
},
],
location: '1:2,467,681..2,667,681',
defaultSession: {
name: 'Runtime plugins',
view: {
id: 'aU9Nqje1U',
type: 'LinearGenomeView',
offsetPx: 22654,
bpPerPx: 108.93300653594771,
displayedRegions: [
{
refName: '1',
start: 0,
end: 249250621,
reversed: false,
assemblyName: 'hg19',
},
],
tracks: [
{
id: 'MbiRphmDa',
type: 'FeatureTrack',
configuration: 'segdups_ucsc_hg19',
displays: [
{
id: '8ovhuA5cFM',
type: 'LinearBasicDisplay',
height: 100,
configuration: 'segdups_ucsc_hg19-LinearBasicDisplay',
},
],
},
],
hideHeader: false,
hideHeaderOverview: false,
trackSelectorType: 'hierarchical',
trackLabels: 'overlapping',
showCenterLine: false,
},
},
})
return <JBrowseLinearGenomeView viewState={state} />
}

const JBrowseLinearGenomeViewStories = {
title: 'Linear View',
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ import { Meta, Story, Canvas } from '@storybook/addon-docs/blocks'

You can use extra load a plugin at runtime for the embedded component.

This can come in the form of
This example loads a plugin that is defined in your own source code

- Plugins loaded a build time
- Plugins loaded at runtime
<Canvas withSource="open">
<Story id="linear-view--with-inline-plugins" />
</Canvas>

The build time would be installed from NPM and included in your source code for
setting up the components. The runtime ones would load e.g. from a URL, and
you'd also write some code to load those. This example shows runtime, but a
small source code comment in this example shows how build time would be used
too
This example loads a plugin from an external URL

<Canvas withSource="open">
<Story id="linear-view--with-plugins" />
<Story id="linear-view--with-external-plugins" />
</Canvas>