jbrowse-plugin-mafviewer 1.0.8 → 1.1.1
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/README.md +54 -20
- package/dist/{TaffyAdapter/TaffyAdapter.d.ts → BgzipTaffyAdapter/BgzipTaffyAdapter.d.ts} +11 -7
- package/dist/BgzipTaffyAdapter/BgzipTaffyAdapter.js +197 -0
- package/dist/BgzipTaffyAdapter/BgzipTaffyAdapter.js.map +1 -0
- package/dist/{TaffyAdapter → BgzipTaffyAdapter}/configSchema.d.ts +14 -1
- package/dist/{TaffyAdapter → BgzipTaffyAdapter}/configSchema.js +21 -6
- package/dist/BgzipTaffyAdapter/configSchema.js.map +1 -0
- package/dist/BgzipTaffyAdapter/index.d.ts +2 -0
- package/dist/BgzipTaffyAdapter/index.js +11 -0
- package/dist/BgzipTaffyAdapter/index.js.map +1 -0
- package/dist/BgzipTaffyAdapter/rowInstructions.d.ts +35 -0
- package/dist/BgzipTaffyAdapter/rowInstructions.js +55 -0
- package/dist/BgzipTaffyAdapter/rowInstructions.js.map +1 -0
- package/dist/BgzipTaffyAdapter/types.d.ts +13 -0
- package/dist/BgzipTaffyAdapter/types.js +2 -0
- package/dist/BgzipTaffyAdapter/types.js.map +1 -0
- package/dist/BgzipTaffyAdapter/virtualOffset.d.ts +8 -0
- package/dist/BgzipTaffyAdapter/virtualOffset.js +23 -0
- package/dist/BgzipTaffyAdapter/virtualOffset.js.map +1 -0
- package/dist/BigMafAdapter/BigMafAdapter.js +1 -1
- package/dist/BigMafAdapter/BigMafAdapter.js.map +1 -1
- package/dist/BigMafAdapter/configSchema.d.ts +11 -0
- package/dist/BigMafAdapter/configSchema.js +11 -0
- package/dist/BigMafAdapter/configSchema.js.map +1 -1
- package/dist/BigMafAdapter/index.js +1 -1
- package/dist/BigMafAdapter/index.js.map +1 -1
- package/dist/LinearMafDisplay/components/ColorLegend.js +10 -6
- package/dist/LinearMafDisplay/components/ColorLegend.js.map +1 -1
- package/dist/LinearMafDisplay/components/ReactComponent.js +39 -4
- package/dist/LinearMafDisplay/components/ReactComponent.js.map +1 -1
- package/dist/LinearMafDisplay/components/SetRowHeight.js +7 -7
- package/dist/LinearMafDisplay/components/SetRowHeight.js.map +1 -1
- package/dist/LinearMafDisplay/components/SvgWrapper.d.ts +8 -0
- package/dist/LinearMafDisplay/components/SvgWrapper.js +21 -0
- package/dist/LinearMafDisplay/components/SvgWrapper.js.map +1 -0
- package/dist/LinearMafDisplay/components/Tree.d.ts +5 -0
- package/dist/LinearMafDisplay/components/Tree.js +22 -0
- package/dist/LinearMafDisplay/components/Tree.js.map +1 -0
- package/dist/LinearMafDisplay/components/YScaleBars.d.ts +0 -1
- package/dist/LinearMafDisplay/components/YScaleBars.js +6 -27
- package/dist/LinearMafDisplay/components/YScaleBars.js.map +1 -1
- package/dist/LinearMafDisplay/components/util.d.ts +1 -0
- package/dist/LinearMafDisplay/components/util.js +8 -0
- package/dist/LinearMafDisplay/components/util.js.map +1 -0
- package/dist/LinearMafDisplay/index.js +1 -1
- package/dist/LinearMafDisplay/index.js.map +1 -1
- package/dist/LinearMafDisplay/renderSvg.js +1 -0
- package/dist/LinearMafDisplay/renderSvg.js.map +1 -1
- package/dist/LinearMafDisplay/stateModel.d.ts +76 -14
- package/dist/LinearMafDisplay/stateModel.js +118 -18
- package/dist/LinearMafDisplay/stateModel.js.map +1 -1
- package/dist/LinearMafDisplay/types.d.ts +17 -0
- package/dist/LinearMafDisplay/types.js +16 -0
- package/dist/LinearMafDisplay/types.js.map +1 -0
- package/dist/LinearMafRenderer/LinearMafRenderer.d.ts +3 -3
- package/dist/LinearMafRenderer/LinearMafRenderer.js +11 -9
- package/dist/LinearMafRenderer/LinearMafRenderer.js.map +1 -1
- package/dist/LinearMafRenderer/components/ReactComponent.js +1 -1
- package/dist/LinearMafRenderer/components/ReactComponent.js.map +1 -1
- package/dist/LinearMafRenderer/index.js +1 -1
- package/dist/LinearMafRenderer/index.js.map +1 -1
- package/dist/MafAddTrackWorkflow/AddTrackWorkflow.js +42 -25
- package/dist/MafAddTrackWorkflow/AddTrackWorkflow.js.map +1 -1
- package/dist/MafRPC/index.d.ts +16 -0
- package/dist/MafRPC/index.js +19 -0
- package/dist/MafRPC/index.js.map +1 -0
- package/dist/MafTabixAdapter/MafTabixAdapter.d.ts +8 -0
- package/dist/MafTabixAdapter/MafTabixAdapter.js +18 -19
- package/dist/MafTabixAdapter/MafTabixAdapter.js.map +1 -1
- package/dist/MafTabixAdapter/configSchema.d.ts +17 -0
- package/dist/MafTabixAdapter/configSchema.js +17 -1
- package/dist/MafTabixAdapter/configSchema.js.map +1 -1
- package/dist/MafTabixAdapter/index.js +1 -1
- package/dist/MafTabixAdapter/index.js.map +1 -1
- package/dist/MafTrack/index.js.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/jbrowse-plugin-mafviewer.umd.production.min.js +65 -4
- package/dist/jbrowse-plugin-mafviewer.umd.production.min.js.map +4 -4
- package/dist/parseNewick.d.ts +60 -0
- package/dist/parseNewick.js +95 -0
- package/dist/parseNewick.js.map +1 -0
- package/dist/util.d.ts +9 -0
- package/dist/util.js +9 -0
- package/dist/util.js.map +1 -0
- package/package.json +18 -5
- package/src/BgzipTaffyAdapter/BgzipTaffyAdapter.ts +227 -0
- package/src/{TaffyAdapter → BgzipTaffyAdapter}/configSchema.ts +21 -6
- package/src/{TaffyAdapter → BgzipTaffyAdapter}/index.ts +5 -4
- package/src/BgzipTaffyAdapter/rowInstructions.ts +91 -0
- package/src/BgzipTaffyAdapter/types.ts +16 -0
- package/src/BgzipTaffyAdapter/virtualOffset.ts +29 -0
- package/src/BigMafAdapter/BigMafAdapter.ts +11 -11
- package/src/BigMafAdapter/configSchema.ts +11 -0
- package/src/BigMafAdapter/index.ts +2 -1
- package/src/LinearMafDisplay/components/ColorLegend.tsx +36 -25
- package/src/LinearMafDisplay/components/ReactComponent.tsx +68 -3
- package/src/LinearMafDisplay/components/SetRowHeight.tsx +6 -5
- package/src/LinearMafDisplay/components/SvgWrapper.tsx +39 -0
- package/src/LinearMafDisplay/components/Tree.tsx +33 -0
- package/src/LinearMafDisplay/components/YScaleBars.tsx +8 -43
- package/src/LinearMafDisplay/components/util.ts +7 -0
- package/src/LinearMafDisplay/index.ts +2 -1
- package/src/LinearMafDisplay/renderSvg.tsx +2 -1
- package/src/LinearMafDisplay/stateModel.ts +139 -18
- package/src/LinearMafDisplay/types.ts +41 -0
- package/src/LinearMafRenderer/LinearMafRenderer.ts +13 -10
- package/src/LinearMafRenderer/components/ReactComponent.tsx +2 -1
- package/src/LinearMafRenderer/index.ts +2 -1
- package/src/MafAddTrackWorkflow/AddTrackWorkflow.tsx +109 -65
- package/src/MafRPC/index.ts +39 -0
- package/src/MafTabixAdapter/MafTabixAdapter.ts +31 -25
- package/src/MafTabixAdapter/configSchema.ts +17 -1
- package/src/MafTabixAdapter/index.ts +2 -1
- package/src/MafTrack/index.ts +1 -0
- package/src/index.ts +6 -4
- package/src/parseNewick.ts +94 -0
- package/src/util.ts +11 -0
- package/LICENSE +0 -201
- package/dist/TaffyAdapter/TaffyAdapter.js +0 -89
- package/dist/TaffyAdapter/TaffyAdapter.js.map +0 -1
- package/dist/TaffyAdapter/configSchema.js.map +0 -1
- package/dist/TaffyAdapter/index.d.ts +0 -2
- package/dist/TaffyAdapter/index.js +0 -11
- package/dist/TaffyAdapter/index.js.map +0 -1
- package/src/TaffyAdapter/TaffyAdapter.ts +0 -112
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter'
|
|
2
|
-
import { getSnapshot } from 'mobx-state-tree'
|
|
3
2
|
import { Feature, Region, SimpleFeature } from '@jbrowse/core/util'
|
|
4
3
|
import { ObservableCreate } from '@jbrowse/core/util/rxjs'
|
|
4
|
+
import { getSnapshot } from 'mobx-state-tree'
|
|
5
5
|
import { firstValueFrom, toArray } from 'rxjs'
|
|
6
6
|
|
|
7
7
|
interface OrganismRecord {
|
|
@@ -63,30 +63,30 @@ export default class BigMafAdapter extends BaseFeatureDataAdapter {
|
|
|
63
63
|
for (const block of blocks) {
|
|
64
64
|
if (block.startsWith('s')) {
|
|
65
65
|
if (aln) {
|
|
66
|
-
alns.push(block.split(/ +/)[6])
|
|
66
|
+
alns.push(block.split(/ +/)[6]!)
|
|
67
67
|
blocks2.push(block)
|
|
68
68
|
} else {
|
|
69
69
|
aln = block.split(/ +/)[6]
|
|
70
|
-
alns.push(aln)
|
|
70
|
+
alns.push(aln!)
|
|
71
71
|
blocks2.push(block)
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
for (let i = 0; i < blocks2.length; i++) {
|
|
77
|
-
const elt = blocks2[i]
|
|
77
|
+
const elt = blocks2[i]!
|
|
78
78
|
const ad = elt.split(/ +/)
|
|
79
|
-
const y = ad[1]
|
|
80
|
-
const org = y[0]
|
|
81
|
-
const chr = y[1]
|
|
79
|
+
const y = ad[1]!.split('.')
|
|
80
|
+
const org = y[0]!
|
|
81
|
+
const chr = y[1]!
|
|
82
82
|
|
|
83
83
|
alignments[org] = {
|
|
84
84
|
chr: chr,
|
|
85
|
-
start: +ad[1]
|
|
86
|
-
srcSize: +ad[2]
|
|
85
|
+
start: +ad[1]!,
|
|
86
|
+
srcSize: +ad[2]!,
|
|
87
87
|
strand: ad[3] === '+' ? 1 : -1,
|
|
88
|
-
unknown: +ad[4]
|
|
89
|
-
data: alns[i]
|
|
88
|
+
unknown: +ad[4]!,
|
|
89
|
+
data: alns[i]!,
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
observer.next(
|
|
@@ -27,6 +27,17 @@ const configSchema = ConfigurationSchema(
|
|
|
27
27
|
locationType: 'UriLocation',
|
|
28
28
|
},
|
|
29
29
|
},
|
|
30
|
+
/**
|
|
31
|
+
* #slot
|
|
32
|
+
*/
|
|
33
|
+
nhLocation: {
|
|
34
|
+
type: 'fileLocation',
|
|
35
|
+
description: 'newick tree',
|
|
36
|
+
defaultValue: {
|
|
37
|
+
uri: '/path/to/my.nh',
|
|
38
|
+
locationType: 'UriLocation',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
30
41
|
},
|
|
31
42
|
{ explicitlyTyped: true },
|
|
32
43
|
)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
2
2
|
import { AdapterType } from '@jbrowse/core/pluggableElementTypes'
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import BigMafAdapter from './BigMafAdapter'
|
|
5
|
+
import configSchema from './configSchema'
|
|
5
6
|
|
|
6
7
|
export default function BigMafAdapterF(pluginManager: PluginManager) {
|
|
7
8
|
return pluginManager.addAdapterType(
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
+
|
|
2
3
|
import { observer } from 'mobx-react'
|
|
3
4
|
|
|
4
5
|
// locals
|
|
5
6
|
import { LinearMafDisplayModel } from '../stateModel'
|
|
6
7
|
import RectBg from './RectBg'
|
|
8
|
+
import Tree from './Tree'
|
|
7
9
|
|
|
8
10
|
const ColorLegend = observer(function ({
|
|
9
11
|
model,
|
|
@@ -14,35 +16,44 @@ const ColorLegend = observer(function ({
|
|
|
14
16
|
svgFontSize: number
|
|
15
17
|
labelWidth: number
|
|
16
18
|
}) {
|
|
17
|
-
const { samples, rowHeight } = model
|
|
18
|
-
const canDisplayLabel = rowHeight >=
|
|
19
|
+
const { totalHeight, treeWidth, samples, rowHeight } = model
|
|
20
|
+
const canDisplayLabel = rowHeight >= 8
|
|
19
21
|
const boxHeight = Math.min(20, rowHeight)
|
|
20
22
|
|
|
21
23
|
return (
|
|
22
24
|
<>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
25
|
+
<RectBg
|
|
26
|
+
y={0}
|
|
27
|
+
x={0}
|
|
28
|
+
width={labelWidth + 5 + treeWidth}
|
|
29
|
+
height={totalHeight}
|
|
30
|
+
/>
|
|
31
|
+
<Tree model={model} />
|
|
32
|
+
<g transform={`translate(${treeWidth + 5},0)`}>
|
|
33
|
+
{samples.map((sample, idx) => (
|
|
34
|
+
<RectBg
|
|
35
|
+
key={`${sample.id}-${idx}`}
|
|
36
|
+
y={idx * rowHeight}
|
|
37
|
+
x={0}
|
|
38
|
+
width={labelWidth + 5}
|
|
39
|
+
height={boxHeight}
|
|
40
|
+
color={sample.color}
|
|
41
|
+
/>
|
|
42
|
+
))}
|
|
43
|
+
{canDisplayLabel
|
|
44
|
+
? samples.map((sample, idx) => (
|
|
45
|
+
<text
|
|
46
|
+
key={`${sample.id}-${idx}`}
|
|
47
|
+
y={idx * rowHeight + rowHeight / 2}
|
|
48
|
+
dominantBaseline="middle"
|
|
49
|
+
x={2}
|
|
50
|
+
fontSize={svgFontSize}
|
|
51
|
+
>
|
|
52
|
+
{sample.label}
|
|
53
|
+
</text>
|
|
54
|
+
))
|
|
55
|
+
: null}
|
|
56
|
+
</g>
|
|
46
57
|
</>
|
|
47
58
|
)
|
|
48
59
|
})
|
|
@@ -1,24 +1,89 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
1
|
+
import React, { useRef, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
import BaseTooltip from '@jbrowse/core/ui/BaseTooltip'
|
|
4
|
+
import SanitizedHTML from '@jbrowse/core/ui/SanitizedHTML'
|
|
5
|
+
import { getContainingView, getEnv } from '@jbrowse/core/util'
|
|
3
6
|
import { observer } from 'mobx-react'
|
|
7
|
+
import { makeStyles } from 'tss-react/mui'
|
|
8
|
+
|
|
4
9
|
import YScaleBars from './YScaleBars'
|
|
5
10
|
import { LinearMafDisplayModel } from '../stateModel'
|
|
6
11
|
|
|
12
|
+
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
13
|
+
|
|
14
|
+
const useStyles = makeStyles()({
|
|
15
|
+
cursor: {
|
|
16
|
+
pointerEvents: 'none',
|
|
17
|
+
},
|
|
18
|
+
})
|
|
19
|
+
|
|
7
20
|
const LinearMafDisplay = observer(function (props: {
|
|
8
21
|
model: LinearMafDisplayModel
|
|
9
22
|
}) {
|
|
10
23
|
const { model } = props
|
|
24
|
+
const { classes } = useStyles()
|
|
11
25
|
const { pluginManager } = getEnv(model)
|
|
26
|
+
const { rowHeight, height, scrollTop, samples: sources } = model
|
|
27
|
+
const ref = useRef<HTMLDivElement>(null)
|
|
12
28
|
|
|
13
29
|
const LinearGenomePlugin = pluginManager.getPlugin(
|
|
14
30
|
'LinearGenomeViewPlugin',
|
|
15
31
|
) as import('@jbrowse/plugin-linear-genome-view').default
|
|
16
32
|
const { BaseLinearDisplayComponent } = LinearGenomePlugin.exports
|
|
17
33
|
|
|
34
|
+
const [mouseY, setMouseY] = useState<number>()
|
|
35
|
+
const [mouseX, setMouseX] = useState<number>()
|
|
36
|
+
const { width } = getContainingView(model) as LinearGenomeViewModel
|
|
37
|
+
|
|
18
38
|
return (
|
|
19
|
-
<div
|
|
39
|
+
<div
|
|
40
|
+
ref={ref}
|
|
41
|
+
onMouseMove={event => {
|
|
42
|
+
const rect = ref.current?.getBoundingClientRect()
|
|
43
|
+
const top = rect?.top || 0
|
|
44
|
+
const left = rect?.left || 0
|
|
45
|
+
setMouseY(event.clientY - top)
|
|
46
|
+
setMouseX(event.clientX - left)
|
|
47
|
+
}}
|
|
48
|
+
onMouseLeave={() => {
|
|
49
|
+
setMouseY(undefined)
|
|
50
|
+
setMouseX(undefined)
|
|
51
|
+
}}
|
|
52
|
+
>
|
|
20
53
|
<BaseLinearDisplayComponent {...props} />
|
|
21
54
|
<YScaleBars model={model} />
|
|
55
|
+
{mouseY ? (
|
|
56
|
+
<div style={{ position: 'relative' }}>
|
|
57
|
+
<svg
|
|
58
|
+
className={classes.cursor}
|
|
59
|
+
width={width}
|
|
60
|
+
height={height}
|
|
61
|
+
style={{
|
|
62
|
+
position: 'absolute',
|
|
63
|
+
top: scrollTop,
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
<line
|
|
67
|
+
x1={0}
|
|
68
|
+
x2={width}
|
|
69
|
+
y1={mouseY - scrollTop}
|
|
70
|
+
y2={mouseY - scrollTop}
|
|
71
|
+
stroke="black"
|
|
72
|
+
/>
|
|
73
|
+
<line x1={mouseX} x2={mouseX} y1={0} y2={height} stroke="black" />
|
|
74
|
+
</svg>
|
|
75
|
+
<BaseTooltip>
|
|
76
|
+
<SanitizedHTML
|
|
77
|
+
html={Object.entries(
|
|
78
|
+
sources[Math.floor(mouseY / rowHeight)] || {},
|
|
79
|
+
)
|
|
80
|
+
.filter(([key]) => key !== 'color' && key !== 'id')
|
|
81
|
+
.map(([key, value]) => `${key}:${value}`)
|
|
82
|
+
.join('\n')}
|
|
83
|
+
/>
|
|
84
|
+
</BaseTooltip>
|
|
85
|
+
</div>
|
|
86
|
+
) : null}
|
|
22
87
|
</div>
|
|
23
88
|
)
|
|
24
89
|
})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import { Dialog } from '@jbrowse/core/ui'
|
|
3
4
|
import {
|
|
4
5
|
Button,
|
|
5
6
|
DialogActions,
|
|
@@ -7,7 +8,7 @@ import {
|
|
|
7
8
|
TextField,
|
|
8
9
|
Typography,
|
|
9
10
|
} from '@mui/material'
|
|
10
|
-
import {
|
|
11
|
+
import { observer } from 'mobx-react'
|
|
11
12
|
import { makeStyles } from 'tss-react/mui'
|
|
12
13
|
|
|
13
14
|
const useStyles = makeStyles()({
|
|
@@ -31,7 +32,7 @@ const SetRowHeightDialog = observer(function (props: {
|
|
|
31
32
|
const [rowProportion, setRowProportion] = useState(`${model.rowProportion}`)
|
|
32
33
|
|
|
33
34
|
return (
|
|
34
|
-
<Dialog open onClose={handleClose} title="
|
|
35
|
+
<Dialog open onClose={handleClose} title="Set row height">
|
|
35
36
|
<DialogContent className={classes.root}>
|
|
36
37
|
<Typography>
|
|
37
38
|
Set row height and the proportion of the row height to use for drawing
|
|
@@ -39,17 +40,17 @@ const SetRowHeightDialog = observer(function (props: {
|
|
|
39
40
|
</Typography>
|
|
40
41
|
<TextField
|
|
41
42
|
value={rowHeight}
|
|
43
|
+
helperText="Enter row height"
|
|
42
44
|
onChange={event => {
|
|
43
45
|
setRowHeight(event.target.value)
|
|
44
46
|
}}
|
|
45
|
-
placeholder="Enter row height"
|
|
46
47
|
/>
|
|
47
48
|
<TextField
|
|
48
49
|
value={rowProportion}
|
|
50
|
+
helperText="Enter row proportion"
|
|
49
51
|
onChange={event => {
|
|
50
52
|
setRowProportion(event.target.value)
|
|
51
53
|
}}
|
|
52
|
-
placeholder="Enter row proportion"
|
|
53
54
|
/>
|
|
54
55
|
<DialogActions>
|
|
55
56
|
<Button
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { getContainingView } from '@jbrowse/core/util'
|
|
4
|
+
import { observer } from 'mobx-react'
|
|
5
|
+
|
|
6
|
+
// locals
|
|
7
|
+
import { LinearMafDisplayModel } from '../stateModel'
|
|
8
|
+
|
|
9
|
+
const SvgWrapper = observer(function ({
|
|
10
|
+
children,
|
|
11
|
+
model,
|
|
12
|
+
exportSVG,
|
|
13
|
+
}: {
|
|
14
|
+
model: LinearMafDisplayModel
|
|
15
|
+
children: React.ReactNode
|
|
16
|
+
exportSVG?: boolean
|
|
17
|
+
}) {
|
|
18
|
+
if (exportSVG) {
|
|
19
|
+
return <>{children}</>
|
|
20
|
+
} else {
|
|
21
|
+
const { rowHeight, samples } = model
|
|
22
|
+
return (
|
|
23
|
+
<svg
|
|
24
|
+
style={{
|
|
25
|
+
position: 'absolute',
|
|
26
|
+
top: 0,
|
|
27
|
+
left: 0,
|
|
28
|
+
pointerEvents: 'none',
|
|
29
|
+
height: samples.length * rowHeight,
|
|
30
|
+
width: getContainingView(model).width,
|
|
31
|
+
}}
|
|
32
|
+
>
|
|
33
|
+
{children}
|
|
34
|
+
</svg>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
export default SvgWrapper
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { observer } from 'mobx-react'
|
|
4
|
+
|
|
5
|
+
const Tree = observer(function ({ model }: { model: any }) {
|
|
6
|
+
const { hierarchy, showBranchLen } = model
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<>
|
|
10
|
+
{hierarchy
|
|
11
|
+
? [...hierarchy.links()].map(link => {
|
|
12
|
+
const { source, target } = link
|
|
13
|
+
const sy = source.x!
|
|
14
|
+
const ty = target.x!
|
|
15
|
+
const tx = showBranchLen ? target.len : target.y
|
|
16
|
+
const sx = showBranchLen ? source.len : source.y
|
|
17
|
+
|
|
18
|
+
// 1d line intersection to check if line crosses block at all, this is
|
|
19
|
+
// an optimization that allows us to skip drawing most tree links
|
|
20
|
+
// outside the block
|
|
21
|
+
return (
|
|
22
|
+
<React.Fragment key={[sy, ty, tx, sx].join('-')}>
|
|
23
|
+
<line stroke="black" x1={sx} y1={sy} x2={sx} y2={ty} />
|
|
24
|
+
<line stroke="black" x1={sx} y1={ty} x2={tx} y2={ty} />
|
|
25
|
+
</React.Fragment>
|
|
26
|
+
)
|
|
27
|
+
})
|
|
28
|
+
: null}
|
|
29
|
+
</>
|
|
30
|
+
)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
export default Tree
|
|
@@ -1,48 +1,13 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import { measureText } from '@jbrowse/core/util'
|
|
3
4
|
import { observer } from 'mobx-react'
|
|
4
5
|
|
|
5
6
|
// locals
|
|
6
7
|
import { LinearMafDisplayModel } from '../stateModel'
|
|
7
8
|
import ColorLegend from './ColorLegend'
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
children,
|
|
11
|
-
model,
|
|
12
|
-
exportSVG,
|
|
13
|
-
}: {
|
|
14
|
-
model: LinearMafDisplayModel
|
|
15
|
-
children: React.ReactNode
|
|
16
|
-
exportSVG?: boolean
|
|
17
|
-
}) {
|
|
18
|
-
if (exportSVG) {
|
|
19
|
-
return <>{children}</>
|
|
20
|
-
} else {
|
|
21
|
-
const { rowHeight, samples } = model
|
|
22
|
-
return (
|
|
23
|
-
<svg
|
|
24
|
-
style={{
|
|
25
|
-
position: 'absolute',
|
|
26
|
-
top: 0,
|
|
27
|
-
left: 0,
|
|
28
|
-
pointerEvents: 'none',
|
|
29
|
-
height: samples.length * rowHeight,
|
|
30
|
-
width: getContainingView(model).width,
|
|
31
|
-
}}
|
|
32
|
-
>
|
|
33
|
-
{children}
|
|
34
|
-
</svg>
|
|
35
|
-
)
|
|
36
|
-
}
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
export function max(arr: number[], init = Number.NEGATIVE_INFINITY) {
|
|
40
|
-
let max = init
|
|
41
|
-
for (const entry of arr) {
|
|
42
|
-
max = Math.max(entry, max)
|
|
43
|
-
}
|
|
44
|
-
return max
|
|
45
|
-
}
|
|
9
|
+
import SvgWrapper from './SvgWrapper'
|
|
10
|
+
import { max } from './util'
|
|
46
11
|
|
|
47
12
|
export const YScaleBars = observer(function (props: {
|
|
48
13
|
model: LinearMafDisplayModel
|
|
@@ -51,8 +16,8 @@ export const YScaleBars = observer(function (props: {
|
|
|
51
16
|
}) {
|
|
52
17
|
const { model } = props
|
|
53
18
|
const { rowHeight, samples } = model
|
|
54
|
-
const svgFontSize = Math.min(Math.max(rowHeight,
|
|
55
|
-
const canDisplayLabel = rowHeight >=
|
|
19
|
+
const svgFontSize = Math.min(Math.max(rowHeight, 8), 14)
|
|
20
|
+
const canDisplayLabel = rowHeight >= 8
|
|
56
21
|
const minWidth = 20
|
|
57
22
|
|
|
58
23
|
const labelWidth = max(
|
|
@@ -62,13 +27,13 @@ export const YScaleBars = observer(function (props: {
|
|
|
62
27
|
)
|
|
63
28
|
|
|
64
29
|
return (
|
|
65
|
-
<
|
|
30
|
+
<SvgWrapper {...props}>
|
|
66
31
|
<ColorLegend
|
|
67
32
|
model={model}
|
|
68
33
|
labelWidth={labelWidth}
|
|
69
34
|
svgFontSize={svgFontSize}
|
|
70
35
|
/>
|
|
71
|
-
</
|
|
36
|
+
</SvgWrapper>
|
|
72
37
|
)
|
|
73
38
|
})
|
|
74
39
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
2
2
|
import { DisplayType } from '@jbrowse/core/pluggableElementTypes'
|
|
3
|
+
|
|
4
|
+
import ReactComponent from './components/ReactComponent'
|
|
3
5
|
import configSchemaF from './configSchema'
|
|
4
6
|
import stateModelFactory from './stateModel'
|
|
5
|
-
import ReactComponent from './components/ReactComponent'
|
|
6
7
|
|
|
7
8
|
export default function LinearMafDisplayF(pluginManager: PluginManager) {
|
|
8
9
|
pluginManager.addDisplayType(() => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
+
|
|
2
3
|
import { getContainingView } from '@jbrowse/core/util'
|
|
3
4
|
import {
|
|
4
5
|
ExportSvgDisplayOptions,
|
|
@@ -6,8 +7,8 @@ import {
|
|
|
6
7
|
} from '@jbrowse/plugin-linear-genome-view'
|
|
7
8
|
|
|
8
9
|
// locals
|
|
9
|
-
import { LinearMafDisplayModel } from './stateModel'
|
|
10
10
|
import YScaleBars from './components/YScaleBars'
|
|
11
|
+
import { LinearMafDisplayModel } from './stateModel'
|
|
11
12
|
|
|
12
13
|
export async function renderSvg(
|
|
13
14
|
self: LinearMafDisplayModel,
|