@jbrowse/plugin-wiggle
Version:
JBrowse 2 wiggle adapters, tracks, etc.
146 lines (145 loc) • 9.87 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const ui_1 = require("@jbrowse/core/ui");
const util_1 = require("@jbrowse/core/util");
const tracks_1 = require("@jbrowse/core/util/tracks");
const material_1 = require("@mui/material");
const copy_to_clipboard_1 = __importDefault(require("copy-to-clipboard"));
const file_saver_1 = require("file-saver");
const mobx_react_1 = require("mobx-react");
const mobx_state_tree_1 = require("mobx-state-tree");
const mui_1 = require("tss-react/mui");
const useStyles = (0, mui_1.makeStyles)()(theme => ({
textAreaFont: {
fontFamily: 'Courier New',
},
mgap: {
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(4),
},
}));
const WiggleClusterDialogManuals = (0, mobx_react_1.observer)(function ({ model, handleClose, children, }) {
const { classes } = useStyles();
const [paste, setPaste] = (0, react_1.useState)('');
const [ret, setRet] = (0, react_1.useState)();
const [error, setError] = (0, react_1.useState)();
const [loading, setLoading] = (0, react_1.useState)(false);
const [showAdvanced, setShowAdvanced] = (0, util_1.useLocalStorage)('cluster-showAdvanced', false);
const [clusterMethod, setClusterMethod] = (0, react_1.useState)('single');
const [samplesPerPixel, setSamplesPerPixel] = (0, react_1.useState)('1');
(0, react_1.useEffect)(() => {
;
(async () => {
try {
setError(undefined);
setRet(undefined);
setLoading(true);
const view = (0, util_1.getContainingView)(model);
const { dynamicBlocks, bpPerPx } = view;
const { rpcManager } = (0, util_1.getSession)(model);
const { sourcesWithoutLayout, adapterConfig } = model;
const sessionId = (0, tracks_1.getRpcSessionId)(model);
const ret = (await rpcManager.call(sessionId, 'MultiWiggleGetScoreMatrix', {
regions: dynamicBlocks.contentBlocks,
sources: sourcesWithoutLayout,
sessionId,
adapterConfig,
bpPerPx: bpPerPx / +samplesPerPixel,
}));
setRet(ret);
}
catch (e) {
if (!(0, util_1.isAbortException)(e) && (0, mobx_state_tree_1.isAlive)(model)) {
console.error(e);
setError(e);
}
}
finally {
setLoading(false);
}
})();
}, [model, samplesPerPixel]);
const results = ret
? `inputMatrix<-matrix(c(${Object.values(ret)
.map(val => val.join(','))
.join(',\n')}
),nrow=${Object.values(ret).length},byrow=TRUE)
rownames(inputMatrix)<-c(${Object.keys(ret)
.map(key => `'${key}'`)
.join(',')})
resultClusters<-hclust(dist(inputMatrix), method='${clusterMethod}')
cat(resultClusters$order,sep='\\n')`
: undefined;
const resultsTsv = ret
? Object.entries(ret)
.map(([key, val]) => [key, ...val].join('\t'))
.join('\n')
: undefined;
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: {
display: 'flex',
gap: '8px',
flexWrap: 'wrap',
marginBottom: '16px',
}, children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => {
(0, file_saver_1.saveAs)(new Blob([results || ''], {
type: 'text/plain;charset=utf-8',
}), 'cluster.R');
}, children: "Download Rscript" }), ' ', "or", ' ', (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => {
(0, copy_to_clipboard_1.default)(results || '');
}, children: "Copy Rscript to clipboard" }), ' ', "or", ' ', (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => {
(0, file_saver_1.saveAs)(new Blob([resultsTsv || ''], {
type: 'text/plain;charset=utf-8',
}), 'scores.tsv');
}, children: "Download TSV" })] }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => {
setShowAdvanced(!showAdvanced);
}, children: showAdvanced
? 'Hide advanced options'
: '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({
single: 'Single',
complete: 'Complete',
}).map(([key, val]) => ((0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(material_1.Radio, { checked: clusterMethod === key, onChange: () => {
setClusterMethod(key);
} }), 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 => {
setSamplesPerPixel(event.target.value);
} })] })] })) : 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 => {
setPaste(event.target.value);
}, slotProps: {
input: {
classes: {
input: classes.textAreaFont,
},
},
} })] })] })] }), (0, jsx_runtime_1.jsxs)(material_1.DialogActions, { children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: () => {
const { sourcesWithoutLayout } = model;
if (sourcesWithoutLayout) {
try {
model.setLayout(paste
.split('\n')
.map(t => t.trim())
.filter(f => !!f)
.map(r => +r)
.map(idx => {
const ret = sourcesWithoutLayout[idx - 1];
if (!ret) {
throw new Error(`out of bounds at ${idx}`);
}
return ret;
}));
}
catch (e) {
console.error(e);
(0, util_1.getSession)(model).notifyError(`${e}`, e);
}
}
handleClose();
}, children: "Apply clustering" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", color: "secondary", onClick: () => {
handleClose();
}, children: "Cancel" })] })] }));
});
exports.default = WiggleClusterDialogManuals;