@jbrowse/plugin-variants 2.2.2 → 2.3.0
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 +1 -0
- package/dist/ChordVariantDisplay/index.js.map +1 -1
- package/dist/ChordVariantDisplay/models/stateModelFactory.d.ts +4 -2
- package/dist/ChordVariantDisplay/models/stateModelFactory.js +1 -2
- package/dist/ChordVariantDisplay/models/stateModelFactory.js.map +1 -1
- package/dist/LinearVariantDisplay/index.js +1 -0
- package/dist/LinearVariantDisplay/index.js.map +1 -1
- package/dist/LinearVariantDisplay/model.d.ts +1 -1
- package/dist/StructuralVariantChordRenderer/Chord.d.ts +32 -0
- package/dist/StructuralVariantChordRenderer/Chord.js +88 -0
- package/dist/StructuralVariantChordRenderer/Chord.js.map +1 -0
- package/dist/StructuralVariantChordRenderer/ReactComponent.d.ts +1 -17
- package/dist/StructuralVariantChordRenderer/ReactComponent.js +11 -93
- package/dist/StructuralVariantChordRenderer/ReactComponent.js.map +1 -1
- package/dist/StructuralVariantChordRenderer/index.d.ts +2 -2
- package/dist/StructuralVariantChordRenderer/index.js +2 -2
- package/dist/StructuralVariantChordRenderer/index.js.map +1 -1
- package/dist/VariantFeatureWidget/BreakendOptionDialog.js +12 -7
- package/dist/VariantFeatureWidget/BreakendOptionDialog.js.map +1 -1
- package/dist/VariantTrack/index.js +1 -0
- package/dist/VariantTrack/index.js.map +1 -1
- package/dist/VcfAdapter/VcfAdapter.js +1 -0
- package/dist/VcfAdapter/VcfAdapter.js.map +1 -1
- package/dist/VcfAdapter/index.js +1 -0
- package/dist/VcfAdapter/index.js.map +1 -1
- package/dist/VcfTabixAdapter/VcfTabixAdapter.js +8 -11
- package/dist/VcfTabixAdapter/VcfTabixAdapter.js.map +1 -1
- package/dist/VcfTabixAdapter/index.js +1 -0
- package/dist/VcfTabixAdapter/index.js.map +1 -1
- package/esm/ChordVariantDisplay/index.js +1 -0
- package/esm/ChordVariantDisplay/index.js.map +1 -1
- package/esm/ChordVariantDisplay/models/stateModelFactory.d.ts +4 -2
- package/esm/ChordVariantDisplay/models/stateModelFactory.js +1 -2
- package/esm/ChordVariantDisplay/models/stateModelFactory.js.map +1 -1
- package/esm/LinearVariantDisplay/index.js +1 -0
- package/esm/LinearVariantDisplay/index.js.map +1 -1
- package/esm/LinearVariantDisplay/model.d.ts +1 -1
- package/esm/StructuralVariantChordRenderer/Chord.d.ts +32 -0
- package/esm/StructuralVariantChordRenderer/Chord.js +83 -0
- package/esm/StructuralVariantChordRenderer/Chord.js.map +1 -0
- package/esm/StructuralVariantChordRenderer/ReactComponent.d.ts +1 -17
- package/esm/StructuralVariantChordRenderer/ReactComponent.js +7 -92
- package/esm/StructuralVariantChordRenderer/ReactComponent.js.map +1 -1
- package/esm/StructuralVariantChordRenderer/index.d.ts +2 -2
- package/esm/StructuralVariantChordRenderer/index.js +2 -2
- package/esm/StructuralVariantChordRenderer/index.js.map +1 -1
- package/esm/VariantFeatureWidget/BreakendOptionDialog.js +12 -7
- package/esm/VariantFeatureWidget/BreakendOptionDialog.js.map +1 -1
- package/esm/VariantTrack/index.js +1 -0
- package/esm/VariantTrack/index.js.map +1 -1
- package/esm/VcfAdapter/VcfAdapter.js +1 -0
- package/esm/VcfAdapter/VcfAdapter.js.map +1 -1
- package/esm/VcfAdapter/index.js +1 -0
- package/esm/VcfAdapter/index.js.map +1 -1
- package/esm/VcfTabixAdapter/VcfTabixAdapter.js +8 -11
- package/esm/VcfTabixAdapter/VcfTabixAdapter.js.map +1 -1
- package/esm/VcfTabixAdapter/index.js +1 -0
- package/esm/VcfTabixAdapter/index.js.map +1 -1
- package/package.json +3 -4
- package/src/ChordVariantDisplay/index.ts +1 -0
- package/src/ChordVariantDisplay/models/stateModelFactory.ts +1 -3
- package/src/LinearVariantDisplay/index.ts +1 -0
- package/src/StructuralVariantChordRenderer/Chord.tsx +141 -0
- package/src/StructuralVariantChordRenderer/ReactComponent.tsx +10 -149
- package/src/StructuralVariantChordRenderer/index.ts +2 -3
- package/src/VariantFeatureWidget/BreakendOptionDialog.tsx +15 -8
- package/src/VariantTrack/index.ts +1 -0
- package/src/VcfAdapter/VcfAdapter.ts +2 -0
- package/src/VcfAdapter/index.ts +1 -0
- package/src/VcfTabixAdapter/VcfTabixAdapter.ts +10 -15
- package/src/VcfTabixAdapter/index.ts +1 -0
- package/dist/ChordVariantDisplay/models/ChordVariantDisplay.d.ts +0 -117
- package/dist/ChordVariantDisplay/models/ChordVariantDisplay.js +0 -62
- package/dist/ChordVariantDisplay/models/ChordVariantDisplay.js.map +0 -1
- package/esm/ChordVariantDisplay/models/ChordVariantDisplay.d.ts +0 -117
- package/esm/ChordVariantDisplay/models/ChordVariantDisplay.js +0 -57
- package/esm/ChordVariantDisplay/models/ChordVariantDisplay.js.map +0 -1
- package/src/ChordVariantDisplay/models/ChordVariantDisplay.ts +0 -69
|
@@ -46,9 +46,7 @@ const stateModelFactory = (configSchema: AnyConfigurationSchemaType) => {
|
|
|
46
46
|
displayModel: self,
|
|
47
47
|
bezierRadius: view.radiusPx * self.bezierRadiusRatio,
|
|
48
48
|
radius: view.radiusPx,
|
|
49
|
-
|
|
50
|
-
// @ts-ignore
|
|
51
|
-
blockDefinitions: this.blockDefinitions,
|
|
49
|
+
blockDefinitions: self.blockDefinitions,
|
|
52
50
|
config: self.configuration.renderer,
|
|
53
51
|
onChordClick: self.onChordClick,
|
|
54
52
|
}
|
|
@@ -9,6 +9,7 @@ export default (pluginManager: PluginManager) => {
|
|
|
9
9
|
const configSchema = configSchemaF(pluginManager)
|
|
10
10
|
return new DisplayType({
|
|
11
11
|
name: 'LinearVariantDisplay',
|
|
12
|
+
displayName: 'Variant display',
|
|
12
13
|
configSchema,
|
|
13
14
|
stateModel: stateModelFactory(configSchema),
|
|
14
15
|
trackType: 'VariantTrack',
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { observer } from 'mobx-react'
|
|
3
|
+
import { polarToCartesian, Feature } from '@jbrowse/core/util'
|
|
4
|
+
import {
|
|
5
|
+
AnyConfigurationModel,
|
|
6
|
+
readConfObject,
|
|
7
|
+
} from '@jbrowse/core/configuration'
|
|
8
|
+
import { parseBreakend } from '@gmod/vcf'
|
|
9
|
+
|
|
10
|
+
export interface Region {
|
|
11
|
+
end: number
|
|
12
|
+
start: number
|
|
13
|
+
refName: string
|
|
14
|
+
elided?: false
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ElidedRegion {
|
|
18
|
+
elided: true
|
|
19
|
+
regions: Region[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type AnyRegion = Region | ElidedRegion
|
|
23
|
+
|
|
24
|
+
export interface Block {
|
|
25
|
+
flipped: boolean
|
|
26
|
+
bpPerRadian: number
|
|
27
|
+
startRadians: number
|
|
28
|
+
region: AnyRegion
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function bpToRadians(block: Block, pos: number) {
|
|
32
|
+
const blockStart = block.region.elided ? 0 : block.region.start
|
|
33
|
+
const blockEnd = block.region.elided ? 0 : block.region.end
|
|
34
|
+
const bpOffset = block.flipped ? blockEnd - pos : pos - blockStart
|
|
35
|
+
return bpOffset / block.bpPerRadian + block.startRadians
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const Chord = observer(function Chord({
|
|
39
|
+
feature,
|
|
40
|
+
blocksForRefs,
|
|
41
|
+
radius,
|
|
42
|
+
config,
|
|
43
|
+
bezierRadius,
|
|
44
|
+
selected,
|
|
45
|
+
onClick,
|
|
46
|
+
}: {
|
|
47
|
+
feature: Feature
|
|
48
|
+
blocksForRefs: { [key: string]: Block }
|
|
49
|
+
radius: number
|
|
50
|
+
config: AnyConfigurationModel
|
|
51
|
+
bezierRadius: number
|
|
52
|
+
selected: boolean
|
|
53
|
+
onClick: (
|
|
54
|
+
feature: Feature,
|
|
55
|
+
reg: AnyRegion,
|
|
56
|
+
endBlock: AnyRegion,
|
|
57
|
+
evt: unknown,
|
|
58
|
+
) => void
|
|
59
|
+
}) {
|
|
60
|
+
// find the blocks that our start and end points belong to
|
|
61
|
+
const startBlock = blocksForRefs[feature.get('refName')]
|
|
62
|
+
if (!startBlock) {
|
|
63
|
+
return null
|
|
64
|
+
}
|
|
65
|
+
let svType
|
|
66
|
+
if (feature.get('INFO')) {
|
|
67
|
+
;[svType] = feature.get('INFO').SVTYPE || []
|
|
68
|
+
} else if (feature.get('mate')) {
|
|
69
|
+
svType = 'mate'
|
|
70
|
+
}
|
|
71
|
+
let endPosition
|
|
72
|
+
let endBlock: Block | undefined
|
|
73
|
+
const alt = feature.get('ALT')?.[0]
|
|
74
|
+
const bnd = alt && parseBreakend(alt)
|
|
75
|
+
if (bnd) {
|
|
76
|
+
// VCF BND
|
|
77
|
+
const matePosition = bnd.MatePosition.split(':')
|
|
78
|
+
endPosition = +matePosition[1]
|
|
79
|
+
endBlock = blocksForRefs[matePosition[0]]
|
|
80
|
+
} else if (alt === '<TRA>') {
|
|
81
|
+
// VCF TRA
|
|
82
|
+
const chr2 = feature.get('INFO')?.CHR2?.[0]
|
|
83
|
+
const end = feature.get('INFO')?.END?.[0]
|
|
84
|
+
endPosition = parseInt(end, 10)
|
|
85
|
+
endBlock = blocksForRefs[chr2]
|
|
86
|
+
} else if (svType === 'mate') {
|
|
87
|
+
// generic simplefeatures arcs
|
|
88
|
+
const mate = feature.get('mate')
|
|
89
|
+
const chr2 = mate.refName
|
|
90
|
+
endPosition = mate.start
|
|
91
|
+
endBlock = blocksForRefs[chr2]
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (endBlock) {
|
|
95
|
+
const startPos = feature.get('start')
|
|
96
|
+
const startRadians = bpToRadians(startBlock, startPos)
|
|
97
|
+
const endRadians = bpToRadians(endBlock, endPosition)
|
|
98
|
+
const startXY = polarToCartesian(radius, startRadians)
|
|
99
|
+
const endXY = polarToCartesian(radius, endRadians)
|
|
100
|
+
const controlXY = polarToCartesian(
|
|
101
|
+
bezierRadius,
|
|
102
|
+
(endRadians + startRadians) / 2,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
const strokeColor = selected
|
|
106
|
+
? readConfObject(config, 'strokeColorSelected', { feature })
|
|
107
|
+
: readConfObject(config, 'strokeColor', { feature })
|
|
108
|
+
|
|
109
|
+
const hoverStrokeColor = readConfObject(config, 'strokeColorHover', {
|
|
110
|
+
feature,
|
|
111
|
+
})
|
|
112
|
+
return (
|
|
113
|
+
<path
|
|
114
|
+
data-testid={`chord-${feature.id()}`}
|
|
115
|
+
d={['M', ...startXY, 'Q', ...controlXY, ...endXY].join(' ')}
|
|
116
|
+
style={{ stroke: strokeColor }}
|
|
117
|
+
onClick={evt => {
|
|
118
|
+
if (endBlock && startBlock) {
|
|
119
|
+
onClick(feature, startBlock.region, endBlock.region, evt)
|
|
120
|
+
}
|
|
121
|
+
}}
|
|
122
|
+
onMouseOver={evt => {
|
|
123
|
+
if (!selected) {
|
|
124
|
+
evt.currentTarget.style.stroke = hoverStrokeColor
|
|
125
|
+
evt.currentTarget.style.strokeWidth = '3px'
|
|
126
|
+
}
|
|
127
|
+
}}
|
|
128
|
+
onMouseOut={evt => {
|
|
129
|
+
if (!selected) {
|
|
130
|
+
evt.currentTarget.style.stroke = strokeColor
|
|
131
|
+
evt.currentTarget.style.strokeWidth = '1px'
|
|
132
|
+
}
|
|
133
|
+
}}
|
|
134
|
+
/>
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return null
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
export default Chord
|
|
@@ -1,146 +1,10 @@
|
|
|
1
1
|
import React, { useMemo } from 'react'
|
|
2
2
|
import { observer } from 'mobx-react'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
AnyConfigurationModel,
|
|
6
|
-
readConfObject,
|
|
7
|
-
} from '@jbrowse/core/configuration'
|
|
8
|
-
import { parseBreakend } from '@gmod/vcf'
|
|
3
|
+
import { Feature } from '@jbrowse/core/util'
|
|
4
|
+
import { AnyConfigurationModel } from '@jbrowse/core/configuration'
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
start: number
|
|
13
|
-
refName: string
|
|
14
|
-
elided?: false
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface ElidedRegion {
|
|
18
|
-
elided: true
|
|
19
|
-
regions: Region[]
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
type AnyRegion = Region | ElidedRegion
|
|
23
|
-
|
|
24
|
-
interface Block {
|
|
25
|
-
flipped: boolean
|
|
26
|
-
bpPerRadian: number
|
|
27
|
-
startRadians: number
|
|
28
|
-
region: AnyRegion
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function bpToRadians(block: Block, pos: number) {
|
|
32
|
-
const blockStart = block.region.elided ? 0 : block.region.start
|
|
33
|
-
const blockEnd = block.region.elided ? 0 : block.region.end
|
|
34
|
-
const bpOffset = block.flipped ? blockEnd - pos : pos - blockStart
|
|
35
|
-
return bpOffset / block.bpPerRadian + block.startRadians
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const Chord = observer(function Chord({
|
|
39
|
-
feature,
|
|
40
|
-
blocksForRefs,
|
|
41
|
-
radius,
|
|
42
|
-
config,
|
|
43
|
-
bezierRadius,
|
|
44
|
-
selected,
|
|
45
|
-
onClick,
|
|
46
|
-
}: {
|
|
47
|
-
feature: Feature
|
|
48
|
-
blocksForRefs: { [key: string]: Block }
|
|
49
|
-
radius: number
|
|
50
|
-
config: AnyConfigurationModel
|
|
51
|
-
bezierRadius: number
|
|
52
|
-
selected: boolean
|
|
53
|
-
onClick: (
|
|
54
|
-
feature: Feature,
|
|
55
|
-
reg: AnyRegion,
|
|
56
|
-
endBlock: AnyRegion,
|
|
57
|
-
evt: unknown,
|
|
58
|
-
) => void
|
|
59
|
-
}) {
|
|
60
|
-
// find the blocks that our start and end points belong to
|
|
61
|
-
const startBlock = blocksForRefs[feature.get('refName')]
|
|
62
|
-
if (!startBlock) {
|
|
63
|
-
return null
|
|
64
|
-
}
|
|
65
|
-
let svType
|
|
66
|
-
if (feature.get('INFO')) {
|
|
67
|
-
;[svType] = feature.get('INFO').SVTYPE || []
|
|
68
|
-
} else if (feature.get('mate')) {
|
|
69
|
-
svType = 'mate'
|
|
70
|
-
}
|
|
71
|
-
let endPosition
|
|
72
|
-
let endBlock: Block | undefined
|
|
73
|
-
const alt = feature.get('ALT')?.[0]
|
|
74
|
-
const bnd = alt && parseBreakend(alt)
|
|
75
|
-
if (bnd) {
|
|
76
|
-
// VCF BND
|
|
77
|
-
const matePosition = bnd.MatePosition.split(':')
|
|
78
|
-
endPosition = +matePosition[1]
|
|
79
|
-
endBlock = blocksForRefs[matePosition[0]]
|
|
80
|
-
} else if (alt === '<TRA>') {
|
|
81
|
-
// VCF TRA
|
|
82
|
-
const chr2 = feature.get('INFO')?.CHR2?.[0]
|
|
83
|
-
const end = feature.get('INFO')?.END?.[0]
|
|
84
|
-
endPosition = parseInt(end, 10)
|
|
85
|
-
endBlock = blocksForRefs[chr2]
|
|
86
|
-
} else if (svType === 'mate') {
|
|
87
|
-
// generic simplefeatures arcs
|
|
88
|
-
const mate = feature.get('mate')
|
|
89
|
-
const chr2 = mate.refName
|
|
90
|
-
endPosition = mate.start
|
|
91
|
-
endBlock = blocksForRefs[chr2]
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (endBlock) {
|
|
95
|
-
const startPos = feature.get('start')
|
|
96
|
-
const startRadians = bpToRadians(startBlock, startPos)
|
|
97
|
-
const endRadians = bpToRadians(endBlock, endPosition)
|
|
98
|
-
const startXY = polarToCartesian(radius, startRadians)
|
|
99
|
-
const endXY = polarToCartesian(radius, endRadians)
|
|
100
|
-
const controlXY = polarToCartesian(
|
|
101
|
-
bezierRadius,
|
|
102
|
-
(endRadians + startRadians) / 2,
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
const strokeColor = selected
|
|
106
|
-
? readConfObject(config, 'strokeColorSelected', { feature })
|
|
107
|
-
: readConfObject(config, 'strokeColor', { feature })
|
|
108
|
-
|
|
109
|
-
const hoverStrokeColor = readConfObject(config, 'strokeColorHover', {
|
|
110
|
-
feature,
|
|
111
|
-
})
|
|
112
|
-
return (
|
|
113
|
-
<path
|
|
114
|
-
data-testid={`chord-${feature.id()}`}
|
|
115
|
-
d={['M', ...startXY, 'Q', ...controlXY, ...endXY].join(' ')}
|
|
116
|
-
style={{ stroke: strokeColor }}
|
|
117
|
-
onClick={evt => {
|
|
118
|
-
if (endBlock && startBlock) {
|
|
119
|
-
onClick(feature, startBlock.region, endBlock.region, evt)
|
|
120
|
-
}
|
|
121
|
-
}}
|
|
122
|
-
onMouseOver={evt => {
|
|
123
|
-
if (!selected) {
|
|
124
|
-
// @ts-ignore
|
|
125
|
-
evt.target.style.stroke = hoverStrokeColor
|
|
126
|
-
// @ts-ignore
|
|
127
|
-
evt.target.style.strokeWidth = 3
|
|
128
|
-
}
|
|
129
|
-
}}
|
|
130
|
-
onMouseOut={evt => {
|
|
131
|
-
if (!selected) {
|
|
132
|
-
// @ts-ignore
|
|
133
|
-
evt.target.style.stroke = strokeColor
|
|
134
|
-
// @ts-ignore
|
|
135
|
-
evt.target.style.strokeWidth = 1
|
|
136
|
-
}
|
|
137
|
-
}}
|
|
138
|
-
/>
|
|
139
|
-
)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return null
|
|
143
|
-
})
|
|
6
|
+
// locals
|
|
7
|
+
import Chord, { Block, AnyRegion } from './Chord'
|
|
144
8
|
|
|
145
9
|
function StructuralVariantChords(props: {
|
|
146
10
|
features: Map<string, Feature>
|
|
@@ -170,19 +34,16 @@ function StructuralVariantChords(props: {
|
|
|
170
34
|
const blocksForRefsMemo = useMemo(() => {
|
|
171
35
|
const blocksForRefs = {} as { [key: string]: Block }
|
|
172
36
|
blockDefinitions.forEach(block => {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
regions.forEach(region => {
|
|
177
|
-
blocksForRefs[region.refName] = block
|
|
178
|
-
})
|
|
37
|
+
;(block.region.elided ? block.region.regions : [block.region]).forEach(
|
|
38
|
+
r => (blocksForRefs[r.refName] = block),
|
|
39
|
+
)
|
|
179
40
|
})
|
|
180
41
|
return blocksForRefs
|
|
181
42
|
}, [blockDefinitions])
|
|
182
|
-
// console.log(blocksForRefs)
|
|
183
43
|
const chords = []
|
|
184
|
-
for (const
|
|
185
|
-
const
|
|
44
|
+
for (const feature of features.values()) {
|
|
45
|
+
const id = feature.id()
|
|
46
|
+
const selected = String(selectedFeatureId) === String(id)
|
|
186
47
|
chords.push(
|
|
187
48
|
<Chord
|
|
188
49
|
key={id}
|
|
@@ -3,16 +3,15 @@ import PluginManager from '@jbrowse/core/PluginManager'
|
|
|
3
3
|
import configSchema from './configSchema'
|
|
4
4
|
import ReactComponent from './ReactComponent'
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
export default (pluginManager: PluginManager) => {
|
|
7
7
|
pluginManager.addRendererType(
|
|
8
8
|
() =>
|
|
9
9
|
new ChordRendererType({
|
|
10
10
|
name: 'StructuralVariantChordRenderer',
|
|
11
|
+
displayName: 'SV chord renderer',
|
|
11
12
|
ReactComponent,
|
|
12
13
|
configSchema,
|
|
13
14
|
pluginManager,
|
|
14
15
|
}),
|
|
15
16
|
)
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
-
export default ChordRendererConfigF
|
|
@@ -8,16 +8,17 @@ import {
|
|
|
8
8
|
DialogContent,
|
|
9
9
|
FormControlLabel,
|
|
10
10
|
} from '@mui/material'
|
|
11
|
-
import { Dialog } from '@jbrowse/core/ui'
|
|
12
11
|
import { makeStyles } from 'tss-react/mui'
|
|
13
12
|
import { getSnapshot } from 'mobx-state-tree'
|
|
13
|
+
// jbrowse
|
|
14
|
+
import { Dialog } from '@jbrowse/core/ui'
|
|
14
15
|
import { getSession, Feature } from '@jbrowse/core/util'
|
|
15
16
|
|
|
16
|
-
const useStyles = makeStyles()(
|
|
17
|
+
const useStyles = makeStyles()({
|
|
17
18
|
block: {
|
|
18
19
|
display: 'block',
|
|
19
20
|
},
|
|
20
|
-
})
|
|
21
|
+
})
|
|
21
22
|
|
|
22
23
|
function BreakendOptionDialog({
|
|
23
24
|
model,
|
|
@@ -69,14 +70,20 @@ function BreakendOptionDialog({
|
|
|
69
70
|
feature,
|
|
70
71
|
view,
|
|
71
72
|
)
|
|
73
|
+
function remapIds(arr: any[]) {
|
|
74
|
+
return arr.map((v: any) => ({
|
|
75
|
+
...v,
|
|
76
|
+
id: v.trackId + '-' + Math.random(),
|
|
77
|
+
}))
|
|
78
|
+
}
|
|
72
79
|
viewSnapshot.views[0].offsetPx -= view.width / 2 + 100
|
|
73
80
|
viewSnapshot.views[1].offsetPx -= view.width / 2 + 100
|
|
74
81
|
viewSnapshot.featureData = feature
|
|
75
|
-
const viewTracks
|
|
76
|
-
viewSnapshot.views[0].tracks = viewTracks
|
|
77
|
-
viewSnapshot.views[1].tracks =
|
|
78
|
-
? viewTracks.slice().reverse()
|
|
79
|
-
|
|
82
|
+
const viewTracks = getSnapshot(view.tracks) as any
|
|
83
|
+
viewSnapshot.views[0].tracks = remapIds(viewTracks)
|
|
84
|
+
viewSnapshot.views[1].tracks = remapIds(
|
|
85
|
+
mirrorTracks ? viewTracks.slice().reverse() : viewTracks,
|
|
86
|
+
)
|
|
80
87
|
|
|
81
88
|
session.addView('BreakpointSplitView', viewSnapshot)
|
|
82
89
|
} catch (e) {
|
|
@@ -9,6 +9,8 @@ import { Feature } from '@jbrowse/core/util/simpleFeature'
|
|
|
9
9
|
import IntervalTree from '@flatten-js/interval-tree'
|
|
10
10
|
import { unzip } from '@gmod/bgzf-filehandle'
|
|
11
11
|
import VCF from '@gmod/vcf'
|
|
12
|
+
|
|
13
|
+
// local
|
|
12
14
|
import VcfFeature from '../VcfTabixAdapter/VcfFeature'
|
|
13
15
|
|
|
14
16
|
const readVcf = (f: string) => {
|
package/src/VcfAdapter/index.ts
CHANGED
|
@@ -14,10 +14,11 @@ import { Feature } from '@jbrowse/core/util/simpleFeature'
|
|
|
14
14
|
import { TabixIndexedFile } from '@gmod/tabix'
|
|
15
15
|
import VcfParser from '@gmod/vcf'
|
|
16
16
|
import { Observer } from 'rxjs'
|
|
17
|
-
import { readConfObject } from '@jbrowse/core/configuration'
|
|
18
|
-
import VcfFeature from './VcfFeature'
|
|
19
17
|
import { GenericFilehandle } from 'generic-filehandle'
|
|
20
18
|
|
|
19
|
+
// local
|
|
20
|
+
import VcfFeature from './VcfFeature'
|
|
21
|
+
|
|
21
22
|
export default class extends BaseFeatureDataAdapter {
|
|
22
23
|
private configured?: Promise<{
|
|
23
24
|
filehandle: GenericFilehandle
|
|
@@ -26,23 +27,17 @@ export default class extends BaseFeatureDataAdapter {
|
|
|
26
27
|
}>
|
|
27
28
|
|
|
28
29
|
private async configurePre() {
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
30
|
+
const pm = this.pluginManager
|
|
31
|
+
const vcfGzLocation = this.getConf('vcfGzLocation')
|
|
32
|
+
const location = this.getConf(['index', 'location'])
|
|
33
|
+
const indexType = this.getConf(['index', 'indexType'])
|
|
32
34
|
|
|
33
|
-
const filehandle = openLocation(
|
|
34
|
-
vcfGzLocation as FileLocation,
|
|
35
|
-
this.pluginManager,
|
|
36
|
-
)
|
|
35
|
+
const filehandle = openLocation(vcfGzLocation as FileLocation, pm)
|
|
37
36
|
const isCSI = indexType === 'CSI'
|
|
38
37
|
const vcf = new TabixIndexedFile({
|
|
39
38
|
filehandle,
|
|
40
|
-
csiFilehandle: isCSI
|
|
41
|
-
|
|
42
|
-
: undefined,
|
|
43
|
-
tbiFilehandle: !isCSI
|
|
44
|
-
? openLocation(location, this.pluginManager)
|
|
45
|
-
: undefined,
|
|
39
|
+
csiFilehandle: isCSI ? openLocation(location, pm) : undefined,
|
|
40
|
+
tbiFilehandle: !isCSI ? openLocation(location, pm) : undefined,
|
|
46
41
|
chunkCacheSize: 50 * 2 ** 20,
|
|
47
42
|
chunkSizeLimit: 1000000000,
|
|
48
43
|
})
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
import PluginManager from '@jbrowse/core/PluginManager';
|
|
3
|
-
/**
|
|
4
|
-
* #stateModel ChordVariantDisplay
|
|
5
|
-
* extends `BaseChordDisplay`
|
|
6
|
-
*/
|
|
7
|
-
declare const ChordVariantDisplayF: (pluginManager: PluginManager) => {
|
|
8
|
-
stateModel: import("mobx-state-tree").IModelType<{
|
|
9
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
10
|
-
type: import("mobx-state-tree").ISimpleType<string>;
|
|
11
|
-
rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
12
|
-
} & {
|
|
13
|
-
bezierRadiusRatio: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
14
|
-
assemblyName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
15
|
-
} & {
|
|
16
|
-
/**
|
|
17
|
-
* #property
|
|
18
|
-
*/
|
|
19
|
-
type: import("mobx-state-tree").ISimpleType<"ChordVariantDisplay">;
|
|
20
|
-
/**
|
|
21
|
-
* #property
|
|
22
|
-
*/
|
|
23
|
-
configuration: import("mobx-state-tree").ITypeUnion<any, any, any>;
|
|
24
|
-
}, {
|
|
25
|
-
rendererTypeName: string;
|
|
26
|
-
error: unknown;
|
|
27
|
-
} & {
|
|
28
|
-
readonly RenderingComponent: import("react").FC<{
|
|
29
|
-
model: {
|
|
30
|
-
id: string; /**
|
|
31
|
-
* #property
|
|
32
|
-
*/
|
|
33
|
-
type: string;
|
|
34
|
-
rpcDriverName: string | undefined;
|
|
35
|
-
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
36
|
-
rendererTypeName: string;
|
|
37
|
-
error: unknown;
|
|
38
|
-
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
39
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
40
|
-
type: import("mobx-state-tree").ISimpleType<string>;
|
|
41
|
-
rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
42
|
-
}, {
|
|
43
|
-
rendererTypeName: string;
|
|
44
|
-
error: unknown;
|
|
45
|
-
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
46
|
-
onHorizontalScroll?: Function | undefined;
|
|
47
|
-
blockState?: Record<string, any> | undefined;
|
|
48
|
-
}>;
|
|
49
|
-
readonly DisplayBlurb: import("react").FC<{
|
|
50
|
-
model: {
|
|
51
|
-
id: string;
|
|
52
|
-
type: string;
|
|
53
|
-
rpcDriverName: string | undefined;
|
|
54
|
-
} & import("mobx-state-tree/dist/internal").NonEmptyObject & {
|
|
55
|
-
rendererTypeName: string;
|
|
56
|
-
error: unknown;
|
|
57
|
-
} & import("mobx-state-tree").IStateTreeNode<import("mobx-state-tree").IModelType<{
|
|
58
|
-
id: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
59
|
-
type: import("mobx-state-tree").ISimpleType<string>;
|
|
60
|
-
rpcDriverName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
61
|
-
}, {
|
|
62
|
-
rendererTypeName: string;
|
|
63
|
-
error: unknown;
|
|
64
|
-
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
65
|
-
}> | null;
|
|
66
|
-
readonly adapterConfig: any;
|
|
67
|
-
readonly parentTrack: any;
|
|
68
|
-
renderProps(): any;
|
|
69
|
-
readonly rendererType: import("@jbrowse/core/pluggableElementTypes").RendererType;
|
|
70
|
-
readonly DisplayMessageComponent: import("react").FC<any> | undefined;
|
|
71
|
-
trackMenuItems(): import("@jbrowse/core/ui").MenuItem[];
|
|
72
|
-
readonly viewMenuActions: import("@jbrowse/core/ui").MenuItem[];
|
|
73
|
-
regionCannotBeRendered(): undefined;
|
|
74
|
-
} & {
|
|
75
|
-
setError(error?: unknown): void;
|
|
76
|
-
setRpcDriverName(rpcDriverName: string): void;
|
|
77
|
-
reload(): void;
|
|
78
|
-
} & {
|
|
79
|
-
filled: boolean;
|
|
80
|
-
reactElement: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
|
81
|
-
data: undefined;
|
|
82
|
-
message: string;
|
|
83
|
-
renderingComponent: import("@jbrowse/core/util").AnyReactComponentType | undefined;
|
|
84
|
-
refNameMap: Record<string, string> | undefined;
|
|
85
|
-
} & {
|
|
86
|
-
onChordClick(feature: import("@jbrowse/core/util").Feature): void;
|
|
87
|
-
} & {
|
|
88
|
-
readonly blockDefinitions: any;
|
|
89
|
-
renderProps(): any;
|
|
90
|
-
readonly rendererType: import("@jbrowse/core/pluggableElementTypes").RendererType;
|
|
91
|
-
isCompatibleWithRenderer(renderer: import("@jbrowse/core/pluggableElementTypes").RendererType): boolean;
|
|
92
|
-
readonly selectedFeatureId: string | undefined;
|
|
93
|
-
} & {
|
|
94
|
-
renderStarted(): void;
|
|
95
|
-
renderSuccess({ message, data, reactElement, renderingComponent, }: {
|
|
96
|
-
message: string;
|
|
97
|
-
data: any;
|
|
98
|
-
reactElement: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
99
|
-
renderingComponent: import("@jbrowse/core/util").AnyReactComponentType;
|
|
100
|
-
}): void;
|
|
101
|
-
renderError(error: unknown): void;
|
|
102
|
-
setRefNameMap(refNameMap: Record<string, string>): void;
|
|
103
|
-
} & {
|
|
104
|
-
afterAttach(): void;
|
|
105
|
-
} & {
|
|
106
|
-
/**
|
|
107
|
-
* #getter
|
|
108
|
-
*/
|
|
109
|
-
readonly rendererTypeName: any;
|
|
110
|
-
/**
|
|
111
|
-
* #method
|
|
112
|
-
*/
|
|
113
|
-
renderProps(): Record<string, unknown>;
|
|
114
|
-
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
|
|
115
|
-
configSchema: import("@jbrowse/core/configuration").AnyConfigurationSchemaType;
|
|
116
|
-
};
|
|
117
|
-
export default ChordVariantDisplayF;
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const plugin_circular_view_1 = require("@jbrowse/plugin-circular-view");
|
|
7
|
-
const configuration_1 = require("@jbrowse/core/configuration");
|
|
8
|
-
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
9
|
-
const util_1 = require("@jbrowse/core/util");
|
|
10
|
-
const tracks_1 = require("@jbrowse/core/util/tracks");
|
|
11
|
-
// locals
|
|
12
|
-
const configSchema_1 = __importDefault(require("./configSchema"));
|
|
13
|
-
/**
|
|
14
|
-
* #stateModel ChordVariantDisplay
|
|
15
|
-
* extends `BaseChordDisplay`
|
|
16
|
-
*/
|
|
17
|
-
const ChordVariantDisplayF = (pluginManager) => {
|
|
18
|
-
const configSchema = (0, configSchema_1.default)(pluginManager);
|
|
19
|
-
const stateModel = mobx_state_tree_1.types
|
|
20
|
-
.compose('ChordVariantDisplay', plugin_circular_view_1.BaseChordDisplayModel, mobx_state_tree_1.types.model({
|
|
21
|
-
/**
|
|
22
|
-
* #property
|
|
23
|
-
*/
|
|
24
|
-
type: mobx_state_tree_1.types.literal('ChordVariantDisplay'),
|
|
25
|
-
/**
|
|
26
|
-
* #property
|
|
27
|
-
*/
|
|
28
|
-
configuration: (0, configuration_1.ConfigurationReference)(configSchema),
|
|
29
|
-
}))
|
|
30
|
-
.views(self => ({
|
|
31
|
-
/**
|
|
32
|
-
* #getter
|
|
33
|
-
*/
|
|
34
|
-
get rendererTypeName() {
|
|
35
|
-
return self.configuration.renderer.type;
|
|
36
|
-
},
|
|
37
|
-
/**
|
|
38
|
-
* #method
|
|
39
|
-
*/
|
|
40
|
-
renderProps() {
|
|
41
|
-
const view = (0, util_1.getContainingView)(self);
|
|
42
|
-
return {
|
|
43
|
-
...(0, tracks_1.getParentRenderProps)(self),
|
|
44
|
-
rpcDriverName: self.rpcDriverName,
|
|
45
|
-
displayModel: self,
|
|
46
|
-
bezierRadius: view.radiusPx * self.bezierRadiusRatio,
|
|
47
|
-
radius: view.radiusPx,
|
|
48
|
-
// @ts-ignore
|
|
49
|
-
blockDefinitions: this.blockDefinitions,
|
|
50
|
-
config: self.configuration.renderer,
|
|
51
|
-
onChordClick: self.onChordClick,
|
|
52
|
-
};
|
|
53
|
-
},
|
|
54
|
-
}));
|
|
55
|
-
return { stateModel, configSchema };
|
|
56
|
-
};
|
|
57
|
-
// http://localhost:3000/test_data/hs37d5.HG002-SequelII-CCS.sv.vcf.gz.tbi
|
|
58
|
-
// render request is for 1.5x the current viewing window
|
|
59
|
-
// tracks all have a height
|
|
60
|
-
//
|
|
61
|
-
exports.default = ChordVariantDisplayF;
|
|
62
|
-
//# sourceMappingURL=ChordVariantDisplay.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ChordVariantDisplay.js","sourceRoot":"","sources":["../../../src/ChordVariantDisplay/models/ChordVariantDisplay.ts"],"names":[],"mappings":";;;;;AAAA,wEAAqE;AACrE,+DAAoE;AACpE,qDAAuC;AACvC,6CAAsD;AACtD,sDAAgE;AAGhE,SAAS;AACT,kEAA0C;AAE1C;;;GAGG;AACH,MAAM,oBAAoB,GAAG,CAAC,aAA4B,EAAE,EAAE;IAC5D,MAAM,YAAY,GAAG,IAAA,sBAAa,EAAC,aAAa,CAAC,CAAA;IACjD,MAAM,UAAU,GAAG,uBAAK;SACrB,OAAO,CACN,qBAAqB,EACrB,4CAAqB,EACrB,uBAAK,CAAC,KAAK,CAAC;QACV;;WAEG;QACH,IAAI,EAAE,uBAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC;QAC1C;;WAEG;QACH,aAAa,EAAE,IAAA,sCAAsB,EAAC,YAAY,CAAC;KACpD,CAAC,CACH;SACA,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACd;;WAEG;QACH,IAAI,gBAAgB;YAClB,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAA;QACzC,CAAC;QAED;;WAEG;QACH,WAAW;YACT,MAAM,IAAI,GAAG,IAAA,wBAAiB,EAAC,IAAI,CAAC,CAAA;YACpC,OAAO;gBACL,GAAG,IAAA,6BAAoB,EAAC,IAAI,CAAC;gBAC7B,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,YAAY,EAAE,IAAI;gBAClB,YAAY,EAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,iBAAiB;gBACpD,MAAM,EAAE,IAAI,CAAC,QAAQ;gBAErB,aAAa;gBACb,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;gBACvC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ;gBACnC,YAAY,EAAE,IAAI,CAAC,YAAY;aAChC,CAAA;QACH,CAAC;KACF,CAAC,CAAC,CAAA;IAEL,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAA;AACrC,CAAC,CAAA;AAED,0EAA0E;AAE1E,wDAAwD;AAExD,2BAA2B;AAC3B,EAAE;AACF,kBAAe,oBAAoB,CAAA"}
|