@jbrowse/plugin-wiggle 3.2.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/MultiLinearWiggleDisplay/components/SourcesGrid.js +2 -2
- package/dist/MultiLinearWiggleDisplay/components/{ClusterDialog/ClusterDialog.d.ts → WiggleClusterDialog/WiggleClusterDialog.d.ts} +2 -2
- package/dist/MultiLinearWiggleDisplay/components/{ClusterDialog/ClusterDialog.js → WiggleClusterDialog/WiggleClusterDialog.js} +7 -7
- package/{esm/MultiLinearWiggleDisplay/components/ClusterDialog/ClusterDialogAuto.d.ts → dist/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogAuto.d.ts} +2 -2
- package/dist/MultiLinearWiggleDisplay/components/{ClusterDialog/ClusterDialogAuto.js → WiggleClusterDialog/WiggleClusterDialogAuto.js} +8 -5
- package/dist/MultiLinearWiggleDisplay/components/{ClusterDialog/ClusterDialogAuto.d.ts → WiggleClusterDialog/WiggleClusterDialogManual.d.ts} +3 -3
- package/dist/MultiLinearWiggleDisplay/components/{ClusterDialog/ClusterDialogManual.js → WiggleClusterDialog/WiggleClusterDialogManual.js} +32 -42
- package/dist/MultiLinearWiggleDisplay/components/util.d.ts +3 -2
- package/dist/MultiLinearWiggleDisplay/model.js +2 -2
- package/dist/WiggleBaseRenderer.js +1 -1
- package/dist/WiggleRPC/MultiWiggleClusterScoreMatrix.js +2 -5
- package/esm/MultiLinearWiggleDisplay/components/SourcesGrid.js +2 -2
- package/esm/MultiLinearWiggleDisplay/components/{ClusterDialog/ClusterDialog.d.ts → WiggleClusterDialog/WiggleClusterDialog.d.ts} +2 -2
- package/esm/MultiLinearWiggleDisplay/components/{ClusterDialog/ClusterDialog.js → WiggleClusterDialog/WiggleClusterDialog.js} +7 -7
- package/{dist/MultiLinearWiggleDisplay/components/ClusterDialog/ClusterDialogManual.d.ts → esm/MultiLinearWiggleDisplay/components/WiggleClusterDialog/WiggleClusterDialogAuto.d.ts} +3 -3
- package/esm/MultiLinearWiggleDisplay/components/{ClusterDialog/ClusterDialogAuto.js → WiggleClusterDialog/WiggleClusterDialogAuto.js} +8 -5
- package/esm/MultiLinearWiggleDisplay/components/{ClusterDialog/ClusterDialogManual.d.ts → WiggleClusterDialog/WiggleClusterDialogManual.d.ts} +2 -2
- package/esm/MultiLinearWiggleDisplay/components/{ClusterDialog/ClusterDialogManual.js → WiggleClusterDialog/WiggleClusterDialogManual.js} +33 -43
- package/esm/MultiLinearWiggleDisplay/components/util.d.ts +3 -2
- package/esm/MultiLinearWiggleDisplay/model.js +2 -2
- package/esm/WiggleBaseRenderer.js +1 -1
- package/esm/WiggleRPC/MultiWiggleClusterScoreMatrix.js +2 -5
- package/package.json +9 -9
- package/dist/WiggleRPC/cluster.d.ts +0 -17
- package/dist/WiggleRPC/cluster.js +0 -84
- package/esm/WiggleRPC/cluster.d.ts +0 -17
- package/esm/WiggleRPC/cluster.js +0 -79
- /package/dist/MultiLinearWiggleDisplay/components/{ClusterDialog → WiggleClusterDialog}/types.d.ts +0 -0
- /package/dist/MultiLinearWiggleDisplay/components/{ClusterDialog → WiggleClusterDialog}/types.js +0 -0
- /package/esm/MultiLinearWiggleDisplay/components/{ClusterDialog → WiggleClusterDialog}/types.d.ts +0 -0
- /package/esm/MultiLinearWiggleDisplay/components/{ClusterDialog → WiggleClusterDialog}/types.js +0 -0
|
@@ -87,8 +87,8 @@ function SourcesGrid({ rows, onChange, showTips, }) {
|
|
|
87
87
|
onChange([...rows]);
|
|
88
88
|
}, onClose: () => {
|
|
89
89
|
setAnchorEl(null);
|
|
90
|
-
} }), (0, jsx_runtime_1.jsx)("div", { style: { height: 400, width: '100%' }, children: (0, jsx_runtime_1.jsx)(x_data_grid_1.DataGrid, { getRowId: row => row.name, checkboxSelection: true,
|
|
91
|
-
setSelected(arg);
|
|
90
|
+
} }), (0, jsx_runtime_1.jsx)("div", { style: { height: 400, width: '100%' }, children: (0, jsx_runtime_1.jsx)(x_data_grid_1.DataGrid, { getRowId: row => row.name, checkboxSelection: true, onRowSelectionModelChange: arg => {
|
|
91
|
+
setSelected([...arg.ids]);
|
|
92
92
|
}, rows: rows, rowHeight: 25, columnHeaderHeight: 33, columns: [
|
|
93
93
|
{
|
|
94
94
|
field: 'color',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReducedModel } from './types';
|
|
2
|
-
declare const
|
|
2
|
+
declare const WiggleClusterDialog: ({ model, handleClose, }: {
|
|
3
3
|
model: ReducedModel;
|
|
4
4
|
handleClose: () => void;
|
|
5
5
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
-
export default
|
|
6
|
+
export default WiggleClusterDialog;
|
|
@@ -8,22 +8,22 @@ const react_1 = require("react");
|
|
|
8
8
|
const ui_1 = require("@jbrowse/core/ui");
|
|
9
9
|
const material_1 = require("@mui/material");
|
|
10
10
|
const mobx_react_1 = require("mobx-react");
|
|
11
|
-
const
|
|
12
|
-
const
|
|
11
|
+
const WiggleClusterDialogAuto_1 = __importDefault(require("./WiggleClusterDialogAuto"));
|
|
12
|
+
const WiggleClusterDialogManual_1 = __importDefault(require("./WiggleClusterDialogManual"));
|
|
13
13
|
function Header({ activeMode, setActiveMode, }) {
|
|
14
14
|
return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(material_1.RadioGroup, { children: Object.entries({
|
|
15
|
-
auto: ((0, jsx_runtime_1.jsx)("div", { children: "Run in-app clustering (
|
|
16
|
-
manual: ((0, jsx_runtime_1.jsx)("div", { children: "Download R script to run clustering (faster
|
|
15
|
+
auto: ((0, jsx_runtime_1.jsx)("div", { children: "Run in-app clustering (slower, particularly for large numbers of samples, uses JS implementation of hclust)" })),
|
|
16
|
+
manual: ((0, jsx_runtime_1.jsx)("div", { children: "Download R script to run clustering (faster, uses R implementation of hclust)" })),
|
|
17
17
|
}).map(([key, val]) => ((0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(material_1.Radio, { checked: activeMode === key, onChange: () => {
|
|
18
18
|
setActiveMode(key);
|
|
19
19
|
} }), label: val }, key))) }) }));
|
|
20
20
|
}
|
|
21
|
-
const
|
|
21
|
+
const WiggleClusterDialog = (0, mobx_react_1.observer)(function ({ model, handleClose, }) {
|
|
22
22
|
const [activeMode, setActiveMode] = (0, react_1.useState)('auto');
|
|
23
23
|
return ((0, jsx_runtime_1.jsx)(ui_1.Dialog, { open: true, title: "Cluster by score", maxWidth: "xl", onClose: (_, reason) => {
|
|
24
24
|
if (reason !== 'backdropClick') {
|
|
25
25
|
handleClose();
|
|
26
26
|
}
|
|
27
|
-
}, children: activeMode === 'auto' ? ((0, jsx_runtime_1.jsx)(
|
|
27
|
+
}, children: activeMode === 'auto' ? ((0, jsx_runtime_1.jsx)(WiggleClusterDialogAuto_1.default, { model: model, handleClose: handleClose, children: (0, jsx_runtime_1.jsx)(Header, { activeMode: activeMode, setActiveMode: setActiveMode }) })) : ((0, jsx_runtime_1.jsx)(WiggleClusterDialogManual_1.default, { model: model, handleClose: handleClose, children: (0, jsx_runtime_1.jsx)(Header, { activeMode: activeMode, setActiveMode: setActiveMode }) })) }));
|
|
28
28
|
});
|
|
29
|
-
exports.default =
|
|
29
|
+
exports.default = WiggleClusterDialog;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReducedModel } from './types';
|
|
2
|
-
declare const
|
|
2
|
+
declare const WiggleClusterDialogAuto: ({ model, children, handleClose, }: {
|
|
3
3
|
model: ReducedModel;
|
|
4
4
|
children: React.ReactNode;
|
|
5
5
|
handleClose: () => void;
|
|
6
6
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
export default
|
|
7
|
+
export default WiggleClusterDialogAuto;
|
|
@@ -9,9 +9,10 @@ const tracks_1 = require("@jbrowse/core/util/tracks");
|
|
|
9
9
|
const material_1 = require("@mui/material");
|
|
10
10
|
const mobx_react_1 = require("mobx-react");
|
|
11
11
|
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
12
|
-
const
|
|
12
|
+
const WiggleClusterDialogAuto = (0, mobx_react_1.observer)(function ({ model, children, handleClose, }) {
|
|
13
13
|
const [progress, setProgress] = (0, react_1.useState)('');
|
|
14
14
|
const [error, setError] = (0, react_1.useState)();
|
|
15
|
+
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
15
16
|
const [stopToken, setStopToken] = (0, react_1.useState)('');
|
|
16
17
|
const [showAdvanced, setShowAdvanced] = (0, react_1.useState)(false);
|
|
17
18
|
const [samplesPerPixel, setSamplesPerPixel] = (0, util_1.useLocalStorage)('cluster-samplesPerPixel', '1');
|
|
@@ -19,12 +20,13 @@ const ClusterDialogAuto = (0, mobx_react_1.observer)(function ({ model, children
|
|
|
19
20
|
setShowAdvanced(!showAdvanced);
|
|
20
21
|
}, children: showAdvanced ? 'Hide advanced options' : 'Show advanced options' }), showAdvanced ? ((0, jsx_runtime_1.jsxs)("div", { style: { marginTop: 20 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { children: "This procedure samples the data at each 'pixel' across the visible by default" }), (0, jsx_runtime_1.jsx)(material_1.TextField, { label: "Samples per pixel (>1 for denser sampling, between 0-1 for sparser sampling)", variant: "outlined", size: "small", value: samplesPerPixel, onChange: event => {
|
|
21
22
|
setSamplesPerPixel(event.target.value);
|
|
22
|
-
} })] })) : null] }), (0, jsx_runtime_1.jsxs)("div", { children: [
|
|
23
|
+
} })] })) : null] }), (0, jsx_runtime_1.jsxs)("div", { children: [loading ? ((0, jsx_runtime_1.jsxs)("div", { style: { padding: 50 }, children: [(0, jsx_runtime_1.jsx)("span", { children: progress || 'Loading...' }), (0, jsx_runtime_1.jsx)(material_1.Button, { onClick: () => {
|
|
23
24
|
(0, stopToken_1.stopStopToken)(stopToken);
|
|
24
|
-
}, children: "Stop" })] })) : null, error ? (0, jsx_runtime_1.jsx)(ui_1.ErrorMessage, { error: error }) : null] })] }), (0, jsx_runtime_1.jsxs)(material_1.DialogActions, { children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: async () => {
|
|
25
|
+
}, children: "Stop" })] })) : null, error ? (0, jsx_runtime_1.jsx)(ui_1.ErrorMessage, { error: error }) : null] })] }), (0, jsx_runtime_1.jsxs)(material_1.DialogActions, { children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", disabled: loading, onClick: async () => {
|
|
25
26
|
try {
|
|
26
27
|
setError(undefined);
|
|
27
|
-
setProgress('');
|
|
28
|
+
setProgress('Initializing');
|
|
29
|
+
setLoading(true);
|
|
28
30
|
const view = (0, util_1.getContainingView)(model);
|
|
29
31
|
if (!view.initialized) {
|
|
30
32
|
return;
|
|
@@ -63,6 +65,7 @@ const ClusterDialogAuto = (0, mobx_react_1.observer)(function ({ model, children
|
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
finally {
|
|
68
|
+
setLoading(false);
|
|
66
69
|
setProgress('');
|
|
67
70
|
setStopToken('');
|
|
68
71
|
}
|
|
@@ -73,4 +76,4 @@ const ClusterDialogAuto = (0, mobx_react_1.observer)(function ({ model, children
|
|
|
73
76
|
}
|
|
74
77
|
}, children: "Cancel" })] })] }));
|
|
75
78
|
});
|
|
76
|
-
exports.default =
|
|
79
|
+
exports.default = WiggleClusterDialogAuto;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReducedModel } from './types';
|
|
2
|
-
declare const
|
|
2
|
+
declare const WiggleClusterDialogManuals: ({ model, handleClose, children, }: {
|
|
3
3
|
model: ReducedModel;
|
|
4
|
-
children: React.ReactNode;
|
|
5
4
|
handleClose: () => void;
|
|
5
|
+
children: React.ReactNode;
|
|
6
6
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
export default
|
|
7
|
+
export default WiggleClusterDialogManuals;
|
|
@@ -8,7 +8,6 @@ const react_1 = require("react");
|
|
|
8
8
|
const ui_1 = require("@jbrowse/core/ui");
|
|
9
9
|
const util_1 = require("@jbrowse/core/util");
|
|
10
10
|
const tracks_1 = require("@jbrowse/core/util/tracks");
|
|
11
|
-
const Menu_1 = __importDefault(require("@mui/icons-material/Menu"));
|
|
12
11
|
const material_1 = require("@mui/material");
|
|
13
12
|
const copy_to_clipboard_1 = __importDefault(require("copy-to-clipboard"));
|
|
14
13
|
const file_saver_1 = require("file-saver");
|
|
@@ -25,15 +24,15 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
25
24
|
gap: theme.spacing(4),
|
|
26
25
|
},
|
|
27
26
|
}));
|
|
28
|
-
const
|
|
27
|
+
const WiggleClusterDialogManuals = (0, mobx_react_1.observer)(function ({ model, handleClose, children, }) {
|
|
29
28
|
const { classes } = useStyles();
|
|
30
29
|
const [paste, setPaste] = (0, react_1.useState)('');
|
|
31
30
|
const [ret, setRet] = (0, react_1.useState)();
|
|
32
31
|
const [error, setError] = (0, react_1.useState)();
|
|
33
32
|
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
34
|
-
const [showAdvanced, setShowAdvanced] = (0,
|
|
35
|
-
const [clusterMethod, setClusterMethod] = (0,
|
|
36
|
-
const [samplesPerPixel, setSamplesPerPixel] = (0,
|
|
33
|
+
const [showAdvanced, setShowAdvanced] = (0, util_1.useLocalStorage)('cluster-showAdvanced', false);
|
|
34
|
+
const [clusterMethod, setClusterMethod] = (0, react_1.useState)('single');
|
|
35
|
+
const [samplesPerPixel, setSamplesPerPixel] = (0, react_1.useState)('1');
|
|
37
36
|
(0, react_1.useEffect)(() => {
|
|
38
37
|
;
|
|
39
38
|
(async () => {
|
|
@@ -82,42 +81,33 @@ cat(resultClusters$order,sep='\\n')`
|
|
|
82
81
|
.map(([key, val]) => [key, ...val].join('\t'))
|
|
83
82
|
.join('\n')
|
|
84
83
|
: undefined;
|
|
85
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(material_1.DialogContent, { children: [children, (0, jsx_runtime_1.jsxs)("div", { style: { marginTop: 50 }, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
},
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
},
|
|
113
|
-
], children: (0, jsx_runtime_1.jsx)(Menu_1.default, {}) }) }), (0, jsx_runtime_1.jsx)("div", { children: showAdvanced ? ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", children: "Advanced options" }), (0, jsx_runtime_1.jsx)(material_1.RadioGroup, { children: Object.entries({
|
|
114
|
-
single: 'Single',
|
|
115
|
-
complete: 'Complete',
|
|
116
|
-
}).map(([key, val]) => ((0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(material_1.Radio, { checked: clusterMethod === key, onChange: () => {
|
|
117
|
-
setClusterMethod(key);
|
|
118
|
-
} }), label: val }, key))) }), (0, jsx_runtime_1.jsxs)("div", { style: { marginTop: 20 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { children: "This procedure samples the data at each 'pixel' across the visible by default" }), (0, jsx_runtime_1.jsx)(material_1.TextField, { label: "Samples per pixel (>1 for denser sampling, between 0-1 for sparser sampling)", variant: "outlined", size: "small", value: samplesPerPixel, onChange: event => {
|
|
119
|
-
setSamplesPerPixel(event.target.value);
|
|
120
|
-
} })] })] })) : null }), results ? ((0, jsx_runtime_1.jsx)("div", {})) : loading ? ((0, jsx_runtime_1.jsx)(ui_1.LoadingEllipses, { variant: "h6", title: "Generating score matrix" })) : error ? ((0, jsx_runtime_1.jsx)(ui_1.ErrorMessage, { error: error })) : null] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", gutterBottom: true, style: { marginTop: '16px' }, children: "Clustering Results:" }), (0, jsx_runtime_1.jsx)(material_1.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 => {
|
|
84
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(material_1.DialogContent, { children: [children, (0, jsx_runtime_1.jsxs)("div", { style: { marginTop: 50 }, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { style: {
|
|
85
|
+
display: 'flex',
|
|
86
|
+
gap: '8px',
|
|
87
|
+
flexWrap: 'wrap',
|
|
88
|
+
marginBottom: '16px',
|
|
89
|
+
}, children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => {
|
|
90
|
+
(0, file_saver_1.saveAs)(new Blob([results || ''], {
|
|
91
|
+
type: 'text/plain;charset=utf-8',
|
|
92
|
+
}), 'cluster.R');
|
|
93
|
+
}, children: "Download Rscript" }), ' ', "or", ' ', (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => {
|
|
94
|
+
(0, copy_to_clipboard_1.default)(results || '');
|
|
95
|
+
}, children: "Copy Rscript to clipboard" }), ' ', "or", ' ', (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => {
|
|
96
|
+
(0, file_saver_1.saveAs)(new Blob([resultsTsv || ''], {
|
|
97
|
+
type: 'text/plain;charset=utf-8',
|
|
98
|
+
}), 'scores.tsv');
|
|
99
|
+
}, children: "Download TSV" })] }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => {
|
|
100
|
+
setShowAdvanced(!showAdvanced);
|
|
101
|
+
}, children: showAdvanced
|
|
102
|
+
? 'Hide advanced options'
|
|
103
|
+
: 'Show advanced options' }) }), showAdvanced ? ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", children: "Advanced options" }), (0, jsx_runtime_1.jsx)(material_1.RadioGroup, { children: Object.entries({
|
|
104
|
+
single: 'Single',
|
|
105
|
+
complete: 'Complete',
|
|
106
|
+
}).map(([key, val]) => ((0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(material_1.Radio, { checked: clusterMethod === key, onChange: () => {
|
|
107
|
+
setClusterMethod(key);
|
|
108
|
+
} }), label: val }, key))) }), (0, jsx_runtime_1.jsxs)("div", { style: { marginTop: 20 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { children: "This procedure samples the data at each 'pixel' across the visible by default" }), (0, jsx_runtime_1.jsx)(material_1.TextField, { label: "Samples per pixel (>1 for denser sampling, between 0-1 for sparser sampling)", variant: "outlined", size: "small", value: samplesPerPixel, onChange: event => {
|
|
109
|
+
setSamplesPerPixel(event.target.value);
|
|
110
|
+
} })] })] })) : null, results ? ((0, jsx_runtime_1.jsx)("div", {})) : loading ? ((0, jsx_runtime_1.jsx)(ui_1.LoadingEllipses, { variant: "h6", title: "Generating score matrix" })) : error ? ((0, jsx_runtime_1.jsx)(ui_1.ErrorMessage, { error: error })) : null] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", gutterBottom: true, style: { marginTop: '16px' }, children: "Clustering Results:" }), (0, jsx_runtime_1.jsx)(material_1.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 => {
|
|
121
111
|
setPaste(event.target.value);
|
|
122
112
|
}, slotProps: {
|
|
123
113
|
input: {
|
|
@@ -152,4 +142,4 @@ cat(resultClusters$order,sep='\\n')`
|
|
|
152
142
|
handleClose();
|
|
153
143
|
}, children: "Cancel" })] })] }));
|
|
154
144
|
});
|
|
155
|
-
exports.default =
|
|
145
|
+
exports.default = WiggleClusterDialogManuals;
|
|
@@ -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;
|
|
@@ -50,7 +50,7 @@ const util_2 = require("../util");
|
|
|
50
50
|
const randomColor = () => '#000000'.replaceAll('0', () => (~~(Math.random() * 16)).toString(16));
|
|
51
51
|
const Tooltip = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/Tooltip'))));
|
|
52
52
|
const SetColorDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/SetColorDialog'))));
|
|
53
|
-
const
|
|
53
|
+
const WiggleClusterDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/WiggleClusterDialog/WiggleClusterDialog'))));
|
|
54
54
|
const rendererTypes = new Map([
|
|
55
55
|
['xyplot', 'MultiXYPlotRenderer'],
|
|
56
56
|
['multirowxy', 'MultiRowXYPlotRenderer'],
|
|
@@ -345,7 +345,7 @@ function stateModelFactory(_pluginManager, configSchema) {
|
|
|
345
345
|
label: 'Cluster by score',
|
|
346
346
|
onClick: () => {
|
|
347
347
|
(0, util_1.getSession)(self).queueDialog(handleClose => [
|
|
348
|
-
|
|
348
|
+
WiggleClusterDialog,
|
|
349
349
|
{
|
|
350
350
|
model: self,
|
|
351
351
|
handleClose,
|
|
@@ -31,7 +31,7 @@ class WiggleBaseRenderer extends FeatureRendererType_1.default {
|
|
|
31
31
|
...results,
|
|
32
32
|
...rest,
|
|
33
33
|
features: reducedFeatures
|
|
34
|
-
? new Map(reducedFeatures.map(
|
|
34
|
+
? new Map(reducedFeatures.map(r => [r.id(), r]))
|
|
35
35
|
: results.features,
|
|
36
36
|
height,
|
|
37
37
|
width,
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.MultiWiggleClusterScoreMatrix = void 0;
|
|
7
7
|
const RpcMethodTypeWithFiltersAndRenameRegions_1 = __importDefault(require("@jbrowse/core/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions"));
|
|
8
|
-
const cluster_1 = require("
|
|
8
|
+
const cluster_1 = require("@jbrowse/core/util/cluster");
|
|
9
9
|
const getScoreMatrix_1 = require("./getScoreMatrix");
|
|
10
10
|
class MultiWiggleClusterScoreMatrix extends RpcMethodTypeWithFiltersAndRenameRegions_1.default {
|
|
11
11
|
constructor() {
|
|
@@ -23,12 +23,9 @@ class MultiWiggleClusterScoreMatrix extends RpcMethodTypeWithFiltersAndRenameReg
|
|
|
23
23
|
stopToken: deserializedArgs.stopToken,
|
|
24
24
|
onProgress: a => {
|
|
25
25
|
var _a;
|
|
26
|
-
(_a = deserializedArgs.statusCallback) === null || _a === void 0 ? void 0 : _a.call(deserializedArgs,
|
|
26
|
+
(_a = deserializedArgs.statusCallback) === null || _a === void 0 ? void 0 : _a.call(deserializedArgs, a);
|
|
27
27
|
},
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
exports.MultiWiggleClusterScoreMatrix = MultiWiggleClusterScoreMatrix;
|
|
32
|
-
function toP(n) {
|
|
33
|
-
return Number.parseFloat(n.toPrecision(3));
|
|
34
|
-
}
|
|
@@ -49,8 +49,8 @@ function SourcesGrid({ rows, onChange, showTips, }) {
|
|
|
49
49
|
onChange([...rows]);
|
|
50
50
|
}, onClose: () => {
|
|
51
51
|
setAnchorEl(null);
|
|
52
|
-
} }), _jsx("div", { style: { height: 400, width: '100%' }, children: _jsx(DataGrid, { getRowId: row => row.name, checkboxSelection: true,
|
|
53
|
-
setSelected(arg);
|
|
52
|
+
} }), _jsx("div", { style: { height: 400, width: '100%' }, children: _jsx(DataGrid, { getRowId: row => row.name, checkboxSelection: true, onRowSelectionModelChange: arg => {
|
|
53
|
+
setSelected([...arg.ids]);
|
|
54
54
|
}, rows: rows, rowHeight: 25, columnHeaderHeight: 33, columns: [
|
|
55
55
|
{
|
|
56
56
|
field: 'color',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReducedModel } from './types';
|
|
2
|
-
declare const
|
|
2
|
+
declare const WiggleClusterDialog: ({ model, handleClose, }: {
|
|
3
3
|
model: ReducedModel;
|
|
4
4
|
handleClose: () => void;
|
|
5
5
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
-
export default
|
|
6
|
+
export default WiggleClusterDialog;
|
|
@@ -3,22 +3,22 @@ import { useState } from 'react';
|
|
|
3
3
|
import { Dialog } from '@jbrowse/core/ui';
|
|
4
4
|
import { FormControlLabel, Radio, RadioGroup } from '@mui/material';
|
|
5
5
|
import { observer } from 'mobx-react';
|
|
6
|
-
import
|
|
7
|
-
import
|
|
6
|
+
import WiggleClusterDialogAuto from './WiggleClusterDialogAuto';
|
|
7
|
+
import WiggleClusterDialogManual from './WiggleClusterDialogManual';
|
|
8
8
|
function Header({ activeMode, setActiveMode, }) {
|
|
9
9
|
return (_jsx("div", { children: _jsx(RadioGroup, { children: Object.entries({
|
|
10
|
-
auto: (_jsx("div", { children: "Run in-app clustering (
|
|
11
|
-
manual: (_jsx("div", { children: "Download R script to run clustering (faster
|
|
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
12
|
}).map(([key, val]) => (_jsx(FormControlLabel, { control: _jsx(Radio, { checked: activeMode === key, onChange: () => {
|
|
13
13
|
setActiveMode(key);
|
|
14
14
|
} }), label: val }, key))) }) }));
|
|
15
15
|
}
|
|
16
|
-
const
|
|
16
|
+
const WiggleClusterDialog = observer(function ({ model, handleClose, }) {
|
|
17
17
|
const [activeMode, setActiveMode] = useState('auto');
|
|
18
18
|
return (_jsx(Dialog, { open: true, title: "Cluster by score", maxWidth: "xl", onClose: (_, reason) => {
|
|
19
19
|
if (reason !== 'backdropClick') {
|
|
20
20
|
handleClose();
|
|
21
21
|
}
|
|
22
|
-
}, children: activeMode === 'auto' ? (_jsx(
|
|
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
23
|
});
|
|
24
|
-
export default
|
|
24
|
+
export default WiggleClusterDialog;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReducedModel } from './types';
|
|
2
|
-
declare const
|
|
2
|
+
declare const WiggleClusterDialogAuto: ({ model, children, handleClose, }: {
|
|
3
3
|
model: ReducedModel;
|
|
4
|
-
handleClose: () => void;
|
|
5
4
|
children: React.ReactNode;
|
|
5
|
+
handleClose: () => void;
|
|
6
6
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
export default
|
|
7
|
+
export default WiggleClusterDialogAuto;
|
|
@@ -7,9 +7,10 @@ import { getRpcSessionId } from '@jbrowse/core/util/tracks';
|
|
|
7
7
|
import { Button, DialogActions, DialogContent, TextField, Typography, } from '@mui/material';
|
|
8
8
|
import { observer } from 'mobx-react';
|
|
9
9
|
import { isAlive } from 'mobx-state-tree';
|
|
10
|
-
const
|
|
10
|
+
const WiggleClusterDialogAuto = observer(function ({ model, children, handleClose, }) {
|
|
11
11
|
const [progress, setProgress] = useState('');
|
|
12
12
|
const [error, setError] = useState();
|
|
13
|
+
const [loading, setLoading] = useState(false);
|
|
13
14
|
const [stopToken, setStopToken] = useState('');
|
|
14
15
|
const [showAdvanced, setShowAdvanced] = useState(false);
|
|
15
16
|
const [samplesPerPixel, setSamplesPerPixel] = useLocalStorage('cluster-samplesPerPixel', '1');
|
|
@@ -17,12 +18,13 @@ const ClusterDialogAuto = observer(function ({ model, children, handleClose, })
|
|
|
17
18
|
setShowAdvanced(!showAdvanced);
|
|
18
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 => {
|
|
19
20
|
setSamplesPerPixel(event.target.value);
|
|
20
|
-
} })] })) : null] }), _jsxs("div", { children: [
|
|
21
|
+
} })] })) : null] }), _jsxs("div", { children: [loading ? (_jsxs("div", { style: { padding: 50 }, children: [_jsx("span", { children: progress || 'Loading...' }), _jsx(Button, { onClick: () => {
|
|
21
22
|
stopStopToken(stopToken);
|
|
22
|
-
}, children: "Stop" })] })) : null, error ? _jsx(ErrorMessage, { error: error }) : null] })] }), _jsxs(DialogActions, { children: [_jsx(Button, { variant: "contained", onClick: async () => {
|
|
23
|
+
}, children: "Stop" })] })) : null, error ? _jsx(ErrorMessage, { error: error }) : null] })] }), _jsxs(DialogActions, { children: [_jsx(Button, { variant: "contained", disabled: loading, onClick: async () => {
|
|
23
24
|
try {
|
|
24
25
|
setError(undefined);
|
|
25
|
-
setProgress('');
|
|
26
|
+
setProgress('Initializing');
|
|
27
|
+
setLoading(true);
|
|
26
28
|
const view = getContainingView(model);
|
|
27
29
|
if (!view.initialized) {
|
|
28
30
|
return;
|
|
@@ -61,6 +63,7 @@ const ClusterDialogAuto = observer(function ({ model, children, handleClose, })
|
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
finally {
|
|
66
|
+
setLoading(false);
|
|
64
67
|
setProgress('');
|
|
65
68
|
setStopToken('');
|
|
66
69
|
}
|
|
@@ -71,4 +74,4 @@ const ClusterDialogAuto = observer(function ({ model, children, handleClose, })
|
|
|
71
74
|
}
|
|
72
75
|
}, children: "Cancel" })] })] }));
|
|
73
76
|
});
|
|
74
|
-
export default
|
|
77
|
+
export default WiggleClusterDialogAuto;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReducedModel } from './types';
|
|
2
|
-
declare const
|
|
2
|
+
declare const WiggleClusterDialogManuals: ({ model, handleClose, children, }: {
|
|
3
3
|
model: ReducedModel;
|
|
4
4
|
handleClose: () => void;
|
|
5
5
|
children: React.ReactNode;
|
|
6
6
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
export default
|
|
7
|
+
export default WiggleClusterDialogManuals;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
4
4
|
import { getContainingView, getSession, isAbortException, useLocalStorage, } from '@jbrowse/core/util';
|
|
5
5
|
import { getRpcSessionId } from '@jbrowse/core/util/tracks';
|
|
6
|
-
import MenuIcon from '@mui/icons-material/Menu';
|
|
7
6
|
import { Button, DialogActions, DialogContent, FormControlLabel, Radio, RadioGroup, TextField, Typography, } from '@mui/material';
|
|
8
7
|
import copy from 'copy-to-clipboard';
|
|
9
8
|
import { saveAs } from 'file-saver';
|
|
@@ -20,15 +19,15 @@ const useStyles = makeStyles()(theme => ({
|
|
|
20
19
|
gap: theme.spacing(4),
|
|
21
20
|
},
|
|
22
21
|
}));
|
|
23
|
-
const
|
|
22
|
+
const WiggleClusterDialogManuals = observer(function ({ model, handleClose, children, }) {
|
|
24
23
|
const { classes } = useStyles();
|
|
25
24
|
const [paste, setPaste] = useState('');
|
|
26
25
|
const [ret, setRet] = useState();
|
|
27
26
|
const [error, setError] = useState();
|
|
28
27
|
const [loading, setLoading] = useState(false);
|
|
29
|
-
const [showAdvanced, setShowAdvanced] =
|
|
30
|
-
const [clusterMethod, setClusterMethod] =
|
|
31
|
-
const [samplesPerPixel, setSamplesPerPixel] =
|
|
28
|
+
const [showAdvanced, setShowAdvanced] = useLocalStorage('cluster-showAdvanced', false);
|
|
29
|
+
const [clusterMethod, setClusterMethod] = useState('single');
|
|
30
|
+
const [samplesPerPixel, setSamplesPerPixel] = useState('1');
|
|
32
31
|
useEffect(() => {
|
|
33
32
|
;
|
|
34
33
|
(async () => {
|
|
@@ -77,42 +76,33 @@ cat(resultClusters$order,sep='\\n')`
|
|
|
77
76
|
.map(([key, val]) => [key, ...val].join('\t'))
|
|
78
77
|
.join('\n')
|
|
79
78
|
: undefined;
|
|
80
|
-
return (_jsxs(_Fragment, { children: [_jsxs(DialogContent, { children: [children, _jsxs("div", { style: { marginTop: 50 }, children: [_jsxs("div", { style: {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
},
|
|
108
|
-
], children: _jsx(MenuIcon, {}) }) }), _jsx("div", { children: showAdvanced ? (_jsxs("div", { children: [_jsx(Typography, { variant: "h6", children: "Advanced options" }), _jsx(RadioGroup, { children: Object.entries({
|
|
109
|
-
single: 'Single',
|
|
110
|
-
complete: 'Complete',
|
|
111
|
-
}).map(([key, val]) => (_jsx(FormControlLabel, { control: _jsx(Radio, { checked: clusterMethod === key, onChange: () => {
|
|
112
|
-
setClusterMethod(key);
|
|
113
|
-
} }), 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 => {
|
|
114
|
-
setSamplesPerPixel(event.target.value);
|
|
115
|
-
} })] })] })) : 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 => {
|
|
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 => {
|
|
116
106
|
setPaste(event.target.value);
|
|
117
107
|
}, slotProps: {
|
|
118
108
|
input: {
|
|
@@ -147,4 +137,4 @@ cat(resultClusters$order,sep='\\n')`
|
|
|
147
137
|
handleClose();
|
|
148
138
|
}, children: "Cancel" })] })] }));
|
|
149
139
|
});
|
|
150
|
-
export default
|
|
140
|
+
export default WiggleClusterDialogManuals;
|
|
@@ -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;
|
|
@@ -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'],
|
|
@@ -306,7 +306,7 @@ export function stateModelFactory(_pluginManager, configSchema) {
|
|
|
306
306
|
label: 'Cluster by score',
|
|
307
307
|
onClick: () => {
|
|
308
308
|
getSession(self).queueDialog(handleClose => [
|
|
309
|
-
|
|
309
|
+
WiggleClusterDialog,
|
|
310
310
|
{
|
|
311
311
|
model: self,
|
|
312
312
|
handleClose,
|
|
@@ -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,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import RpcMethodTypeWithFiltersAndRenameRegions from '@jbrowse/core/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions';
|
|
2
|
-
import { clusterData } from '
|
|
2
|
+
import { clusterData } from '@jbrowse/core/util/cluster';
|
|
3
3
|
import { getScoreMatrix } from './getScoreMatrix';
|
|
4
4
|
export class MultiWiggleClusterScoreMatrix extends RpcMethodTypeWithFiltersAndRenameRegions {
|
|
5
5
|
constructor() {
|
|
@@ -17,11 +17,8 @@ export class MultiWiggleClusterScoreMatrix extends RpcMethodTypeWithFiltersAndRe
|
|
|
17
17
|
stopToken: deserializedArgs.stopToken,
|
|
18
18
|
onProgress: a => {
|
|
19
19
|
var _a;
|
|
20
|
-
(_a = deserializedArgs.statusCallback) === null || _a === void 0 ? void 0 : _a.call(deserializedArgs,
|
|
20
|
+
(_a = deserializedArgs.statusCallback) === null || _a === void 0 ? void 0 : _a.call(deserializedArgs, a);
|
|
21
21
|
},
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
function toP(n) {
|
|
26
|
-
return Number.parseFloat(n.toPrecision(3));
|
|
27
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-wiggle",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "JBrowse 2 wiggle adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@gmod/bbi": "^6.0.0",
|
|
40
|
-
"@jbrowse/core": "^3.
|
|
41
|
-
"@jbrowse/plugin-data-management": "^3.
|
|
42
|
-
"@jbrowse/plugin-linear-genome-view": "^3.
|
|
43
|
-
"@mui/icons-material": "^
|
|
44
|
-
"@mui/material": "^
|
|
45
|
-
"@mui/x-charts-vendor": "^
|
|
46
|
-
"@mui/x-data-grid": "^
|
|
40
|
+
"@jbrowse/core": "^3.3.0",
|
|
41
|
+
"@jbrowse/plugin-data-management": "^3.3.0",
|
|
42
|
+
"@jbrowse/plugin-linear-genome-view": "^3.3.0",
|
|
43
|
+
"@mui/icons-material": "^7.0.0",
|
|
44
|
+
"@mui/material": "^7.0.0",
|
|
45
|
+
"@mui/x-charts-vendor": "^8.0.0",
|
|
46
|
+
"@mui/x-data-grid": "^8.0.0",
|
|
47
47
|
"fast-deep-equal": "^3.1.3",
|
|
48
48
|
"mobx": "^6.0.0",
|
|
49
49
|
"mobx-react": "^9.0.0",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"distModule": "esm/index.js",
|
|
63
63
|
"srcModule": "src/index.ts",
|
|
64
64
|
"module": "esm/index.js",
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "0bb64d8cc7ecdd167515308b31eec3d9acbc59e4"
|
|
66
66
|
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export declare function euclideanDistance(a: number[], b: number[]): number;
|
|
2
|
-
export declare function averageDistance(setA: number[], setB: number[], distances: number[][]): number;
|
|
3
|
-
export declare function clusterData({ data, distance, linkage, onProgress, stopToken, }: {
|
|
4
|
-
data: number[][];
|
|
5
|
-
distance?: (a: number[], b: number[]) => number;
|
|
6
|
-
linkage?: (a: number[], b: number[], distances: number[][]) => number;
|
|
7
|
-
onProgress?: (a: number) => void;
|
|
8
|
-
stopToken?: string;
|
|
9
|
-
}): {
|
|
10
|
-
clusters: {
|
|
11
|
-
height: number;
|
|
12
|
-
indexes: number[];
|
|
13
|
-
} | undefined;
|
|
14
|
-
distances: number[][];
|
|
15
|
-
order: number[];
|
|
16
|
-
clustersGivenK: number[][][];
|
|
17
|
-
};
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.euclideanDistance = euclideanDistance;
|
|
4
|
-
exports.averageDistance = averageDistance;
|
|
5
|
-
exports.clusterData = clusterData;
|
|
6
|
-
const stopToken_1 = require("@jbrowse/core/util/stopToken");
|
|
7
|
-
function euclideanDistance(a, b) {
|
|
8
|
-
const size = Math.min(a.length, b.length);
|
|
9
|
-
let sum = 0;
|
|
10
|
-
for (let index = 0; index < size; index++) {
|
|
11
|
-
sum += (a[index] - b[index]) * (a[index] - b[index]);
|
|
12
|
-
}
|
|
13
|
-
return Math.sqrt(sum);
|
|
14
|
-
}
|
|
15
|
-
function averageDistance(setA, setB, distances) {
|
|
16
|
-
let distance = 0;
|
|
17
|
-
for (const a of setA) {
|
|
18
|
-
for (const b of setB) {
|
|
19
|
-
distance += distances[a][b];
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return distance / setA.length / setB.length;
|
|
23
|
-
}
|
|
24
|
-
function updateProgress(stepNumber, stepProgress, onProgress) {
|
|
25
|
-
onProgress(stepNumber / 2 + stepProgress / 2);
|
|
26
|
-
}
|
|
27
|
-
function clusterData({ data, distance = euclideanDistance, linkage = averageDistance, onProgress, stopToken, }) {
|
|
28
|
-
const distances = data.map((datum, index) => {
|
|
29
|
-
if (onProgress) {
|
|
30
|
-
updateProgress(0, index / (data.length - 1), onProgress);
|
|
31
|
-
}
|
|
32
|
-
return data.map(otherDatum => distance(datum, otherDatum));
|
|
33
|
-
});
|
|
34
|
-
const clusters = data.map((_datum, index) => ({
|
|
35
|
-
height: 0,
|
|
36
|
-
indexes: [Number(index)],
|
|
37
|
-
}));
|
|
38
|
-
let clustersGivenK = [];
|
|
39
|
-
let start = performance.now();
|
|
40
|
-
for (let iteration = 0; iteration < data.length; iteration++) {
|
|
41
|
-
if (performance.now() - start > 2000) {
|
|
42
|
-
(0, stopToken_1.checkStopToken)(stopToken);
|
|
43
|
-
start = performance.now();
|
|
44
|
-
}
|
|
45
|
-
if (onProgress) {
|
|
46
|
-
updateProgress(1, (iteration + 1) / data.length, onProgress);
|
|
47
|
-
}
|
|
48
|
-
clustersGivenK.push(clusters.map(cluster => cluster.indexes));
|
|
49
|
-
if (iteration >= data.length - 1) {
|
|
50
|
-
break;
|
|
51
|
-
}
|
|
52
|
-
let nearestDistance = Infinity;
|
|
53
|
-
let nearestRow = 0;
|
|
54
|
-
let nearestCol = 0;
|
|
55
|
-
for (let row = 0; row < clusters.length; row++) {
|
|
56
|
-
for (let col = row + 1; col < clusters.length; col++) {
|
|
57
|
-
const distance = linkage(clusters[row].indexes, clusters[col].indexes, distances);
|
|
58
|
-
if (distance < nearestDistance) {
|
|
59
|
-
nearestDistance = distance;
|
|
60
|
-
nearestRow = row;
|
|
61
|
-
nearestCol = col;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
const newCluster = {
|
|
66
|
-
indexes: [
|
|
67
|
-
...clusters[nearestRow].indexes,
|
|
68
|
-
...clusters[nearestCol].indexes,
|
|
69
|
-
],
|
|
70
|
-
height: nearestDistance,
|
|
71
|
-
children: [clusters[nearestRow], clusters[nearestCol]],
|
|
72
|
-
};
|
|
73
|
-
clusters.splice(Math.max(nearestRow, nearestCol), 1);
|
|
74
|
-
clusters.splice(Math.min(nearestRow, nearestCol), 1);
|
|
75
|
-
clusters.push(newCluster);
|
|
76
|
-
}
|
|
77
|
-
clustersGivenK = [[], ...clustersGivenK.reverse()];
|
|
78
|
-
return {
|
|
79
|
-
clusters: clusters[0],
|
|
80
|
-
distances: distances,
|
|
81
|
-
order: clusters[0].indexes,
|
|
82
|
-
clustersGivenK: clustersGivenK,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export declare function euclideanDistance(a: number[], b: number[]): number;
|
|
2
|
-
export declare function averageDistance(setA: number[], setB: number[], distances: number[][]): number;
|
|
3
|
-
export declare function clusterData({ data, distance, linkage, onProgress, stopToken, }: {
|
|
4
|
-
data: number[][];
|
|
5
|
-
distance?: (a: number[], b: number[]) => number;
|
|
6
|
-
linkage?: (a: number[], b: number[], distances: number[][]) => number;
|
|
7
|
-
onProgress?: (a: number) => void;
|
|
8
|
-
stopToken?: string;
|
|
9
|
-
}): {
|
|
10
|
-
clusters: {
|
|
11
|
-
height: number;
|
|
12
|
-
indexes: number[];
|
|
13
|
-
} | undefined;
|
|
14
|
-
distances: number[][];
|
|
15
|
-
order: number[];
|
|
16
|
-
clustersGivenK: number[][][];
|
|
17
|
-
};
|
package/esm/WiggleRPC/cluster.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { checkStopToken } from '@jbrowse/core/util/stopToken';
|
|
2
|
-
export function euclideanDistance(a, b) {
|
|
3
|
-
const size = Math.min(a.length, b.length);
|
|
4
|
-
let sum = 0;
|
|
5
|
-
for (let index = 0; index < size; index++) {
|
|
6
|
-
sum += (a[index] - b[index]) * (a[index] - b[index]);
|
|
7
|
-
}
|
|
8
|
-
return Math.sqrt(sum);
|
|
9
|
-
}
|
|
10
|
-
export function averageDistance(setA, setB, distances) {
|
|
11
|
-
let distance = 0;
|
|
12
|
-
for (const a of setA) {
|
|
13
|
-
for (const b of setB) {
|
|
14
|
-
distance += distances[a][b];
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return distance / setA.length / setB.length;
|
|
18
|
-
}
|
|
19
|
-
function updateProgress(stepNumber, stepProgress, onProgress) {
|
|
20
|
-
onProgress(stepNumber / 2 + stepProgress / 2);
|
|
21
|
-
}
|
|
22
|
-
export function clusterData({ data, distance = euclideanDistance, linkage = averageDistance, onProgress, stopToken, }) {
|
|
23
|
-
const distances = data.map((datum, index) => {
|
|
24
|
-
if (onProgress) {
|
|
25
|
-
updateProgress(0, index / (data.length - 1), onProgress);
|
|
26
|
-
}
|
|
27
|
-
return data.map(otherDatum => distance(datum, otherDatum));
|
|
28
|
-
});
|
|
29
|
-
const clusters = data.map((_datum, index) => ({
|
|
30
|
-
height: 0,
|
|
31
|
-
indexes: [Number(index)],
|
|
32
|
-
}));
|
|
33
|
-
let clustersGivenK = [];
|
|
34
|
-
let start = performance.now();
|
|
35
|
-
for (let iteration = 0; iteration < data.length; iteration++) {
|
|
36
|
-
if (performance.now() - start > 2000) {
|
|
37
|
-
checkStopToken(stopToken);
|
|
38
|
-
start = performance.now();
|
|
39
|
-
}
|
|
40
|
-
if (onProgress) {
|
|
41
|
-
updateProgress(1, (iteration + 1) / data.length, onProgress);
|
|
42
|
-
}
|
|
43
|
-
clustersGivenK.push(clusters.map(cluster => cluster.indexes));
|
|
44
|
-
if (iteration >= data.length - 1) {
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
let nearestDistance = Infinity;
|
|
48
|
-
let nearestRow = 0;
|
|
49
|
-
let nearestCol = 0;
|
|
50
|
-
for (let row = 0; row < clusters.length; row++) {
|
|
51
|
-
for (let col = row + 1; col < clusters.length; col++) {
|
|
52
|
-
const distance = linkage(clusters[row].indexes, clusters[col].indexes, distances);
|
|
53
|
-
if (distance < nearestDistance) {
|
|
54
|
-
nearestDistance = distance;
|
|
55
|
-
nearestRow = row;
|
|
56
|
-
nearestCol = col;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
const newCluster = {
|
|
61
|
-
indexes: [
|
|
62
|
-
...clusters[nearestRow].indexes,
|
|
63
|
-
...clusters[nearestCol].indexes,
|
|
64
|
-
],
|
|
65
|
-
height: nearestDistance,
|
|
66
|
-
children: [clusters[nearestRow], clusters[nearestCol]],
|
|
67
|
-
};
|
|
68
|
-
clusters.splice(Math.max(nearestRow, nearestCol), 1);
|
|
69
|
-
clusters.splice(Math.min(nearestRow, nearestCol), 1);
|
|
70
|
-
clusters.push(newCluster);
|
|
71
|
-
}
|
|
72
|
-
clustersGivenK = [[], ...clustersGivenK.reverse()];
|
|
73
|
-
return {
|
|
74
|
-
clusters: clusters[0],
|
|
75
|
-
distances: distances,
|
|
76
|
-
order: clusters[0].indexes,
|
|
77
|
-
clustersGivenK: clustersGivenK,
|
|
78
|
-
};
|
|
79
|
-
}
|
/package/dist/MultiLinearWiggleDisplay/components/{ClusterDialog → WiggleClusterDialog}/types.d.ts
RENAMED
|
File without changes
|
/package/dist/MultiLinearWiggleDisplay/components/{ClusterDialog → WiggleClusterDialog}/types.js
RENAMED
|
File without changes
|
/package/esm/MultiLinearWiggleDisplay/components/{ClusterDialog → WiggleClusterDialog}/types.d.ts
RENAMED
|
File without changes
|
/package/esm/MultiLinearWiggleDisplay/components/{ClusterDialog → WiggleClusterDialog}/types.js
RENAMED
|
File without changes
|