@jbrowse/plugin-variants 2.0.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ChordVariantDisplay/index.js +9 -9
- package/dist/ChordVariantDisplay/index.js.map +1 -1
- package/dist/ChordVariantDisplay/models/ChordVariantDisplay.js +23 -25
- package/dist/ChordVariantDisplay/models/ChordVariantDisplay.js.map +1 -1
- package/dist/LinearVariantDisplay/configSchema.js +3 -3
- package/dist/LinearVariantDisplay/configSchema.js.map +1 -1
- package/dist/LinearVariantDisplay/index.d.ts +3 -2
- package/dist/LinearVariantDisplay/index.js +17 -5
- package/dist/LinearVariantDisplay/index.js.map +1 -1
- package/dist/LinearVariantDisplay/model.js +24 -72
- package/dist/LinearVariantDisplay/model.js.map +1 -1
- package/dist/StructuralVariantChordRenderer/ReactComponent.js +57 -103
- package/dist/StructuralVariantChordRenderer/ReactComponent.js.map +1 -1
- package/dist/StructuralVariantChordRenderer/index.js +7 -7
- package/dist/StructuralVariantChordRenderer/index.js.map +1 -1
- package/dist/VariantFeatureWidget/AnnotGrid.d.ts +5 -0
- package/dist/VariantFeatureWidget/AnnotGrid.js +22 -0
- package/dist/VariantFeatureWidget/AnnotGrid.js.map +1 -0
- package/dist/VariantFeatureWidget/BreakendOptionDialog.js +23 -40
- package/dist/VariantFeatureWidget/BreakendOptionDialog.js.map +1 -1
- package/dist/VariantFeatureWidget/BreakendPanel.d.ts +7 -0
- package/dist/VariantFeatureWidget/BreakendPanel.js +82 -0
- package/dist/VariantFeatureWidget/BreakendPanel.js.map +1 -0
- package/dist/VariantFeatureWidget/VariantAnnPanel.d.ts +5 -0
- package/dist/VariantFeatureWidget/VariantAnnPanel.js +25 -0
- package/dist/VariantFeatureWidget/VariantAnnPanel.js.map +1 -0
- package/dist/VariantFeatureWidget/VariantCsqPanel.d.ts +5 -0
- package/dist/VariantFeatureWidget/VariantCsqPanel.js +25 -0
- package/dist/VariantFeatureWidget/VariantCsqPanel.js.map +1 -0
- package/dist/VariantFeatureWidget/VariantFeatureWidget.js +23 -184
- package/dist/VariantFeatureWidget/VariantFeatureWidget.js.map +1 -1
- package/dist/VariantFeatureWidget/VariantSampleGrid.d.ts +2 -0
- package/dist/VariantFeatureWidget/VariantSampleGrid.js +83 -0
- package/dist/VariantFeatureWidget/VariantSampleGrid.js.map +1 -0
- package/dist/VariantFeatureWidget/index.d.ts +2 -0
- package/dist/VariantFeatureWidget/index.js +41 -4
- package/dist/VariantFeatureWidget/index.js.map +1 -1
- package/dist/VariantTrack/index.d.ts +3 -0
- package/dist/VariantTrack/index.js +19 -0
- package/dist/VariantTrack/index.js.map +1 -0
- package/dist/VcfAdapter/VcfAdapter.js +85 -221
- package/dist/VcfAdapter/VcfAdapter.js.map +1 -1
- package/dist/VcfAdapter/configSchema.js +1 -1
- package/dist/VcfAdapter/configSchema.js.map +1 -1
- package/dist/VcfAdapter/index.d.ts +3 -1
- package/dist/VcfAdapter/index.js +32 -3
- package/dist/VcfAdapter/index.js.map +1 -1
- package/dist/VcfTabixAdapter/VcfFeature.js +76 -107
- package/dist/VcfTabixAdapter/VcfFeature.js.map +1 -1
- package/dist/VcfTabixAdapter/VcfTabixAdapter.js +88 -231
- package/dist/VcfTabixAdapter/VcfTabixAdapter.js.map +1 -1
- package/dist/VcfTabixAdapter/configSchema.js +2 -2
- package/dist/VcfTabixAdapter/configSchema.js.map +1 -1
- package/dist/VcfTabixAdapter/index.d.ts +3 -0
- package/dist/VcfTabixAdapter/index.js +34 -2
- package/dist/VcfTabixAdapter/index.js.map +1 -1
- package/dist/extensionPoints.d.ts +3 -0
- package/dist/extensionPoints.js +51 -0
- package/dist/extensionPoints.js.map +1 -0
- package/dist/index.js +24 -162
- package/dist/index.js.map +1 -1
- package/esm/LinearVariantDisplay/index.d.ts +3 -2
- package/esm/LinearVariantDisplay/index.js +17 -2
- package/esm/LinearVariantDisplay/index.js.map +1 -1
- package/esm/VariantFeatureWidget/AnnotGrid.d.ts +5 -0
- package/esm/VariantFeatureWidget/AnnotGrid.js +16 -0
- package/esm/VariantFeatureWidget/AnnotGrid.js.map +1 -0
- package/esm/VariantFeatureWidget/BreakendPanel.d.ts +7 -0
- package/esm/VariantFeatureWidget/BreakendPanel.js +53 -0
- package/esm/VariantFeatureWidget/BreakendPanel.js.map +1 -0
- package/esm/VariantFeatureWidget/VariantAnnPanel.d.ts +5 -0
- package/esm/VariantFeatureWidget/VariantAnnPanel.js +19 -0
- package/esm/VariantFeatureWidget/VariantAnnPanel.js.map +1 -0
- package/esm/VariantFeatureWidget/VariantCsqPanel.d.ts +5 -0
- package/esm/VariantFeatureWidget/VariantCsqPanel.js +19 -0
- package/esm/VariantFeatureWidget/VariantCsqPanel.js.map +1 -0
- package/esm/VariantFeatureWidget/VariantFeatureWidget.js +13 -104
- package/esm/VariantFeatureWidget/VariantFeatureWidget.js.map +1 -1
- package/esm/VariantFeatureWidget/VariantSampleGrid.d.ts +2 -0
- package/esm/VariantFeatureWidget/VariantSampleGrid.js +57 -0
- package/esm/VariantFeatureWidget/VariantSampleGrid.js.map +1 -0
- package/esm/VariantFeatureWidget/index.d.ts +2 -0
- package/esm/VariantFeatureWidget/index.js +11 -0
- package/esm/VariantFeatureWidget/index.js.map +1 -1
- package/esm/VariantTrack/index.d.ts +3 -0
- package/esm/VariantTrack/index.js +14 -0
- package/esm/VariantTrack/index.js.map +1 -0
- package/esm/VcfAdapter/VcfAdapter.js +9 -7
- package/esm/VcfAdapter/VcfAdapter.js.map +1 -1
- package/esm/VcfAdapter/index.d.ts +3 -1
- package/esm/VcfAdapter/index.js +9 -1
- package/esm/VcfAdapter/index.js.map +1 -1
- package/esm/VcfTabixAdapter/VcfFeature.js +1 -1
- package/esm/VcfTabixAdapter/VcfFeature.js.map +1 -1
- package/esm/VcfTabixAdapter/VcfTabixAdapter.js +1 -7
- package/esm/VcfTabixAdapter/VcfTabixAdapter.js.map +1 -1
- package/esm/VcfTabixAdapter/index.d.ts +3 -0
- package/esm/VcfTabixAdapter/index.js +9 -0
- package/esm/VcfTabixAdapter/index.js.map +1 -1
- package/esm/extensionPoints.d.ts +3 -0
- package/esm/extensionPoints.js +49 -0
- package/esm/extensionPoints.js.map +1 -0
- package/esm/index.js +12 -95
- package/esm/index.js.map +1 -1
- package/package.json +7 -8
- package/src/LinearVariantDisplay/index.ts +19 -2
- package/src/VariantFeatureWidget/AnnotGrid.tsx +28 -0
- package/src/VariantFeatureWidget/BreakendPanel.tsx +94 -0
- package/src/VariantFeatureWidget/VariantAnnPanel.tsx +31 -0
- package/src/VariantFeatureWidget/VariantCsqPanel.tsx +31 -0
- package/src/VariantFeatureWidget/VariantFeatureWidget.tsx +13 -198
- package/src/VariantFeatureWidget/VariantSampleGrid.tsx +105 -0
- package/src/VariantFeatureWidget/__snapshots__/VariantFeatureWidget.test.js.snap +6 -0
- package/src/VariantFeatureWidget/index.ts +15 -0
- package/src/VariantTrack/index.ts +26 -0
- package/src/VcfAdapter/VcfAdapter.ts +15 -16
- package/src/VcfAdapter/index.ts +14 -1
- package/src/VcfTabixAdapter/VcfFeature.ts +1 -1
- package/src/VcfTabixAdapter/VcfTabixAdapter.ts +1 -7
- package/src/VcfTabixAdapter/index.ts +15 -0
- package/src/__snapshots__/index.test.js.snap +4 -4
- package/src/extensionPoints.ts +74 -0
- package/src/index.ts +12 -155
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import React, { useState } from 'react'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
FormControlLabel,
|
|
6
|
+
Checkbox,
|
|
7
|
+
TextField,
|
|
8
|
+
Typography,
|
|
9
|
+
} from '@mui/material'
|
|
10
|
+
|
|
11
|
+
import { DataGrid } from '@mui/x-data-grid'
|
|
12
|
+
import { BaseCard } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
|
|
13
|
+
|
|
14
|
+
export default function VariantSamples(props: any) {
|
|
15
|
+
const [filter, setFilter] = useState<any>({})
|
|
16
|
+
const [showFilters, setShowFilters] = useState(false)
|
|
17
|
+
const { feature } = props
|
|
18
|
+
|
|
19
|
+
const { samples = {} } = feature
|
|
20
|
+
const preFilteredRows: any = Object.entries(samples)
|
|
21
|
+
if (!preFilteredRows.length) {
|
|
22
|
+
return null
|
|
23
|
+
}
|
|
24
|
+
const infoFields = ['sample', ...Object.keys(preFilteredRows[0][1])].map(
|
|
25
|
+
field => ({
|
|
26
|
+
field,
|
|
27
|
+
}),
|
|
28
|
+
)
|
|
29
|
+
let error
|
|
30
|
+
let rows = []
|
|
31
|
+
const filters = Object.keys(filter)
|
|
32
|
+
|
|
33
|
+
// catch some error thrown from regex
|
|
34
|
+
// note: maps all values into a string, if this is not done rows are not
|
|
35
|
+
// sortable by the data-grid
|
|
36
|
+
try {
|
|
37
|
+
rows = preFilteredRows
|
|
38
|
+
.map((row: any) => ({
|
|
39
|
+
...Object.fromEntries(
|
|
40
|
+
Object.entries(row[1]).map(entry => [entry[0], String(entry[1])]),
|
|
41
|
+
),
|
|
42
|
+
sample: row[0],
|
|
43
|
+
id: row[0],
|
|
44
|
+
}))
|
|
45
|
+
.filter((row: any) => {
|
|
46
|
+
return filters.length
|
|
47
|
+
? filters.every(key => {
|
|
48
|
+
const val = row[key]
|
|
49
|
+
const currFilter = filter[key]
|
|
50
|
+
return currFilter ? val.match(new RegExp(currFilter, 'i')) : true
|
|
51
|
+
})
|
|
52
|
+
: true
|
|
53
|
+
})
|
|
54
|
+
} catch (e) {
|
|
55
|
+
error = e
|
|
56
|
+
}
|
|
57
|
+
// disableSelectionOnClick helps avoid
|
|
58
|
+
// https://github.com/mui-org/material-ui-x/issues/1197
|
|
59
|
+
return (
|
|
60
|
+
<BaseCard {...props} title="Samples">
|
|
61
|
+
{error ? <Typography color="error">{`${error}`}</Typography> : null}
|
|
62
|
+
|
|
63
|
+
<FormControlLabel
|
|
64
|
+
control={
|
|
65
|
+
<Checkbox
|
|
66
|
+
checked={showFilters}
|
|
67
|
+
onChange={() => setShowFilters(f => !f)}
|
|
68
|
+
/>
|
|
69
|
+
}
|
|
70
|
+
label="Show sample filters"
|
|
71
|
+
/>
|
|
72
|
+
{showFilters ? (
|
|
73
|
+
<>
|
|
74
|
+
<Typography>
|
|
75
|
+
These filters can use a plain text search or regex style query, e.g.
|
|
76
|
+
in the genotype field, entering 1 will query for all genotypes that
|
|
77
|
+
include the first alternate allele e.g. 0|1 or 1|1, entering
|
|
78
|
+
[1-9]\d* will find any non-zero allele e.g. 0|2 or 2/33
|
|
79
|
+
</Typography>
|
|
80
|
+
{infoFields.map(({ field }) => {
|
|
81
|
+
return (
|
|
82
|
+
<TextField
|
|
83
|
+
key={`filter-${field}`}
|
|
84
|
+
placeholder={`Filter ${field}`}
|
|
85
|
+
value={filter[field] || ''}
|
|
86
|
+
onChange={event =>
|
|
87
|
+
setFilter({ ...filter, [field]: event.target.value })
|
|
88
|
+
}
|
|
89
|
+
/>
|
|
90
|
+
)
|
|
91
|
+
})}
|
|
92
|
+
</>
|
|
93
|
+
) : null}
|
|
94
|
+
<div style={{ height: 600, width: '100%', overflow: 'auto' }}>
|
|
95
|
+
<DataGrid
|
|
96
|
+
rows={rows}
|
|
97
|
+
columns={infoFields}
|
|
98
|
+
disableSelectionOnClick
|
|
99
|
+
rowHeight={25}
|
|
100
|
+
disableColumnMenu
|
|
101
|
+
/>
|
|
102
|
+
</div>
|
|
103
|
+
</BaseCard>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
@@ -198,5 +198,11 @@ exports[`VariantTrack widget renders with just the required model elements 1`] =
|
|
|
198
198
|
<hr
|
|
199
199
|
class="MuiDivider-root MuiDivider-fullWidth css-9mgopn-MuiDivider-root"
|
|
200
200
|
/>
|
|
201
|
+
<hr
|
|
202
|
+
class="MuiDivider-root MuiDivider-fullWidth css-9mgopn-MuiDivider-root"
|
|
203
|
+
/>
|
|
204
|
+
<hr
|
|
205
|
+
class="MuiDivider-root MuiDivider-fullWidth css-9mgopn-MuiDivider-root"
|
|
206
|
+
/>
|
|
201
207
|
</div>
|
|
202
208
|
`;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { lazy } from 'react'
|
|
1
2
|
import { ConfigurationSchema } from '@jbrowse/core/configuration'
|
|
3
|
+
import WidgetType from '@jbrowse/core/pluggableElementTypes/WidgetType'
|
|
2
4
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
3
5
|
import { types } from 'mobx-state-tree'
|
|
4
6
|
import { stateModelFactory as baseModelFactory } from '@jbrowse/core/BaseFeatureWidget'
|
|
@@ -15,3 +17,16 @@ export function stateModelFactory(pluginManager: PluginManager) {
|
|
|
15
17
|
}),
|
|
16
18
|
)
|
|
17
19
|
}
|
|
20
|
+
|
|
21
|
+
export default (pluginManager: PluginManager) => {
|
|
22
|
+
pluginManager.addWidgetType(
|
|
23
|
+
() =>
|
|
24
|
+
new WidgetType({
|
|
25
|
+
name: 'VariantFeatureWidget',
|
|
26
|
+
heading: 'Feature details',
|
|
27
|
+
configSchema,
|
|
28
|
+
stateModel: stateModelFactory(pluginManager),
|
|
29
|
+
ReactComponent: lazy(() => import('./VariantFeatureWidget')),
|
|
30
|
+
}),
|
|
31
|
+
)
|
|
32
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import PluginManager from '@jbrowse/core/PluginManager'
|
|
2
|
+
import { ConfigurationSchema } from '@jbrowse/core/configuration'
|
|
3
|
+
import TrackType from '@jbrowse/core/pluggableElementTypes/TrackType'
|
|
4
|
+
import {
|
|
5
|
+
createBaseTrackConfig,
|
|
6
|
+
createBaseTrackModel,
|
|
7
|
+
} from '@jbrowse/core/pluggableElementTypes/models'
|
|
8
|
+
|
|
9
|
+
export default (pluginManager: PluginManager) => {
|
|
10
|
+
pluginManager.addTrackType(() => {
|
|
11
|
+
const configSchema = ConfigurationSchema(
|
|
12
|
+
'VariantTrack',
|
|
13
|
+
{},
|
|
14
|
+
{ baseConfiguration: createBaseTrackConfig(pluginManager) },
|
|
15
|
+
)
|
|
16
|
+
return new TrackType({
|
|
17
|
+
name: 'VariantTrack',
|
|
18
|
+
configSchema,
|
|
19
|
+
stateModel: createBaseTrackModel(
|
|
20
|
+
pluginManager,
|
|
21
|
+
'VariantTrack',
|
|
22
|
+
configSchema,
|
|
23
|
+
),
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
}
|
|
@@ -6,23 +6,24 @@ import { Region } from '@jbrowse/core/util/types'
|
|
|
6
6
|
import { openLocation } from '@jbrowse/core/util/io'
|
|
7
7
|
import { ObservableCreate } from '@jbrowse/core/util/rxjs'
|
|
8
8
|
import { Feature } from '@jbrowse/core/util/simpleFeature'
|
|
9
|
-
import { readConfObject } from '@jbrowse/core/configuration'
|
|
10
9
|
import IntervalTree from '@flatten-js/interval-tree'
|
|
11
10
|
import { unzip } from '@gmod/bgzf-filehandle'
|
|
12
11
|
import VCF from '@gmod/vcf'
|
|
13
12
|
import VcfFeature from '../VcfTabixAdapter/VcfFeature'
|
|
14
13
|
|
|
15
14
|
const readVcf = (f: string) => {
|
|
16
|
-
const lines = f.split('\n')
|
|
17
15
|
const header: string[] = []
|
|
18
16
|
const rest: string[] = []
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
f.split('\n')
|
|
18
|
+
.map(f => f.trim())
|
|
19
|
+
.filter(f => !!f)
|
|
20
|
+
.forEach(line => {
|
|
21
|
+
if (line.startsWith('#')) {
|
|
22
|
+
header.push(line)
|
|
23
|
+
} else if (line) {
|
|
24
|
+
rest.push(line)
|
|
25
|
+
}
|
|
26
|
+
})
|
|
26
27
|
return { header: header.join('\n'), lines: rest }
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -51,19 +52,17 @@ export default class VcfAdapter extends BaseFeatureDataAdapter {
|
|
|
51
52
|
|
|
52
53
|
// converts lines into an interval tree
|
|
53
54
|
public async setupP() {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
this.pluginManager,
|
|
57
|
-
).readFile()
|
|
55
|
+
const pm = this.pluginManager
|
|
56
|
+
const buf = await openLocation(this.getConf('vcfLocation'), pm).readFile()
|
|
58
57
|
|
|
59
|
-
const
|
|
58
|
+
const buffer = isGzip(buf) ? await unzip(buf) : buf
|
|
60
59
|
|
|
61
60
|
// 512MB max chrome string length is 512MB
|
|
62
|
-
if (
|
|
61
|
+
if (buffer.length > 536_870_888) {
|
|
63
62
|
throw new Error('Data exceeds maximum string length (512MB)')
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
const str = new TextDecoder().decode(
|
|
65
|
+
const str = new TextDecoder().decode(buffer)
|
|
67
66
|
const { header, lines } = readVcf(str)
|
|
68
67
|
|
|
69
68
|
const intervalTree = lines
|
package/src/VcfAdapter/index.ts
CHANGED
|
@@ -1 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import PluginManager from '@jbrowse/core/PluginManager'
|
|
2
|
+
import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'
|
|
3
|
+
import configSchema from './configSchema'
|
|
4
|
+
|
|
5
|
+
export default (pluginManager: PluginManager) => {
|
|
6
|
+
pluginManager.addAdapterType(
|
|
7
|
+
() =>
|
|
8
|
+
new AdapterType({
|
|
9
|
+
name: 'VcfAdapter',
|
|
10
|
+
configSchema,
|
|
11
|
+
getAdapterClass: () => import('./VcfAdapter').then(r => r.default),
|
|
12
|
+
}),
|
|
13
|
+
)
|
|
14
|
+
}
|
|
@@ -106,7 +106,7 @@ export default class VCFFeature implements Feature {
|
|
|
106
106
|
alt: string[],
|
|
107
107
|
): [string, string] | [undefined, undefined] {
|
|
108
108
|
// it's just a remark if there are no alternate alleles
|
|
109
|
-
if (!alt || alt ===
|
|
109
|
+
if (!alt || alt.length === 0) {
|
|
110
110
|
return ['remark', 'no alternative alleles']
|
|
111
111
|
}
|
|
112
112
|
|
|
@@ -118,9 +118,6 @@ export default class extends BaseFeatureDataAdapter {
|
|
|
118
118
|
regions: Region[],
|
|
119
119
|
opts: BaseOptions = {},
|
|
120
120
|
) {
|
|
121
|
-
// TODO: restore commented version below once TSDX supports Rollup v2
|
|
122
|
-
// xref: https://github.com/rollup/rollup/blob/master/CHANGELOG.md#bug-fixes-45
|
|
123
|
-
const superGetFeaturesInMultipleRegions = super.getFeaturesInMultipleRegions
|
|
124
121
|
return ObservableCreate<Feature>(async (observer: Observer<Feature>) => {
|
|
125
122
|
const { vcf } = await this.configure()
|
|
126
123
|
|
|
@@ -138,10 +135,7 @@ export default class extends BaseFeatureDataAdapter {
|
|
|
138
135
|
`getFeaturesInMultipleRegions fetching ${pct}% of VCF file, but whole-file streaming not yet implemented`,
|
|
139
136
|
)
|
|
140
137
|
}
|
|
141
|
-
|
|
142
|
-
.call(this, regions, opts)
|
|
143
|
-
.subscribe(observer)
|
|
144
|
-
// super.getFeaturesInMultipleRegions(regions, opts).subscribe(observer)
|
|
138
|
+
super.getFeaturesInMultipleRegions(regions, opts).subscribe(observer)
|
|
145
139
|
})
|
|
146
140
|
}
|
|
147
141
|
|
|
@@ -1 +1,16 @@
|
|
|
1
|
+
import PluginManager from '@jbrowse/core/PluginManager'
|
|
2
|
+
import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'
|
|
3
|
+
import configSchema from './configSchema'
|
|
4
|
+
|
|
1
5
|
export { default as configSchema } from './configSchema'
|
|
6
|
+
|
|
7
|
+
export default (pluginManager: PluginManager) => {
|
|
8
|
+
pluginManager.addAdapterType(
|
|
9
|
+
() =>
|
|
10
|
+
new AdapterType({
|
|
11
|
+
name: 'VcfTabixAdapter',
|
|
12
|
+
configSchema,
|
|
13
|
+
getAdapterClass: () => import('./VcfTabixAdapter').then(r => r.default),
|
|
14
|
+
}),
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -5,14 +5,14 @@ exports[`plugin in a stock JBrowse 1`] = `Object {}`;
|
|
|
5
5
|
exports[`plugin in a stock JBrowse 2`] = `
|
|
6
6
|
Object {
|
|
7
7
|
"displays": Array [
|
|
8
|
-
Object {
|
|
9
|
-
"displayId": "trackId0-ChordVariantDisplay",
|
|
10
|
-
"type": "ChordVariantDisplay",
|
|
11
|
-
},
|
|
12
8
|
Object {
|
|
13
9
|
"displayId": "trackId0-LinearVariantDisplay",
|
|
14
10
|
"type": "LinearVariantDisplay",
|
|
15
11
|
},
|
|
12
|
+
Object {
|
|
13
|
+
"displayId": "trackId0-ChordVariantDisplay",
|
|
14
|
+
"type": "ChordVariantDisplay",
|
|
15
|
+
},
|
|
16
16
|
],
|
|
17
17
|
"trackId": "trackId0",
|
|
18
18
|
"type": "VariantTrack",
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import PluginManager from '@jbrowse/core/PluginManager'
|
|
2
|
+
import { FileLocation } from '@jbrowse/core/util/types'
|
|
3
|
+
import {
|
|
4
|
+
makeIndex,
|
|
5
|
+
makeIndexType,
|
|
6
|
+
getFileName,
|
|
7
|
+
AdapterGuesser,
|
|
8
|
+
TrackTypeGuesser,
|
|
9
|
+
} from '@jbrowse/core/util/tracks'
|
|
10
|
+
|
|
11
|
+
export default (pluginManager: PluginManager) => {
|
|
12
|
+
pluginManager.addToExtensionPoint(
|
|
13
|
+
'Core-guessAdapterForLocation',
|
|
14
|
+
(adapterGuesser: AdapterGuesser) => {
|
|
15
|
+
return (
|
|
16
|
+
file: FileLocation,
|
|
17
|
+
index?: FileLocation,
|
|
18
|
+
adapterHint?: string,
|
|
19
|
+
) => {
|
|
20
|
+
const regexGuess = /\.vcf\.b?gz$/i
|
|
21
|
+
const adapterName = 'VcfTabixAdapter'
|
|
22
|
+
const fileName = getFileName(file)
|
|
23
|
+
const indexName = index && getFileName(index)
|
|
24
|
+
const obj = {
|
|
25
|
+
type: adapterName,
|
|
26
|
+
vcfGzLocation: file,
|
|
27
|
+
index: {
|
|
28
|
+
location: index || makeIndex(file, '.tbi'),
|
|
29
|
+
indexType: makeIndexType(indexName, 'CSI', 'TBI'),
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
if (regexGuess.test(fileName) && !adapterHint) {
|
|
33
|
+
return obj
|
|
34
|
+
} else if (adapterHint === adapterName) {
|
|
35
|
+
return obj
|
|
36
|
+
}
|
|
37
|
+
return adapterGuesser(file, index, adapterHint)
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
)
|
|
41
|
+
pluginManager.addToExtensionPoint(
|
|
42
|
+
'Core-guessTrackTypeForLocation',
|
|
43
|
+
(trackTypeGuesser: TrackTypeGuesser) => {
|
|
44
|
+
return (adapterName: string) => {
|
|
45
|
+
if (adapterName === 'VcfTabixAdapter' || adapterName === 'VcfAdapter') {
|
|
46
|
+
return 'VariantTrack'
|
|
47
|
+
}
|
|
48
|
+
return trackTypeGuesser(adapterName)
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
pluginManager.addToExtensionPoint(
|
|
54
|
+
'Core-guessAdapterForLocation',
|
|
55
|
+
(adapterGuesser: AdapterGuesser) => {
|
|
56
|
+
return (
|
|
57
|
+
file: FileLocation,
|
|
58
|
+
index?: FileLocation,
|
|
59
|
+
adapterHint?: string,
|
|
60
|
+
) => {
|
|
61
|
+
const regexGuess = /\.vcf$/i
|
|
62
|
+
const adapterName = 'VcfAdapter'
|
|
63
|
+
const fileName = getFileName(file)
|
|
64
|
+
if (regexGuess.test(fileName) || adapterHint === adapterName) {
|
|
65
|
+
return {
|
|
66
|
+
type: adapterName,
|
|
67
|
+
vcfLocation: file,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return adapterGuesser(file, index, adapterHint)
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
)
|
|
74
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,175 +1,32 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
createBaseTrackConfig,
|
|
7
|
-
createBaseTrackModel,
|
|
8
|
-
} from '@jbrowse/core/pluggableElementTypes/models'
|
|
9
|
-
import { FileLocation } from '@jbrowse/core/util/types'
|
|
10
|
-
import TrackType from '@jbrowse/core/pluggableElementTypes/TrackType'
|
|
11
|
-
import WidgetType from '@jbrowse/core/pluggableElementTypes/WidgetType'
|
|
1
|
+
import VcfAdapterF from './VcfAdapter'
|
|
2
|
+
import VcfTabixAdapterF from './VcfTabixAdapter'
|
|
3
|
+
import ExtensionPointsF from './extensionPoints'
|
|
4
|
+
import VariantTrackF from './VariantTrack'
|
|
12
5
|
import Plugin from '@jbrowse/core/Plugin'
|
|
13
6
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
14
|
-
import { BaseLinearDisplayComponent } from '@jbrowse/plugin-linear-genome-view'
|
|
15
7
|
import ChordVariantDisplay from './ChordVariantDisplay'
|
|
16
|
-
import
|
|
17
|
-
configSchemaFactory as linearVariantDisplayConfigSchemaFactory,
|
|
18
|
-
modelFactory as linearVariantDisplayModelFactory,
|
|
19
|
-
} from './LinearVariantDisplay'
|
|
8
|
+
import LinearVariantDisplayF from './LinearVariantDisplay'
|
|
20
9
|
import StructuralVariantChordRendererFactory from './StructuralVariantChordRenderer'
|
|
21
|
-
import
|
|
22
|
-
configSchema as variantFeatureWidgetConfigSchema,
|
|
23
|
-
stateModelFactory as variantFeatureWidgetStateModelFactory,
|
|
24
|
-
} from './VariantFeatureWidget'
|
|
25
|
-
import { configSchema as vcfTabixAdapterConfigSchema } from './VcfTabixAdapter'
|
|
26
|
-
import { configSchema as vcfAdapterConfigSchema } from './VcfAdapter'
|
|
27
|
-
import {
|
|
28
|
-
makeIndex,
|
|
29
|
-
makeIndexType,
|
|
30
|
-
AdapterGuesser,
|
|
31
|
-
getFileName,
|
|
32
|
-
TrackTypeGuesser,
|
|
33
|
-
} from '@jbrowse/core/util/tracks'
|
|
10
|
+
import VariantFeatureWidgetF from './VariantFeatureWidget'
|
|
34
11
|
|
|
35
12
|
export default class VariantsPlugin extends Plugin {
|
|
36
13
|
name = 'VariantsPlugin'
|
|
37
14
|
|
|
38
15
|
install(pluginManager: PluginManager) {
|
|
39
|
-
pluginManager
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
import('./VcfTabixAdapter/VcfTabixAdapter').then(r => r.default),
|
|
46
|
-
}),
|
|
47
|
-
)
|
|
48
|
-
pluginManager.addToExtensionPoint(
|
|
49
|
-
'Core-guessAdapterForLocation',
|
|
50
|
-
(adapterGuesser: AdapterGuesser) => {
|
|
51
|
-
return (
|
|
52
|
-
file: FileLocation,
|
|
53
|
-
index?: FileLocation,
|
|
54
|
-
adapterHint?: string,
|
|
55
|
-
) => {
|
|
56
|
-
const regexGuess = /\.vcf\.b?gz$/i
|
|
57
|
-
const adapterName = 'VcfTabixAdapter'
|
|
58
|
-
const fileName = getFileName(file)
|
|
59
|
-
const indexName = index && getFileName(index)
|
|
60
|
-
const obj = {
|
|
61
|
-
type: adapterName,
|
|
62
|
-
vcfGzLocation: file,
|
|
63
|
-
index: {
|
|
64
|
-
location: index || makeIndex(file, '.tbi'),
|
|
65
|
-
indexType: makeIndexType(indexName, 'CSI', 'TBI'),
|
|
66
|
-
},
|
|
67
|
-
}
|
|
68
|
-
if (regexGuess.test(fileName) && !adapterHint) {
|
|
69
|
-
return obj
|
|
70
|
-
} else if (adapterHint === adapterName) {
|
|
71
|
-
return obj
|
|
72
|
-
}
|
|
73
|
-
return adapterGuesser(file, index, adapterHint)
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
)
|
|
77
|
-
pluginManager.addToExtensionPoint(
|
|
78
|
-
'Core-guessTrackTypeForLocation',
|
|
79
|
-
(trackTypeGuesser: TrackTypeGuesser) => {
|
|
80
|
-
return (adapterName: string) => {
|
|
81
|
-
if (
|
|
82
|
-
adapterName === 'VcfTabixAdapter' ||
|
|
83
|
-
adapterName === 'VcfAdapter'
|
|
84
|
-
) {
|
|
85
|
-
return 'VariantTrack'
|
|
86
|
-
}
|
|
87
|
-
return trackTypeGuesser(adapterName)
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
pluginManager.addAdapterType(
|
|
93
|
-
() =>
|
|
94
|
-
new AdapterType({
|
|
95
|
-
name: 'VcfAdapter',
|
|
96
|
-
configSchema: vcfAdapterConfigSchema,
|
|
97
|
-
getAdapterClass: () =>
|
|
98
|
-
import('./VcfAdapter/VcfAdapter').then(r => r.default),
|
|
99
|
-
}),
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
pluginManager.addToExtensionPoint(
|
|
103
|
-
'Core-guessAdapterForLocation',
|
|
104
|
-
(adapterGuesser: AdapterGuesser) => {
|
|
105
|
-
return (
|
|
106
|
-
file: FileLocation,
|
|
107
|
-
index?: FileLocation,
|
|
108
|
-
adapterHint?: string,
|
|
109
|
-
) => {
|
|
110
|
-
const regexGuess = /\.vcf$/i
|
|
111
|
-
const adapterName = 'VcfAdapter'
|
|
112
|
-
const fileName = getFileName(file)
|
|
113
|
-
if (regexGuess.test(fileName) || adapterHint === adapterName) {
|
|
114
|
-
return {
|
|
115
|
-
type: adapterName,
|
|
116
|
-
vcfLocation: file,
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return adapterGuesser(file, index, adapterHint)
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
)
|
|
16
|
+
VcfAdapterF(pluginManager)
|
|
17
|
+
VcfTabixAdapterF(pluginManager)
|
|
18
|
+
VariantFeatureWidgetF(pluginManager)
|
|
19
|
+
VariantTrackF(pluginManager)
|
|
20
|
+
ExtensionPointsF(pluginManager)
|
|
21
|
+
LinearVariantDisplayF(pluginManager)
|
|
123
22
|
|
|
124
23
|
pluginManager.addRendererType(() =>
|
|
125
24
|
pluginManager.jbrequire(StructuralVariantChordRendererFactory),
|
|
126
25
|
)
|
|
127
|
-
pluginManager.addTrackType(() => {
|
|
128
|
-
const configSchema = ConfigurationSchema(
|
|
129
|
-
'VariantTrack',
|
|
130
|
-
{},
|
|
131
|
-
{ baseConfiguration: createBaseTrackConfig(pluginManager) },
|
|
132
|
-
)
|
|
133
|
-
return new TrackType({
|
|
134
|
-
name: 'VariantTrack',
|
|
135
|
-
configSchema,
|
|
136
|
-
stateModel: createBaseTrackModel(
|
|
137
|
-
pluginManager,
|
|
138
|
-
'VariantTrack',
|
|
139
|
-
configSchema,
|
|
140
|
-
),
|
|
141
|
-
})
|
|
142
|
-
})
|
|
143
26
|
|
|
144
27
|
pluginManager.addDisplayType(() =>
|
|
145
28
|
pluginManager.jbrequire(ChordVariantDisplay),
|
|
146
29
|
)
|
|
147
|
-
|
|
148
|
-
pluginManager.addDisplayType(() => {
|
|
149
|
-
const configSchema =
|
|
150
|
-
linearVariantDisplayConfigSchemaFactory(pluginManager)
|
|
151
|
-
return new DisplayType({
|
|
152
|
-
name: 'LinearVariantDisplay',
|
|
153
|
-
configSchema,
|
|
154
|
-
stateModel: linearVariantDisplayModelFactory(configSchema),
|
|
155
|
-
trackType: 'VariantTrack',
|
|
156
|
-
viewType: 'LinearGenomeView',
|
|
157
|
-
ReactComponent: BaseLinearDisplayComponent,
|
|
158
|
-
})
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
pluginManager.addWidgetType(
|
|
162
|
-
() =>
|
|
163
|
-
new WidgetType({
|
|
164
|
-
name: 'VariantFeatureWidget',
|
|
165
|
-
heading: 'Feature details',
|
|
166
|
-
configSchema: variantFeatureWidgetConfigSchema,
|
|
167
|
-
stateModel: variantFeatureWidgetStateModelFactory(pluginManager),
|
|
168
|
-
ReactComponent: lazy(
|
|
169
|
-
() => import('./VariantFeatureWidget/VariantFeatureWidget'),
|
|
170
|
-
),
|
|
171
|
-
}),
|
|
172
|
-
)
|
|
173
30
|
}
|
|
174
31
|
}
|
|
175
32
|
|