@jbrowse/plugin-wiggle 3.1.0 → 3.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/BigWigAdapter/BigWigAdapter.js +1 -1
- package/dist/LinearWiggleDisplay/model.d.ts +10 -10
- package/dist/MultiDensityRenderer/MultiDensityRenderer.js +2 -2
- package/dist/MultiLineRenderer/MultiLineRenderer.js +2 -2
- package/dist/MultiLinearWiggleDisplay/components/SourcesGrid.js +4 -4
- package/dist/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialog.d.ts +6 -0
- package/dist/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialog.js +29 -0
- package/dist/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogAuto.d.ts +7 -0
- package/dist/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogAuto.js +79 -0
- package/dist/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogManual.d.ts +7 -0
- package/dist/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogManual.js +145 -0
- package/dist/MultiLinearWiggleDisplay/components/WiggleClusterDialog/types.d.ts +7 -0
- package/dist/MultiLinearWiggleDisplay/components/WiggleClusterDialog/types.js +2 -0
- package/dist/MultiLinearWiggleDisplay/components/util.d.ts +3 -2
- package/dist/MultiLinearWiggleDisplay/model.d.ts +15 -9
- package/dist/MultiLinearWiggleDisplay/model.js +29 -15
- package/dist/MultiRowLineRenderer/MultiRowLineRenderer.js +2 -2
- package/dist/MultiRowXYPlotRenderer/MultiRowXYPlotRenderer.js +2 -2
- package/dist/MultiXYPlotRenderer/MultiXYPlotRenderer.js +3 -3
- package/dist/WiggleBaseRenderer.d.ts +1 -0
- package/dist/WiggleBaseRenderer.js +4 -4
- package/dist/WiggleRPC/MultiWiggleClusterScoreMatrix.d.ts +14 -0
- package/dist/WiggleRPC/MultiWiggleClusterScoreMatrix.js +31 -0
- package/dist/WiggleRPC/MultiWiggleGetScoreMatrix.d.ts +2 -13
- package/dist/WiggleRPC/MultiWiggleGetScoreMatrix.js +5 -37
- package/dist/WiggleRPC/getScoreMatrix.d.ts +6 -0
- package/dist/WiggleRPC/getScoreMatrix.js +35 -0
- package/dist/WiggleRPC/rpcMethods.d.ts +1 -0
- package/dist/WiggleRPC/rpcMethods.js +1 -0
- package/dist/WiggleRPC/type.d.ts +0 -0
- package/dist/WiggleRPC/type.js +1 -0
- package/dist/WiggleRPC/types.d.ts +13 -0
- package/dist/WiggleRPC/types.js +2 -0
- package/dist/drawDensity.d.ts +1 -0
- package/dist/drawDensity.js +12 -2
- package/dist/drawLine.d.ts +1 -0
- package/dist/drawLine.js +9 -3
- package/dist/drawXY.js +8 -8
- package/dist/index.js +1 -0
- package/dist/shared/SharedWiggleMixin.d.ts +8 -8
- package/dist/shared/SharedWiggleMixin.js +11 -8
- package/esm/BigWigAdapter/BigWigAdapter.js +1 -1
- package/esm/LinearWiggleDisplay/model.d.ts +10 -10
- package/esm/MultiDensityRenderer/MultiDensityRenderer.js +3 -3
- package/esm/MultiLineRenderer/MultiLineRenderer.js +3 -3
- package/esm/MultiLinearWiggleDisplay/components/SourcesGrid.js +4 -4
- package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialog.d.ts +6 -0
- package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialog.js +24 -0
- package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogAuto.d.ts +7 -0
- package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogAuto.js +77 -0
- package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogManual.d.ts +7 -0
- package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogManual.js +140 -0
- package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/types.d.ts +7 -0
- package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/types.js +1 -0
- package/esm/MultiLinearWiggleDisplay/components/util.d.ts +3 -2
- package/esm/MultiLinearWiggleDisplay/model.d.ts +15 -9
- package/esm/MultiLinearWiggleDisplay/model.js +29 -15
- package/esm/MultiRowLineRenderer/MultiRowLineRenderer.js +3 -3
- package/esm/MultiRowXYPlotRenderer/MultiRowXYPlotRenderer.js +3 -3
- package/esm/MultiXYPlotRenderer/MultiXYPlotRenderer.js +4 -4
- package/esm/WiggleBaseRenderer.d.ts +1 -0
- package/esm/WiggleBaseRenderer.js +5 -5
- package/esm/WiggleRPC/MultiWiggleClusterScoreMatrix.d.ts +14 -0
- package/esm/WiggleRPC/MultiWiggleClusterScoreMatrix.js +24 -0
- package/esm/WiggleRPC/MultiWiggleGetScoreMatrix.d.ts +2 -13
- package/esm/WiggleRPC/MultiWiggleGetScoreMatrix.js +5 -37
- package/esm/WiggleRPC/getScoreMatrix.d.ts +6 -0
- package/esm/WiggleRPC/getScoreMatrix.js +32 -0
- package/esm/WiggleRPC/rpcMethods.d.ts +1 -0
- package/esm/WiggleRPC/rpcMethods.js +1 -0
- package/esm/WiggleRPC/type.d.ts +0 -0
- package/esm/WiggleRPC/type.js +1 -0
- package/esm/WiggleRPC/types.d.ts +13 -0
- package/esm/WiggleRPC/types.js +1 -0
- package/esm/drawDensity.d.ts +1 -0
- package/esm/drawDensity.js +12 -2
- package/esm/drawLine.d.ts +1 -0
- package/esm/drawLine.js +9 -3
- package/esm/drawXY.js +8 -8
- package/esm/index.js +2 -1
- package/esm/shared/SharedWiggleMixin.d.ts +8 -8
- package/esm/shared/SharedWiggleMixin.js +11 -8
- package/package.json +9 -9
- package/dist/MultiLinearWiggleDisplay/components/ClusterDialog.d.ts +0 -11
- package/dist/MultiLinearWiggleDisplay/components/ClusterDialog.js +0 -115
- package/esm/MultiLinearWiggleDisplay/components/ClusterDialog.d.ts +0 -11
- package/esm/MultiLinearWiggleDisplay/components/ClusterDialog.js +0 -109
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Dialog } from '@jbrowse/core/ui';
|
|
4
|
+
import { FormControlLabel, Radio, RadioGroup } from '@mui/material';
|
|
5
|
+
import { observer } from 'mobx-react';
|
|
6
|
+
import WiggleClusterDialogAuto from './WiggleClusterDialogAuto';
|
|
7
|
+
import WiggleClusterDialogManual from './WiggleClusterDialogManual';
|
|
8
|
+
function Header({ activeMode, setActiveMode, }) {
|
|
9
|
+
return (_jsx("div", { children: _jsx(RadioGroup, { children: Object.entries({
|
|
10
|
+
auto: (_jsx("div", { children: "Run in-app clustering (slower, particularly for large numbers of samples, uses JS implementation of hclust)" })),
|
|
11
|
+
manual: (_jsx("div", { children: "Download R script to run clustering (faster, uses R implementation of hclust)" })),
|
|
12
|
+
}).map(([key, val]) => (_jsx(FormControlLabel, { control: _jsx(Radio, { checked: activeMode === key, onChange: () => {
|
|
13
|
+
setActiveMode(key);
|
|
14
|
+
} }), label: val }, key))) }) }));
|
|
15
|
+
}
|
|
16
|
+
const WiggleClusterDialog = observer(function ({ model, handleClose, }) {
|
|
17
|
+
const [activeMode, setActiveMode] = useState('auto');
|
|
18
|
+
return (_jsx(Dialog, { open: true, title: "Cluster by score", maxWidth: "xl", onClose: (_, reason) => {
|
|
19
|
+
if (reason !== 'backdropClick') {
|
|
20
|
+
handleClose();
|
|
21
|
+
}
|
|
22
|
+
}, children: activeMode === 'auto' ? (_jsx(WiggleClusterDialogAuto, { model: model, handleClose: handleClose, children: _jsx(Header, { activeMode: activeMode, setActiveMode: setActiveMode }) })) : (_jsx(WiggleClusterDialogManual, { model: model, handleClose: handleClose, children: _jsx(Header, { activeMode: activeMode, setActiveMode: setActiveMode }) })) }));
|
|
23
|
+
});
|
|
24
|
+
export default WiggleClusterDialog;
|
package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogAuto.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReducedModel } from './types';
|
|
2
|
+
declare const WiggleClusterDialogAuto: ({ model, children, handleClose, }: {
|
|
3
|
+
model: ReducedModel;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
handleClose: () => void;
|
|
6
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default WiggleClusterDialogAuto;
|
package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogAuto.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { ErrorMessage } from '@jbrowse/core/ui';
|
|
4
|
+
import { getContainingView, getSession, isAbortException, useLocalStorage, } from '@jbrowse/core/util';
|
|
5
|
+
import { createStopToken, stopStopToken } from '@jbrowse/core/util/stopToken';
|
|
6
|
+
import { getRpcSessionId } from '@jbrowse/core/util/tracks';
|
|
7
|
+
import { Button, DialogActions, DialogContent, TextField, Typography, } from '@mui/material';
|
|
8
|
+
import { observer } from 'mobx-react';
|
|
9
|
+
import { isAlive } from 'mobx-state-tree';
|
|
10
|
+
const WiggleClusterDialogAuto = observer(function ({ model, children, handleClose, }) {
|
|
11
|
+
const [progress, setProgress] = useState('');
|
|
12
|
+
const [error, setError] = useState();
|
|
13
|
+
const [loading, setLoading] = useState(false);
|
|
14
|
+
const [stopToken, setStopToken] = useState('');
|
|
15
|
+
const [showAdvanced, setShowAdvanced] = useState(false);
|
|
16
|
+
const [samplesPerPixel, setSamplesPerPixel] = useLocalStorage('cluster-samplesPerPixel', '1');
|
|
17
|
+
return (_jsxs(_Fragment, { children: [_jsxs(DialogContent, { children: [children, _jsxs("div", { style: { marginTop: 50 }, children: [_jsx(Button, { variant: "contained", onClick: () => {
|
|
18
|
+
setShowAdvanced(!showAdvanced);
|
|
19
|
+
}, children: showAdvanced ? 'Hide advanced options' : 'Show advanced options' }), showAdvanced ? (_jsxs("div", { style: { marginTop: 20 }, children: [_jsx(Typography, { children: "This procedure samples the data at each 'pixel' across the visible by default" }), _jsx(TextField, { label: "Samples per pixel (>1 for denser sampling, between 0-1 for sparser sampling)", variant: "outlined", size: "small", value: samplesPerPixel, onChange: event => {
|
|
20
|
+
setSamplesPerPixel(event.target.value);
|
|
21
|
+
} })] })) : null] }), _jsxs("div", { children: [loading ? (_jsxs("div", { style: { padding: 50 }, children: [_jsx("span", { children: progress || 'Loading...' }), _jsx(Button, { onClick: () => {
|
|
22
|
+
stopStopToken(stopToken);
|
|
23
|
+
}, children: "Stop" })] })) : null, error ? _jsx(ErrorMessage, { error: error }) : null] })] }), _jsxs(DialogActions, { children: [_jsx(Button, { variant: "contained", disabled: loading, onClick: async () => {
|
|
24
|
+
try {
|
|
25
|
+
setError(undefined);
|
|
26
|
+
setProgress('Initializing');
|
|
27
|
+
setLoading(true);
|
|
28
|
+
const view = getContainingView(model);
|
|
29
|
+
if (!view.initialized) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const { rpcManager } = getSession(model);
|
|
33
|
+
const { sourcesWithoutLayout, adapterConfig } = model;
|
|
34
|
+
if (sourcesWithoutLayout) {
|
|
35
|
+
const sessionId = getRpcSessionId(model);
|
|
36
|
+
const stopToken = createStopToken();
|
|
37
|
+
setStopToken(stopToken);
|
|
38
|
+
const ret = (await rpcManager.call(sessionId, 'MultiWiggleClusterScoreMatrix', {
|
|
39
|
+
regions: view.dynamicBlocks.contentBlocks,
|
|
40
|
+
sources: sourcesWithoutLayout,
|
|
41
|
+
sessionId,
|
|
42
|
+
adapterConfig,
|
|
43
|
+
stopToken,
|
|
44
|
+
bpPerPx: view.bpPerPx / +samplesPerPixel,
|
|
45
|
+
statusCallback: (arg) => {
|
|
46
|
+
setProgress(arg);
|
|
47
|
+
},
|
|
48
|
+
}));
|
|
49
|
+
model.setLayout(ret.order.map(idx => {
|
|
50
|
+
const ret = sourcesWithoutLayout[idx];
|
|
51
|
+
if (!ret) {
|
|
52
|
+
throw new Error(`out of bounds at ${idx}`);
|
|
53
|
+
}
|
|
54
|
+
return ret;
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
handleClose();
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
if (!isAbortException(e) && isAlive(model)) {
|
|
61
|
+
console.error(e);
|
|
62
|
+
setError(e);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
setLoading(false);
|
|
67
|
+
setProgress('');
|
|
68
|
+
setStopToken('');
|
|
69
|
+
}
|
|
70
|
+
}, children: "Run clustering" }), _jsx(Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
71
|
+
handleClose();
|
|
72
|
+
if (stopToken) {
|
|
73
|
+
stopStopToken(stopToken);
|
|
74
|
+
}
|
|
75
|
+
}, children: "Cancel" })] })] }));
|
|
76
|
+
});
|
|
77
|
+
export default WiggleClusterDialogAuto;
|
package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogManual.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReducedModel } from './types';
|
|
2
|
+
declare const WiggleClusterDialogManuals: ({ model, handleClose, children, }: {
|
|
3
|
+
model: ReducedModel;
|
|
4
|
+
handleClose: () => void;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default WiggleClusterDialogManuals;
|
package/esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogManual.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
4
|
+
import { getContainingView, getSession, isAbortException, useLocalStorage, } from '@jbrowse/core/util';
|
|
5
|
+
import { getRpcSessionId } from '@jbrowse/core/util/tracks';
|
|
6
|
+
import { Button, DialogActions, DialogContent, FormControlLabel, Radio, RadioGroup, TextField, Typography, } from '@mui/material';
|
|
7
|
+
import copy from 'copy-to-clipboard';
|
|
8
|
+
import { saveAs } from 'file-saver';
|
|
9
|
+
import { observer } from 'mobx-react';
|
|
10
|
+
import { isAlive } from 'mobx-state-tree';
|
|
11
|
+
import { makeStyles } from 'tss-react/mui';
|
|
12
|
+
const useStyles = makeStyles()(theme => ({
|
|
13
|
+
textAreaFont: {
|
|
14
|
+
fontFamily: 'Courier New',
|
|
15
|
+
},
|
|
16
|
+
mgap: {
|
|
17
|
+
display: 'flex',
|
|
18
|
+
flexDirection: 'column',
|
|
19
|
+
gap: theme.spacing(4),
|
|
20
|
+
},
|
|
21
|
+
}));
|
|
22
|
+
const WiggleClusterDialogManuals = observer(function ({ model, handleClose, children, }) {
|
|
23
|
+
const { classes } = useStyles();
|
|
24
|
+
const [paste, setPaste] = useState('');
|
|
25
|
+
const [ret, setRet] = useState();
|
|
26
|
+
const [error, setError] = useState();
|
|
27
|
+
const [loading, setLoading] = useState(false);
|
|
28
|
+
const [showAdvanced, setShowAdvanced] = useLocalStorage('cluster-showAdvanced', false);
|
|
29
|
+
const [clusterMethod, setClusterMethod] = useState('single');
|
|
30
|
+
const [samplesPerPixel, setSamplesPerPixel] = useState('1');
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
;
|
|
33
|
+
(async () => {
|
|
34
|
+
try {
|
|
35
|
+
setError(undefined);
|
|
36
|
+
setRet(undefined);
|
|
37
|
+
setLoading(true);
|
|
38
|
+
const view = getContainingView(model);
|
|
39
|
+
const { dynamicBlocks, bpPerPx } = view;
|
|
40
|
+
const { rpcManager } = getSession(model);
|
|
41
|
+
const { sourcesWithoutLayout, adapterConfig } = model;
|
|
42
|
+
const sessionId = getRpcSessionId(model);
|
|
43
|
+
const ret = (await rpcManager.call(sessionId, 'MultiWiggleGetScoreMatrix', {
|
|
44
|
+
regions: dynamicBlocks.contentBlocks,
|
|
45
|
+
sources: sourcesWithoutLayout,
|
|
46
|
+
sessionId,
|
|
47
|
+
adapterConfig,
|
|
48
|
+
bpPerPx: bpPerPx / +samplesPerPixel,
|
|
49
|
+
}));
|
|
50
|
+
setRet(ret);
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
if (!isAbortException(e) && isAlive(model)) {
|
|
54
|
+
console.error(e);
|
|
55
|
+
setError(e);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
setLoading(false);
|
|
60
|
+
}
|
|
61
|
+
})();
|
|
62
|
+
}, [model, samplesPerPixel]);
|
|
63
|
+
const results = ret
|
|
64
|
+
? `inputMatrix<-matrix(c(${Object.values(ret)
|
|
65
|
+
.map(val => val.join(','))
|
|
66
|
+
.join(',\n')}
|
|
67
|
+
),nrow=${Object.values(ret).length},byrow=TRUE)
|
|
68
|
+
rownames(inputMatrix)<-c(${Object.keys(ret)
|
|
69
|
+
.map(key => `'${key}'`)
|
|
70
|
+
.join(',')})
|
|
71
|
+
resultClusters<-hclust(dist(inputMatrix), method='${clusterMethod}')
|
|
72
|
+
cat(resultClusters$order,sep='\\n')`
|
|
73
|
+
: undefined;
|
|
74
|
+
const resultsTsv = ret
|
|
75
|
+
? Object.entries(ret)
|
|
76
|
+
.map(([key, val]) => [key, ...val].join('\t'))
|
|
77
|
+
.join('\n')
|
|
78
|
+
: undefined;
|
|
79
|
+
return (_jsxs(_Fragment, { children: [_jsxs(DialogContent, { children: [children, _jsxs("div", { style: { marginTop: 50 }, children: [_jsxs("div", { children: [_jsxs("div", { style: {
|
|
80
|
+
display: 'flex',
|
|
81
|
+
gap: '8px',
|
|
82
|
+
flexWrap: 'wrap',
|
|
83
|
+
marginBottom: '16px',
|
|
84
|
+
}, children: [_jsx(Button, { variant: "contained", onClick: () => {
|
|
85
|
+
saveAs(new Blob([results || ''], {
|
|
86
|
+
type: 'text/plain;charset=utf-8',
|
|
87
|
+
}), 'cluster.R');
|
|
88
|
+
}, children: "Download Rscript" }), ' ', "or", ' ', _jsx(Button, { variant: "contained", onClick: () => {
|
|
89
|
+
copy(results || '');
|
|
90
|
+
}, children: "Copy Rscript to clipboard" }), ' ', "or", ' ', _jsx(Button, { variant: "contained", onClick: () => {
|
|
91
|
+
saveAs(new Blob([resultsTsv || ''], {
|
|
92
|
+
type: 'text/plain;charset=utf-8',
|
|
93
|
+
}), 'scores.tsv');
|
|
94
|
+
}, children: "Download TSV" })] }), _jsx("div", { children: _jsx(Button, { variant: "contained", onClick: () => {
|
|
95
|
+
setShowAdvanced(!showAdvanced);
|
|
96
|
+
}, children: showAdvanced
|
|
97
|
+
? 'Hide advanced options'
|
|
98
|
+
: 'Show advanced options' }) }), showAdvanced ? (_jsxs("div", { children: [_jsx(Typography, { variant: "h6", children: "Advanced options" }), _jsx(RadioGroup, { children: Object.entries({
|
|
99
|
+
single: 'Single',
|
|
100
|
+
complete: 'Complete',
|
|
101
|
+
}).map(([key, val]) => (_jsx(FormControlLabel, { control: _jsx(Radio, { checked: clusterMethod === key, onChange: () => {
|
|
102
|
+
setClusterMethod(key);
|
|
103
|
+
} }), label: val }, key))) }), _jsxs("div", { style: { marginTop: 20 }, children: [_jsx(Typography, { children: "This procedure samples the data at each 'pixel' across the visible by default" }), _jsx(TextField, { label: "Samples per pixel (>1 for denser sampling, between 0-1 for sparser sampling)", variant: "outlined", size: "small", value: samplesPerPixel, onChange: event => {
|
|
104
|
+
setSamplesPerPixel(event.target.value);
|
|
105
|
+
} })] })] })) : null, results ? (_jsx("div", {})) : loading ? (_jsx(LoadingEllipses, { variant: "h6", title: "Generating score matrix" })) : error ? (_jsx(ErrorMessage, { error: error })) : null] }), _jsxs("div", { children: [_jsx(Typography, { variant: "subtitle2", gutterBottom: true, style: { marginTop: '16px' }, children: "Clustering Results:" }), _jsx(TextField, { multiline: true, fullWidth: true, variant: "outlined", placeholder: "Paste results from Rscript here (sequence of numbers, one per line, specifying the new ordering)", rows: 10, value: paste, onChange: event => {
|
|
106
|
+
setPaste(event.target.value);
|
|
107
|
+
}, slotProps: {
|
|
108
|
+
input: {
|
|
109
|
+
classes: {
|
|
110
|
+
input: classes.textAreaFont,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
} })] })] })] }), _jsxs(DialogActions, { children: [_jsx(Button, { variant: "contained", onClick: () => {
|
|
114
|
+
const { sourcesWithoutLayout } = model;
|
|
115
|
+
if (sourcesWithoutLayout) {
|
|
116
|
+
try {
|
|
117
|
+
model.setLayout(paste
|
|
118
|
+
.split('\n')
|
|
119
|
+
.map(t => t.trim())
|
|
120
|
+
.filter(f => !!f)
|
|
121
|
+
.map(r => +r)
|
|
122
|
+
.map(idx => {
|
|
123
|
+
const ret = sourcesWithoutLayout[idx - 1];
|
|
124
|
+
if (!ret) {
|
|
125
|
+
throw new Error(`out of bounds at ${idx}`);
|
|
126
|
+
}
|
|
127
|
+
return ret;
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
console.error(e);
|
|
132
|
+
getSession(model).notifyError(`${e}`, e);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
handleClose();
|
|
136
|
+
}, children: "Apply clustering" }), _jsx(Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
137
|
+
handleClose();
|
|
138
|
+
}, children: "Cancel" })] })] }));
|
|
139
|
+
});
|
|
140
|
+
export default WiggleClusterDialogManuals;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Source } from '../../types';
|
|
2
|
+
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
3
|
+
export interface ReducedModel {
|
|
4
|
+
sourcesWithoutLayout?: Source[];
|
|
5
|
+
adapterConfig: AnyConfigurationModel;
|
|
6
|
+
setLayout: (arg: Source[]) => void;
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { WiggleDisplayModel } from '../model';
|
|
2
|
+
import type { GridRowId } from '@mui/x-data-grid';
|
|
2
3
|
export declare function moveUp(arr: {
|
|
3
4
|
name: string;
|
|
4
|
-
}[], sel:
|
|
5
|
+
}[], sel: GridRowId[], by?: number): {
|
|
5
6
|
name: string;
|
|
6
7
|
}[];
|
|
7
8
|
export declare function moveDown(arr: {
|
|
8
9
|
name: string;
|
|
9
|
-
}[], sel:
|
|
10
|
+
}[], sel: GridRowId[], by?: number): {
|
|
10
11
|
name: string;
|
|
11
12
|
}[];
|
|
12
13
|
export declare function getOffset(model: WiggleDisplayModel): number;
|
|
@@ -259,11 +259,11 @@ export declare function stateModelFactory(_pluginManager: PluginManager, configS
|
|
|
259
259
|
setCrossHatches(cross: boolean): void;
|
|
260
260
|
} & {
|
|
261
261
|
readonly adapterTypeName: any;
|
|
262
|
-
readonly rendererTypeNameSimple:
|
|
262
|
+
readonly rendererTypeNameSimple: string;
|
|
263
263
|
readonly filters: undefined;
|
|
264
|
-
readonly scaleType:
|
|
265
|
-
readonly maxScore:
|
|
266
|
-
readonly minScore:
|
|
264
|
+
readonly scaleType: string;
|
|
265
|
+
readonly maxScore: number;
|
|
266
|
+
readonly minScore: number;
|
|
267
267
|
} & {
|
|
268
268
|
readonly adapterCapabilities: string[];
|
|
269
269
|
readonly rendererConfig: {
|
|
@@ -277,7 +277,7 @@ export declare function stateModelFactory(_pluginManager: PluginManager, configS
|
|
|
277
277
|
} & import("mobx-state-tree/dist/internal").NonEmptyObject & any & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
|
|
278
278
|
} & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
|
|
279
279
|
} & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
|
|
280
|
-
readonly autoscaleType:
|
|
280
|
+
readonly autoscaleType: string;
|
|
281
281
|
} & {
|
|
282
282
|
readonly domain: number[] | undefined;
|
|
283
283
|
} & {
|
|
@@ -290,9 +290,9 @@ export declare function stateModelFactory(_pluginManager: PluginManager, configS
|
|
|
290
290
|
scoreMin: number;
|
|
291
291
|
scoreMax: number;
|
|
292
292
|
} | undefined;
|
|
293
|
-
autoscaleType:
|
|
294
|
-
scaleType:
|
|
295
|
-
inverted:
|
|
293
|
+
autoscaleType: string;
|
|
294
|
+
scaleType: string;
|
|
295
|
+
inverted: boolean;
|
|
296
296
|
};
|
|
297
297
|
readonly canHaveFill: boolean;
|
|
298
298
|
readonly displayCrossHatchesSetting: boolean;
|
|
@@ -344,6 +344,12 @@ export declare function stateModelFactory(_pluginManager: PluginManager, configS
|
|
|
344
344
|
readonly canHaveFill: boolean;
|
|
345
345
|
readonly renderColorBoxes: boolean;
|
|
346
346
|
readonly prefersOffset: boolean;
|
|
347
|
+
readonly sourcesWithoutLayout: {
|
|
348
|
+
color: string;
|
|
349
|
+
baseUri?: string;
|
|
350
|
+
name: string;
|
|
351
|
+
group?: string;
|
|
352
|
+
}[] | undefined;
|
|
347
353
|
readonly sources: {
|
|
348
354
|
color: string;
|
|
349
355
|
baseUri?: string;
|
|
@@ -354,7 +360,7 @@ export declare function stateModelFactory(_pluginManager: PluginManager, configS
|
|
|
354
360
|
} & {
|
|
355
361
|
readonly rowHeight: number;
|
|
356
362
|
readonly rowHeightTooSmallForScalebar: boolean;
|
|
357
|
-
readonly useMinimalTicks:
|
|
363
|
+
readonly useMinimalTicks: boolean;
|
|
358
364
|
} & {
|
|
359
365
|
adapterProps(): any;
|
|
360
366
|
readonly ticks: {
|
|
@@ -11,7 +11,7 @@ import { YSCALEBAR_LABEL_OFFSET, getScale } from '../util';
|
|
|
11
11
|
const randomColor = () => '#000000'.replaceAll('0', () => (~~(Math.random() * 16)).toString(16));
|
|
12
12
|
const Tooltip = lazy(() => import('./components/Tooltip'));
|
|
13
13
|
const SetColorDialog = lazy(() => import('./components/SetColorDialog'));
|
|
14
|
-
const
|
|
14
|
+
const WiggleClusterDialog = lazy(() => import('./components/WiggleClusterDialog/WiggleClusterDialog'));
|
|
15
15
|
const rendererTypes = new Map([
|
|
16
16
|
['xyplot', 'MultiXYPlotRenderer'],
|
|
17
17
|
['multirowxy', 'MultiRowXYPlotRenderer'],
|
|
@@ -98,6 +98,19 @@ export function stateModelFactory(_pluginManager, configSchema) {
|
|
|
98
98
|
get prefersOffset() {
|
|
99
99
|
return this.isMultiRow;
|
|
100
100
|
},
|
|
101
|
+
get sourcesWithoutLayout() {
|
|
102
|
+
var _a;
|
|
103
|
+
const sources = Object.fromEntries(((_a = self.sourcesVolatile) === null || _a === void 0 ? void 0 : _a.map(s => [s.name, s])) || []);
|
|
104
|
+
const iter = self.sourcesVolatile;
|
|
105
|
+
return iter === null || iter === void 0 ? void 0 : iter.map(s => ({
|
|
106
|
+
...sources[s.name],
|
|
107
|
+
...s,
|
|
108
|
+
})).map((s, i) => ({
|
|
109
|
+
...s,
|
|
110
|
+
color: s.color ||
|
|
111
|
+
(!this.isMultiRow ? colors[i] || randomColor() : 'blue'),
|
|
112
|
+
}));
|
|
113
|
+
},
|
|
101
114
|
get sources() {
|
|
102
115
|
var _a;
|
|
103
116
|
const sources = Object.fromEntries(((_a = self.sourcesVolatile) === null || _a === void 0 ? void 0 : _a.map(s => [s.name, s])) || []);
|
|
@@ -125,7 +138,8 @@ export function stateModelFactory(_pluginManager, configSchema) {
|
|
|
125
138
|
return this.rowHeight < 70;
|
|
126
139
|
},
|
|
127
140
|
get useMinimalTicks() {
|
|
128
|
-
return (getConf(self, 'minimalTicks') ||
|
|
141
|
+
return (getConf(self, 'minimalTicks') ||
|
|
142
|
+
this.rowHeightTooSmallForScalebar);
|
|
129
143
|
},
|
|
130
144
|
}))
|
|
131
145
|
.views(self => {
|
|
@@ -255,18 +269,6 @@ export function stateModelFactory(_pluginManager, configSchema) {
|
|
|
255
269
|
},
|
|
256
270
|
]
|
|
257
271
|
: []),
|
|
258
|
-
...(self.graphType
|
|
259
|
-
? [
|
|
260
|
-
{
|
|
261
|
-
type: 'checkbox',
|
|
262
|
-
label: 'Draw cross hatches',
|
|
263
|
-
checked: self.displayCrossHatchesSetting,
|
|
264
|
-
onClick: () => {
|
|
265
|
-
self.toggleCrossHatches();
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
]
|
|
269
|
-
: []),
|
|
270
272
|
...(hasRenderings
|
|
271
273
|
? [
|
|
272
274
|
{
|
|
@@ -288,11 +290,23 @@ export function stateModelFactory(_pluginManager, configSchema) {
|
|
|
288
290
|
},
|
|
289
291
|
]
|
|
290
292
|
: []),
|
|
293
|
+
...(self.graphType
|
|
294
|
+
? [
|
|
295
|
+
{
|
|
296
|
+
type: 'checkbox',
|
|
297
|
+
label: 'Draw cross hatches',
|
|
298
|
+
checked: self.displayCrossHatchesSetting,
|
|
299
|
+
onClick: () => {
|
|
300
|
+
self.toggleCrossHatches();
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
]
|
|
304
|
+
: []),
|
|
291
305
|
{
|
|
292
306
|
label: 'Cluster by score',
|
|
293
307
|
onClick: () => {
|
|
294
308
|
getSession(self).queueDialog(handleClose => [
|
|
295
|
-
|
|
309
|
+
WiggleClusterDialog,
|
|
296
310
|
{
|
|
297
311
|
model: self,
|
|
298
312
|
handleClose,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { groupBy } from '@jbrowse/core/util';
|
|
1
|
+
import { forEachWithStopTokenCheck, groupBy } from '@jbrowse/core/util';
|
|
2
2
|
import WiggleBaseRenderer from '../WiggleBaseRenderer';
|
|
3
3
|
export default class MultiRowLineRenderer extends WiggleBaseRenderer {
|
|
4
4
|
async draw(ctx, props) {
|
|
5
|
-
const { bpPerPx, sources, regions, features } = props;
|
|
5
|
+
const { stopToken, bpPerPx, sources, regions, features } = props;
|
|
6
6
|
const region = regions[0];
|
|
7
7
|
const groups = groupBy(features.values(), f => f.get('source'));
|
|
8
8
|
const height = props.height / sources.length;
|
|
@@ -10,7 +10,7 @@ export default class MultiRowLineRenderer extends WiggleBaseRenderer {
|
|
|
10
10
|
const { drawLine } = await import('../drawLine');
|
|
11
11
|
let feats = [];
|
|
12
12
|
ctx.save();
|
|
13
|
-
sources
|
|
13
|
+
forEachWithStopTokenCheck(sources, stopToken, source => {
|
|
14
14
|
const { reducedFeatures } = drawLine(ctx, {
|
|
15
15
|
...props,
|
|
16
16
|
features: groups[source.name] || [],
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { groupBy } from '@jbrowse/core/util';
|
|
1
|
+
import { forEachWithStopTokenCheck, groupBy } from '@jbrowse/core/util';
|
|
2
2
|
import WiggleBaseRenderer from '../WiggleBaseRenderer';
|
|
3
3
|
export default class MultiXYPlotRenderer extends WiggleBaseRenderer {
|
|
4
4
|
async draw(ctx, props) {
|
|
5
|
-
const { bpPerPx, sources, regions, features } = props;
|
|
5
|
+
const { stopToken, bpPerPx, sources, regions, features } = props;
|
|
6
6
|
const region = regions[0];
|
|
7
7
|
const groups = groupBy(features.values(), f => f.get('source'));
|
|
8
8
|
const height = props.height / sources.length;
|
|
@@ -10,7 +10,7 @@ export default class MultiXYPlotRenderer extends WiggleBaseRenderer {
|
|
|
10
10
|
const { drawXY } = await import('../drawXY');
|
|
11
11
|
let feats = [];
|
|
12
12
|
ctx.save();
|
|
13
|
-
sources
|
|
13
|
+
forEachWithStopTokenCheck(sources, stopToken, source => {
|
|
14
14
|
const { reducedFeatures } = drawXY(ctx, {
|
|
15
15
|
...props,
|
|
16
16
|
features: groups[source.name] || [],
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { groupBy } from '@jbrowse/core/util';
|
|
1
|
+
import { forEachWithStopTokenCheck, groupBy } from '@jbrowse/core/util';
|
|
2
2
|
import WiggleBaseRenderer from '../WiggleBaseRenderer';
|
|
3
3
|
import { YSCALEBAR_LABEL_OFFSET } from '../util';
|
|
4
4
|
export default class MultiXYPlotRenderer extends WiggleBaseRenderer {
|
|
5
5
|
async draw(ctx, props) {
|
|
6
|
-
const { sources, features } = props;
|
|
6
|
+
const { stopToken, sources, features } = props;
|
|
7
7
|
const groups = groupBy(features.values(), f => f.get('source'));
|
|
8
8
|
const { drawXY } = await import('../drawXY');
|
|
9
9
|
let feats = [];
|
|
10
|
-
|
|
10
|
+
forEachWithStopTokenCheck(sources, stopToken, source => {
|
|
11
11
|
const features = groups[source.name] || [];
|
|
12
12
|
const { reducedFeatures } = drawXY(ctx, {
|
|
13
13
|
...props,
|
|
@@ -16,7 +16,7 @@ export default class MultiXYPlotRenderer extends WiggleBaseRenderer {
|
|
|
16
16
|
colorCallback: () => source.color || 'blue',
|
|
17
17
|
});
|
|
18
18
|
feats = feats.concat(reducedFeatures);
|
|
19
|
-
}
|
|
19
|
+
});
|
|
20
20
|
return { reducedFeatures: feats };
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -17,6 +17,7 @@ export interface RenderArgsDeserialized extends FeatureRenderArgsDeserialized {
|
|
|
17
17
|
};
|
|
18
18
|
inverted: boolean;
|
|
19
19
|
themeOptions: ThemeOptions;
|
|
20
|
+
statusCallback?: (arg: string) => void;
|
|
20
21
|
}
|
|
21
22
|
export interface RenderArgsDeserializedWithFeatures extends RenderArgsDeserialized {
|
|
22
23
|
features: Map<string, Feature>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import FeatureRendererType from '@jbrowse/core/pluggableElementTypes/renderers/FeatureRendererType';
|
|
2
|
-
import { renderToAbstractCanvas } from '@jbrowse/core/util';
|
|
2
|
+
import { renderToAbstractCanvas, updateStatus } from '@jbrowse/core/util';
|
|
3
3
|
export default class WiggleBaseRenderer extends FeatureRendererType {
|
|
4
4
|
constructor() {
|
|
5
5
|
super(...arguments);
|
|
@@ -7,14 +7,14 @@ export default class WiggleBaseRenderer extends FeatureRendererType {
|
|
|
7
7
|
}
|
|
8
8
|
async render(renderProps) {
|
|
9
9
|
const features = await this.getFeatures(renderProps);
|
|
10
|
-
const { inverted, height, regions, bpPerPx } = renderProps;
|
|
10
|
+
const { inverted, height, regions, bpPerPx, statusCallback = () => { }, } = renderProps;
|
|
11
11
|
const region = regions[0];
|
|
12
12
|
const width = (region.end - region.start) / bpPerPx;
|
|
13
|
-
const { reducedFeatures, ...rest } = await renderToAbstractCanvas(width, height, renderProps, ctx => this.draw(ctx, {
|
|
13
|
+
const { reducedFeatures, ...rest } = await updateStatus('Rendering plot', statusCallback, () => renderToAbstractCanvas(width, height, renderProps, ctx => this.draw(ctx, {
|
|
14
14
|
...renderProps,
|
|
15
15
|
features,
|
|
16
16
|
inverted,
|
|
17
|
-
}));
|
|
17
|
+
})));
|
|
18
18
|
const results = await super.render({
|
|
19
19
|
...renderProps,
|
|
20
20
|
...rest,
|
|
@@ -26,7 +26,7 @@ export default class WiggleBaseRenderer extends FeatureRendererType {
|
|
|
26
26
|
...results,
|
|
27
27
|
...rest,
|
|
28
28
|
features: reducedFeatures
|
|
29
|
-
? new Map(reducedFeatures.map(
|
|
29
|
+
? new Map(reducedFeatures.map(r => [r.id(), r]))
|
|
30
30
|
: results.features,
|
|
31
31
|
height,
|
|
32
32
|
width,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import RpcMethodTypeWithFiltersAndRenameRegions from '@jbrowse/core/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions';
|
|
2
|
+
import type { GetScoreMatrixArgs } from './types';
|
|
3
|
+
export declare class MultiWiggleClusterScoreMatrix extends RpcMethodTypeWithFiltersAndRenameRegions {
|
|
4
|
+
name: string;
|
|
5
|
+
execute(args: GetScoreMatrixArgs, rpcDriverClassName: string): Promise<{
|
|
6
|
+
clusters: {
|
|
7
|
+
height: number;
|
|
8
|
+
indexes: number[];
|
|
9
|
+
} | undefined;
|
|
10
|
+
distances: number[][];
|
|
11
|
+
order: number[];
|
|
12
|
+
clustersGivenK: number[][][];
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import RpcMethodTypeWithFiltersAndRenameRegions from '@jbrowse/core/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions';
|
|
2
|
+
import { clusterData } from '@jbrowse/core/util/cluster';
|
|
3
|
+
import { getScoreMatrix } from './getScoreMatrix';
|
|
4
|
+
export class MultiWiggleClusterScoreMatrix extends RpcMethodTypeWithFiltersAndRenameRegions {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.name = 'MultiWiggleClusterScoreMatrix';
|
|
8
|
+
}
|
|
9
|
+
async execute(args, rpcDriverClassName) {
|
|
10
|
+
const deserializedArgs = await this.deserializeArguments(args, rpcDriverClassName);
|
|
11
|
+
const matrix = await getScoreMatrix({
|
|
12
|
+
pluginManager: this.pluginManager,
|
|
13
|
+
args: deserializedArgs,
|
|
14
|
+
});
|
|
15
|
+
return clusterData({
|
|
16
|
+
data: Object.values(matrix),
|
|
17
|
+
stopToken: deserializedArgs.stopToken,
|
|
18
|
+
onProgress: a => {
|
|
19
|
+
var _a;
|
|
20
|
+
(_a = deserializedArgs.statusCallback) === null || _a === void 0 ? void 0 : _a.call(deserializedArgs, a);
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,17 +1,6 @@
|
|
|
1
1
|
import RpcMethodTypeWithFiltersAndRenameRegions from '@jbrowse/core/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions';
|
|
2
|
-
import {
|
|
3
|
-
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
2
|
+
import type { GetScoreMatrixArgs } from './types';
|
|
4
3
|
export declare class MultiWiggleGetScoreMatrix extends RpcMethodTypeWithFiltersAndRenameRegions {
|
|
5
4
|
name: string;
|
|
6
|
-
execute(args:
|
|
7
|
-
adapterConfig: AnyConfigurationModel;
|
|
8
|
-
stopToken?: string;
|
|
9
|
-
sessionId: string;
|
|
10
|
-
headers?: Record<string, string>;
|
|
11
|
-
regions: Region[];
|
|
12
|
-
bpPerPx: number;
|
|
13
|
-
}, rpcDriverClassName: string): Promise<Record<string, {
|
|
14
|
-
name: string;
|
|
15
|
-
scores: string[];
|
|
16
|
-
}>>;
|
|
5
|
+
execute(args: GetScoreMatrixArgs, rpcDriverClassName: string): Promise<Record<string, number[]>>;
|
|
17
6
|
}
|