@jbrowse/plugin-wiggle 3.2.0 → 3.4.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.d.ts +0 -1
- package/dist/BigWigAdapter/BigWigAdapter.js +0 -1
- package/dist/LinearWiggleDisplay/model.d.ts +1 -1
- 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/YScaleBars.js +2 -2
- package/dist/MultiLinearWiggleDisplay/components/util.d.ts +3 -2
- package/dist/MultiLinearWiggleDisplay/model.d.ts +3 -1
- package/dist/MultiLinearWiggleDisplay/model.js +14 -2
- package/dist/MultiWiggleAdapter/MultiWiggleAdapter.d.ts +0 -1
- package/dist/MultiWiggleAdapter/MultiWiggleAdapter.js +0 -1
- package/dist/WiggleBaseRenderer.d.ts +4 -4
- package/dist/WiggleBaseRenderer.js +1 -1
- package/dist/WiggleRPC/MultiWiggleClusterScoreMatrix.js +2 -5
- package/dist/drawDensity.js +12 -4
- package/dist/drawLine.js +4 -2
- package/dist/drawXY.js +7 -3
- package/dist/shared/SharedWiggleMixin.d.ts +1 -1
- package/esm/BigWigAdapter/BigWigAdapter.d.ts +0 -1
- package/esm/BigWigAdapter/BigWigAdapter.js +0 -1
- package/esm/LinearWiggleDisplay/model.d.ts +1 -1
- 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/YScaleBars.js +2 -2
- package/esm/MultiLinearWiggleDisplay/components/util.d.ts +3 -2
- package/esm/MultiLinearWiggleDisplay/model.d.ts +3 -1
- package/esm/MultiLinearWiggleDisplay/model.js +14 -2
- package/esm/MultiWiggleAdapter/MultiWiggleAdapter.d.ts +0 -1
- package/esm/MultiWiggleAdapter/MultiWiggleAdapter.js +0 -1
- package/esm/WiggleBaseRenderer.d.ts +4 -4
- package/esm/WiggleBaseRenderer.js +1 -1
- package/esm/WiggleRPC/MultiWiggleClusterScoreMatrix.js +2 -5
- package/esm/drawDensity.js +12 -4
- package/esm/drawLine.js +4 -2
- package/esm/drawXY.js +7 -3
- package/esm/shared/SharedWiggleMixin.d.ts +1 -1
- package/package.json +10 -10
- 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
|
@@ -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;
|
|
@@ -16,7 +16,7 @@ const Wrapper = observer(function ({ children, model, exportSVG, }) {
|
|
|
16
16
|
});
|
|
17
17
|
export const YScaleBars = observer(function (props) {
|
|
18
18
|
const { model, orientation, exportSVG } = props;
|
|
19
|
-
const { stats, needsFullHeightScalebar, sources } = model;
|
|
20
|
-
return stats && sources ? (_jsx(Wrapper, { ...props, children: needsFullHeightScalebar ? (_jsx(FullHeightScaleBar, { model: model, orientation: orientation, exportSVG: exportSVG })) : (_jsx(IndividualScaleBars, { model: model, orientation: orientation, exportSVG: exportSVG })) })) : null;
|
|
19
|
+
const { showSidebar, stats, needsFullHeightScalebar, sources } = model;
|
|
20
|
+
return stats && sources ? (_jsx(Wrapper, { ...props, children: showSidebar ? (needsFullHeightScalebar ? (_jsx(FullHeightScaleBar, { model: model, orientation: orientation, exportSVG: exportSVG })) : (_jsx(IndividualScaleBars, { model: model, orientation: orientation, exportSVG: exportSVG }))) : null })) : null;
|
|
21
21
|
});
|
|
22
22
|
export default YScaleBars;
|
|
@@ -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;
|
|
@@ -101,6 +101,7 @@ export declare function stateModelFactory(_pluginManager: PluginManager, configS
|
|
|
101
101
|
} & {
|
|
102
102
|
type: import("mobx-state-tree").ISimpleType<"MultiLinearWiggleDisplay">;
|
|
103
103
|
layout: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IType<Source[], Source[], Source[]>, [undefined]>;
|
|
104
|
+
showSidebar: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
104
105
|
}, {
|
|
105
106
|
rendererTypeName: string;
|
|
106
107
|
error: unknown;
|
|
@@ -213,7 +214,7 @@ export declare function stateModelFactory(_pluginManager: PluginManager, configS
|
|
|
213
214
|
} & {
|
|
214
215
|
addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
|
|
215
216
|
deleteBlock(key: string): void;
|
|
216
|
-
selectFeature(feature: Feature): void
|
|
217
|
+
selectFeature(feature: Feature): Promise<void>;
|
|
217
218
|
navToFeature(feature: Feature): void;
|
|
218
219
|
clearFeatureSelection(): void;
|
|
219
220
|
setFeatureIdUnderMouse(feature?: string): void;
|
|
@@ -327,6 +328,7 @@ export declare function stateModelFactory(_pluginManager: PluginManager, configS
|
|
|
327
328
|
featureUnderMouseVolatile: Feature | undefined;
|
|
328
329
|
sourcesVolatile: Source[] | undefined;
|
|
329
330
|
} & {
|
|
331
|
+
setShowSidebar(arg: boolean): void;
|
|
330
332
|
setSourcesLoading(str: string): void;
|
|
331
333
|
setLayout(layout: Source[]): void;
|
|
332
334
|
clearLayout(): void;
|
|
@@ -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'],
|
|
@@ -24,6 +24,7 @@ export function stateModelFactory(_pluginManager, configSchema) {
|
|
|
24
24
|
.compose('MultiLinearWiggleDisplay', SharedWiggleMixin(configSchema), types.model({
|
|
25
25
|
type: types.literal('MultiLinearWiggleDisplay'),
|
|
26
26
|
layout: types.optional(types.frozen(), []),
|
|
27
|
+
showSidebar: true,
|
|
27
28
|
}))
|
|
28
29
|
.volatile(() => ({
|
|
29
30
|
sourcesLoadingStopToken: undefined,
|
|
@@ -31,6 +32,9 @@ export function stateModelFactory(_pluginManager, configSchema) {
|
|
|
31
32
|
sourcesVolatile: undefined,
|
|
32
33
|
}))
|
|
33
34
|
.actions(self => ({
|
|
35
|
+
setShowSidebar(arg) {
|
|
36
|
+
self.showSidebar = arg;
|
|
37
|
+
},
|
|
34
38
|
setSourcesLoading(str) {
|
|
35
39
|
if (self.sourcesLoadingStopToken) {
|
|
36
40
|
stopStopToken(self.sourcesLoadingStopToken);
|
|
@@ -306,7 +310,7 @@ export function stateModelFactory(_pluginManager, configSchema) {
|
|
|
306
310
|
label: 'Cluster by score',
|
|
307
311
|
onClick: () => {
|
|
308
312
|
getSession(self).queueDialog(handleClose => [
|
|
309
|
-
|
|
313
|
+
WiggleClusterDialog,
|
|
310
314
|
{
|
|
311
315
|
model: self,
|
|
312
316
|
handleClose,
|
|
@@ -314,6 +318,14 @@ export function stateModelFactory(_pluginManager, configSchema) {
|
|
|
314
318
|
]);
|
|
315
319
|
},
|
|
316
320
|
},
|
|
321
|
+
{
|
|
322
|
+
label: 'Show sidebar',
|
|
323
|
+
type: 'checkbox',
|
|
324
|
+
checked: self.showSidebar,
|
|
325
|
+
onClick: () => {
|
|
326
|
+
self.setShowSidebar(!self.showSidebar);
|
|
327
|
+
},
|
|
328
|
+
},
|
|
317
329
|
{
|
|
318
330
|
label: 'Edit colors/arrangement...',
|
|
319
331
|
onClick: () => {
|
|
@@ -33,7 +33,7 @@ export default abstract class WiggleBaseRenderer extends FeatureRendererType {
|
|
|
33
33
|
height: number;
|
|
34
34
|
width: number;
|
|
35
35
|
containsNoTransferables: boolean;
|
|
36
|
-
canvasRecordedData:
|
|
36
|
+
canvasRecordedData: Record<string, unknown>;
|
|
37
37
|
reactElement?: React.ReactElement;
|
|
38
38
|
html?: string;
|
|
39
39
|
} | {
|
|
@@ -41,15 +41,15 @@ export default abstract class WiggleBaseRenderer extends FeatureRendererType {
|
|
|
41
41
|
height: number;
|
|
42
42
|
width: number;
|
|
43
43
|
containsNoTransferables: boolean;
|
|
44
|
-
|
|
44
|
+
imageData: any;
|
|
45
|
+
reactElement?: React.ReactElement;
|
|
45
46
|
html?: string;
|
|
46
47
|
} | {
|
|
47
48
|
features: Map<string, Feature>;
|
|
48
49
|
height: number;
|
|
49
50
|
width: number;
|
|
50
51
|
containsNoTransferables: boolean;
|
|
51
|
-
|
|
52
|
-
reactElement?: React.ReactElement;
|
|
52
|
+
reactElement: React.ReactElement;
|
|
53
53
|
html?: string;
|
|
54
54
|
}>;
|
|
55
55
|
abstract draw<T extends RenderArgsDeserializedWithFeatures>(ctx: CanvasRenderingContext2D, props: T): Promise<Record<string, unknown> | undefined>;
|
|
@@ -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/esm/drawDensity.js
CHANGED
|
@@ -36,15 +36,21 @@ export function drawDensity(ctx, props) {
|
|
|
36
36
|
start = performance.now();
|
|
37
37
|
}
|
|
38
38
|
const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
|
|
39
|
-
if (Math.floor(leftPx) !== Math.floor(prevLeftPx)) {
|
|
39
|
+
if (Math.floor(leftPx) !== Math.floor(prevLeftPx) || rightPx - leftPx > 1) {
|
|
40
40
|
reducedFeatures.push(feature);
|
|
41
41
|
prevLeftPx = leftPx;
|
|
42
42
|
}
|
|
43
43
|
const score = feature.get('score');
|
|
44
44
|
hasClipping = hasClipping || score > niceMax || score < niceMin;
|
|
45
45
|
const w = rightPx - leftPx + fudgeFactor;
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
if (score >= scaleOpts.domain[0]) {
|
|
47
|
+
ctx.fillStyle = cb(feature, score);
|
|
48
|
+
ctx.fillRect(leftPx, 0, w, height);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
ctx.fillStyle = '#eee';
|
|
52
|
+
ctx.fillRect(leftPx, 0, w, height);
|
|
53
|
+
}
|
|
48
54
|
}
|
|
49
55
|
ctx.save();
|
|
50
56
|
if (hasClipping) {
|
|
@@ -66,5 +72,7 @@ export function drawDensity(ctx, props) {
|
|
|
66
72
|
}
|
|
67
73
|
}
|
|
68
74
|
ctx.restore();
|
|
69
|
-
return {
|
|
75
|
+
return {
|
|
76
|
+
reducedFeatures,
|
|
77
|
+
};
|
|
70
78
|
}
|
package/esm/drawLine.js
CHANGED
|
@@ -25,7 +25,7 @@ export function drawLine(ctx, props) {
|
|
|
25
25
|
start = performance.now();
|
|
26
26
|
}
|
|
27
27
|
const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
|
|
28
|
-
if (Math.floor(leftPx) !== Math.floor(prevLeftPx)) {
|
|
28
|
+
if (Math.floor(leftPx) !== Math.floor(prevLeftPx) || rightPx - leftPx > 1) {
|
|
29
29
|
reducedFeatures.push(feature);
|
|
30
30
|
prevLeftPx = leftPx;
|
|
31
31
|
}
|
|
@@ -68,5 +68,7 @@ export function drawLine(ctx, props) {
|
|
|
68
68
|
ctx.stroke();
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
return {
|
|
71
|
+
return {
|
|
72
|
+
reducedFeatures,
|
|
73
|
+
};
|
|
72
74
|
}
|
package/esm/drawXY.js
CHANGED
|
@@ -89,7 +89,8 @@ export function drawXY(ctx, props) {
|
|
|
89
89
|
.toString())
|
|
90
90
|
: c;
|
|
91
91
|
const w = Math.max(rightPx - leftPx + fudgeFactor, minSize);
|
|
92
|
-
if (Math.floor(leftPx) !== Math.floor(prevLeftPx)
|
|
92
|
+
if (Math.floor(leftPx) !== Math.floor(prevLeftPx) ||
|
|
93
|
+
rightPx - leftPx > 1) {
|
|
93
94
|
reducedFeatures.push(feature);
|
|
94
95
|
prevLeftPx = leftPx;
|
|
95
96
|
}
|
|
@@ -128,7 +129,8 @@ export function drawXY(ctx, props) {
|
|
|
128
129
|
start = performance.now();
|
|
129
130
|
}
|
|
130
131
|
const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
|
|
131
|
-
if (Math.floor(leftPx) !== Math.floor(prevLeftPx)
|
|
132
|
+
if (Math.floor(leftPx) !== Math.floor(prevLeftPx) ||
|
|
133
|
+
rightPx - leftPx > 1) {
|
|
132
134
|
reducedFeatures.push(feature);
|
|
133
135
|
prevLeftPx = leftPx;
|
|
134
136
|
}
|
|
@@ -180,5 +182,7 @@ export function drawXY(ctx, props) {
|
|
|
180
182
|
ctx.stroke();
|
|
181
183
|
}
|
|
182
184
|
}
|
|
183
|
-
return {
|
|
185
|
+
return {
|
|
186
|
+
reducedFeatures,
|
|
187
|
+
};
|
|
184
188
|
}
|
|
@@ -206,7 +206,7 @@ export default function SharedWiggleMixin(configSchema: AnyConfigurationSchemaTy
|
|
|
206
206
|
} & {
|
|
207
207
|
addBlock(key: string, block: import("@jbrowse/core/util/blockTypes").BaseBlock): void;
|
|
208
208
|
deleteBlock(key: string): void;
|
|
209
|
-
selectFeature(feature: Feature): void
|
|
209
|
+
selectFeature(feature: Feature): Promise<void>;
|
|
210
210
|
navToFeature(feature: Feature): void;
|
|
211
211
|
clearFeatureSelection(): void;
|
|
212
212
|
setFeatureIdUnderMouse(feature?: string): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-wiggle",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "JBrowse 2 wiggle adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
"clean": "rimraf dist esm *.tsbuildinfo"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@gmod/bbi": "^
|
|
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": "^
|
|
39
|
+
"@gmod/bbi": "^7.0.0",
|
|
40
|
+
"@jbrowse/core": "^3.4.0",
|
|
41
|
+
"@jbrowse/plugin-data-management": "^3.4.0",
|
|
42
|
+
"@jbrowse/plugin-linear-genome-view": "^3.4.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": "a9f1ac35fc2dd810bae92cdaf1fc19995bee4413"
|
|
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
|
-
}
|