@vitessce/statistical-plots 4.0.6 → 4.0.8
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/{deflate-C-0XOaix.js → deflate--aCxt3Uk.js} +1 -1
- package/dist/{index-CFje_HC1.js → index-BSDNU38l.js} +935 -127
- package/dist/index.js +2 -1
- package/dist/{jpeg-HJZeqbJ9.js → jpeg-KhuOxw4Z.js} +1 -1
- package/dist/{lerc-BtoOWLPL.js → lerc-CElkXFuI.js} +1 -1
- package/dist/{lzw-BS2ckxRa.js → lzw-CKBozwxj.js} +1 -1
- package/dist/{packbits-8sTofHBF.js → packbits-DBXx1JcY.js} +1 -1
- package/dist/{raw-DA0bjume.js → raw-Vb44MxD9.js} +1 -1
- package/dist/{webimage-C3yiEsf-.js → webimage-Df6sOKlo.js} +1 -1
- package/dist-tsc/CellSetCompositionBarPlot.d.ts.map +1 -1
- package/dist-tsc/CellSetCompositionBarPlot.js +87 -53
- package/dist-tsc/CellSetCompositionBarPlot.js.map +1 -1
- package/dist-tsc/SingleCellSetSelector.d.ts +2 -0
- package/dist-tsc/SingleCellSetSelector.d.ts.map +1 -0
- package/dist-tsc/SingleCellSetSelector.js +27 -0
- package/dist-tsc/SingleCellSetSelector.js.map +1 -0
- package/dist-tsc/SingleCellSetSelectorSubscriber.d.ts +2 -0
- package/dist-tsc/SingleCellSetSelectorSubscriber.d.ts.map +1 -0
- package/dist-tsc/SingleCellSetSelectorSubscriber.js +40 -0
- package/dist-tsc/SingleCellSetSelectorSubscriber.js.map +1 -0
- package/dist-tsc/VolcanoPlot.d.ts.map +1 -1
- package/dist-tsc/VolcanoPlot.js +6 -2
- package/dist-tsc/VolcanoPlot.js.map +1 -1
- package/dist-tsc/VolcanoPlotOptions.js +2 -2
- package/dist-tsc/VolcanoPlotOptions.js.map +1 -1
- package/dist-tsc/VolcanoPlotSubscriber.d.ts.map +1 -1
- package/dist-tsc/VolcanoPlotSubscriber.js +3 -1
- package/dist-tsc/VolcanoPlotSubscriber.js.map +1 -1
- package/dist-tsc/index.d.ts +1 -0
- package/dist-tsc/index.js +1 -0
- package/dist-tsc/index.js.map +1 -1
- package/package.json +8 -8
- package/src/CellSetCompositionBarPlot.js +102 -57
- package/src/SingleCellSetSelector.js +54 -0
- package/src/SingleCellSetSelectorSubscriber.js +124 -0
- package/src/VolcanoPlot.js +8 -2
- package/src/VolcanoPlotOptions.js +2 -2
- package/src/VolcanoPlotSubscriber.js +33 -21
- package/src/index.js +1 -0
|
@@ -88,6 +88,7 @@ export default function CellSetCompositionBarPlot(props) {
|
|
|
88
88
|
interceptExpectedSample: df.interceptExpectedSample[i],
|
|
89
89
|
effectExpectedSample: df.effectExpectedSample[i],
|
|
90
90
|
isCredibleEffect: df.isCredibleEffect[i],
|
|
91
|
+
significanceText: df.isCredibleEffect[i] ? ' ' : 'NS',
|
|
91
92
|
// Boolean flag for wasReferenceObsSet (check metadata)
|
|
92
93
|
isReferenceSet: (obsSetId === referenceCellType),
|
|
93
94
|
};
|
|
@@ -134,69 +135,107 @@ export default function CellSetCompositionBarPlot(props) {
|
|
|
134
135
|
return undefined;
|
|
135
136
|
}, [computedData]);
|
|
136
137
|
|
|
138
|
+
const nsTextAlign = useMemo(() => {
|
|
139
|
+
if (computedData) {
|
|
140
|
+
const firstNotSig = computedData.find(d => !d.isCredibleEffect);
|
|
141
|
+
return firstNotSig?.logFoldChange < 0 ? 'right' : 'left';
|
|
142
|
+
}
|
|
143
|
+
return 'center';
|
|
144
|
+
}, [computedData]);
|
|
145
|
+
|
|
146
|
+
const areAnySignificant = useMemo(() => computedData?.some(
|
|
147
|
+
d => d.isCredibleEffect,
|
|
148
|
+
), [computedData]);
|
|
149
|
+
|
|
137
150
|
const xScale = {
|
|
138
151
|
domain: xExtent,
|
|
139
152
|
};
|
|
140
153
|
|
|
141
154
|
const spec = {
|
|
142
|
-
|
|
143
|
-
params: [
|
|
155
|
+
layer: [
|
|
144
156
|
{
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
157
|
+
params: [
|
|
158
|
+
{
|
|
159
|
+
name: 'bar_select',
|
|
160
|
+
select: {
|
|
161
|
+
type: 'point',
|
|
162
|
+
on: 'click[event.shiftKey === false]',
|
|
163
|
+
fields: ['obsSetPath'],
|
|
164
|
+
empty: 'none',
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: 'shift_bar_select',
|
|
169
|
+
select: {
|
|
170
|
+
type: 'point',
|
|
171
|
+
on: 'click[event.shiftKey]',
|
|
172
|
+
fields: ['obsSetPath'],
|
|
173
|
+
empty: 'none',
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
mark: { type: 'bar', stroke: 'black', cursor: 'pointer' },
|
|
178
|
+
encoding: {
|
|
179
|
+
y: {
|
|
180
|
+
field: 'keyName',
|
|
181
|
+
type: 'nominal',
|
|
182
|
+
axis: { labelExpr: `substring(datum.label, ${keyLength})` },
|
|
183
|
+
title: `${captializedObsType} Set`,
|
|
184
|
+
sort: keys,
|
|
185
|
+
},
|
|
186
|
+
x: {
|
|
187
|
+
// TODO: support using intercept+effect here based on user-selected options?
|
|
188
|
+
field: 'logFoldChange',
|
|
189
|
+
type: 'quantitative',
|
|
190
|
+
title: 'Log fold-change',
|
|
191
|
+
scale: xScale,
|
|
192
|
+
},
|
|
193
|
+
color: {
|
|
194
|
+
field: 'key',
|
|
195
|
+
type: 'nominal',
|
|
196
|
+
scale: colorScale,
|
|
197
|
+
legend: null,
|
|
198
|
+
},
|
|
199
|
+
fillOpacity: {
|
|
200
|
+
field: 'isCredibleEffect',
|
|
201
|
+
type: 'nominal',
|
|
202
|
+
scale: opacityScale,
|
|
203
|
+
},
|
|
204
|
+
strokeWidth: {
|
|
205
|
+
field: 'isReferenceSet',
|
|
206
|
+
type: 'nominal',
|
|
207
|
+
scale: strokeWidthScale,
|
|
208
|
+
legend: null,
|
|
209
|
+
},
|
|
210
|
+
tooltip: {
|
|
211
|
+
field: 'effectExpectedSample',
|
|
212
|
+
type: 'quantitative',
|
|
213
|
+
},
|
|
151
214
|
},
|
|
152
215
|
},
|
|
153
216
|
{
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
217
|
+
mark: { type: 'text', align: nsTextAlign, dx: nsTextAlign === 'right' ? -5 : 5 },
|
|
218
|
+
encoding: {
|
|
219
|
+
y: {
|
|
220
|
+
field: 'keyName',
|
|
221
|
+
type: 'nominal',
|
|
222
|
+
axis: { labelExpr: `substring(datum.label, ${keyLength})` },
|
|
223
|
+
title: `${captializedObsType} Set`,
|
|
224
|
+
sort: keys,
|
|
225
|
+
},
|
|
226
|
+
x: {
|
|
227
|
+
field: 'logFoldChange',
|
|
228
|
+
type: 'quantitative',
|
|
229
|
+
title: 'Log fold-change',
|
|
230
|
+
scale: xScale,
|
|
231
|
+
},
|
|
232
|
+
text: {
|
|
233
|
+
field: 'significanceText',
|
|
234
|
+
},
|
|
160
235
|
},
|
|
161
236
|
},
|
|
162
237
|
],
|
|
163
|
-
|
|
164
|
-
y: {
|
|
165
|
-
field: 'keyName',
|
|
166
|
-
type: 'nominal',
|
|
167
|
-
axis: { labelExpr: `substring(datum.label, ${keyLength})` },
|
|
168
|
-
title: `${captializedObsType} Set`,
|
|
169
|
-
sort: keys,
|
|
170
|
-
},
|
|
171
|
-
x: {
|
|
172
|
-
// TODO: support using intercept+effect here based on user-selected options?
|
|
173
|
-
field: 'logFoldChange',
|
|
174
|
-
type: 'quantitative',
|
|
175
|
-
title: 'Log fold-change',
|
|
176
|
-
scale: xScale,
|
|
177
|
-
},
|
|
178
|
-
color: {
|
|
179
|
-
field: 'key',
|
|
180
|
-
type: 'nominal',
|
|
181
|
-
scale: colorScale,
|
|
182
|
-
legend: null,
|
|
183
|
-
},
|
|
184
|
-
fillOpacity: {
|
|
185
|
-
field: 'isCredibleEffect',
|
|
186
|
-
type: 'nominal',
|
|
187
|
-
scale: opacityScale,
|
|
188
|
-
},
|
|
189
|
-
strokeWidth: {
|
|
190
|
-
field: 'isReferenceSet',
|
|
191
|
-
type: 'nominal',
|
|
192
|
-
scale: strokeWidthScale,
|
|
193
|
-
legend: null,
|
|
194
|
-
},
|
|
195
|
-
tooltip: {
|
|
196
|
-
field: 'effectExpectedSample',
|
|
197
|
-
type: 'quantitative',
|
|
198
|
-
},
|
|
199
|
-
},
|
|
238
|
+
|
|
200
239
|
// TODO: for width, also subtract length of longest y-axis set name label.
|
|
201
240
|
width: clamp(width - marginRight, 10, Infinity),
|
|
202
241
|
height: clamp(height - marginBottom, 10, Infinity),
|
|
@@ -221,11 +260,17 @@ export default function CellSetCompositionBarPlot(props) {
|
|
|
221
260
|
), [captializedObsType]);
|
|
222
261
|
|
|
223
262
|
return (
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
263
|
+
<>
|
|
264
|
+
{areAnySignificant ? (
|
|
265
|
+
<VegaPlot
|
|
266
|
+
data={computedData}
|
|
267
|
+
spec={spec}
|
|
268
|
+
signalListeners={signalListeners}
|
|
269
|
+
getTooltipText={getTooltipText}
|
|
270
|
+
/>
|
|
271
|
+
) : (
|
|
272
|
+
<p>No results were significant for the selected conditions.</p>
|
|
273
|
+
)}
|
|
274
|
+
</>
|
|
230
275
|
);
|
|
231
276
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { Grid, NativeSelect } from '@vitessce/styles';
|
|
3
|
+
|
|
4
|
+
function pathToKey(pathArr) {
|
|
5
|
+
return pathArr.join('___');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function keyToPath(keyStr) {
|
|
9
|
+
return keyStr.split('___');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default function SingleCellSetSelector(props) {
|
|
13
|
+
const {
|
|
14
|
+
multiObsSetSelection,
|
|
15
|
+
singleObsSetSelection,
|
|
16
|
+
setSingleObsSetSelection,
|
|
17
|
+
} = props;
|
|
18
|
+
|
|
19
|
+
const handleChange = useCallback((event) => {
|
|
20
|
+
if (event.target.value === '__none__') {
|
|
21
|
+
setSingleObsSetSelection(null);
|
|
22
|
+
} else {
|
|
23
|
+
const nextPath = keyToPath(event.target.value);
|
|
24
|
+
setSingleObsSetSelection([
|
|
25
|
+
nextPath,
|
|
26
|
+
]);
|
|
27
|
+
}
|
|
28
|
+
}, []);
|
|
29
|
+
|
|
30
|
+
const hasMultiOptions = (
|
|
31
|
+
Array.isArray(multiObsSetSelection)
|
|
32
|
+
&& multiObsSetSelection.length > 0
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Grid container size={12}>
|
|
37
|
+
<NativeSelect
|
|
38
|
+
onChange={handleChange}
|
|
39
|
+
value={singleObsSetSelection ? pathToKey(singleObsSetSelection) : '__none__'}
|
|
40
|
+
variant="standard"
|
|
41
|
+
sx={{ width: '100%' }}
|
|
42
|
+
>
|
|
43
|
+
<option value="__none__">None</option>
|
|
44
|
+
{hasMultiOptions ? (
|
|
45
|
+
<>
|
|
46
|
+
{multiObsSetSelection.map(o => (
|
|
47
|
+
<option value={pathToKey(o)}>{o.at(-1)}</option>
|
|
48
|
+
))}
|
|
49
|
+
</>
|
|
50
|
+
) : null}
|
|
51
|
+
</NativeSelect>
|
|
52
|
+
</Grid>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
import React, { useEffect } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
TitleInfo,
|
|
5
|
+
useCoordination,
|
|
6
|
+
useLoaders,
|
|
7
|
+
useReady,
|
|
8
|
+
useFeatureStatsData,
|
|
9
|
+
useMatchingLoader,
|
|
10
|
+
useColumnNameMapping,
|
|
11
|
+
useCoordinationScopes,
|
|
12
|
+
useMultiCoordinationScopes,
|
|
13
|
+
} from '@vitessce/vit-s';
|
|
14
|
+
import {
|
|
15
|
+
ViewType,
|
|
16
|
+
COMPONENT_COORDINATION_TYPES,
|
|
17
|
+
ViewHelpMapping,
|
|
18
|
+
DataType,
|
|
19
|
+
CoordinationType,
|
|
20
|
+
} from '@vitessce/constants-internal';
|
|
21
|
+
import { isEqual } from 'lodash-es';
|
|
22
|
+
import SingleCellSetSelector from './SingleCellSetSelector.js';
|
|
23
|
+
|
|
24
|
+
export function SingleCellSetSelectorSubscriber(props) {
|
|
25
|
+
const {
|
|
26
|
+
title = 'Cell Type of Interest',
|
|
27
|
+
coordinationScopes: coordinationScopesRaw,
|
|
28
|
+
removeGridComponent,
|
|
29
|
+
theme,
|
|
30
|
+
helpText = ViewHelpMapping.SINGLE_OBS_SET_SELECTOR,
|
|
31
|
+
} = props;
|
|
32
|
+
|
|
33
|
+
const loaders = useLoaders();
|
|
34
|
+
const coordinationScopes = useCoordinationScopes(coordinationScopesRaw);
|
|
35
|
+
|
|
36
|
+
// Get "props" from the coordination space.
|
|
37
|
+
const [{
|
|
38
|
+
obsType,
|
|
39
|
+
obsSetColor,
|
|
40
|
+
}, {
|
|
41
|
+
setObsType,
|
|
42
|
+
setObsSetColor,
|
|
43
|
+
}] = useCoordination(
|
|
44
|
+
COMPONENT_COORDINATION_TYPES[ViewType.SINGLE_OBS_SET_SELECTOR],
|
|
45
|
+
coordinationScopes,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
const obsSetSelectionScopes = useMultiCoordinationScopes(
|
|
50
|
+
CoordinationType.OBS_SET_SELECTION,
|
|
51
|
+
coordinationScopes,
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const [{
|
|
55
|
+
obsSetSelection: multiObsSetSelection,
|
|
56
|
+
}, {
|
|
57
|
+
setObsSetSelection: setMultiObsSetSelection,
|
|
58
|
+
}] = useCoordination(
|
|
59
|
+
COMPONENT_COORDINATION_TYPES[ViewType.SINGLE_OBS_SET_SELECTOR],
|
|
60
|
+
{ obsSetSelection: obsSetSelectionScopes?.[0] },
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const [{
|
|
64
|
+
obsSetSelection: singleObsSetSelectionArr,
|
|
65
|
+
}, {
|
|
66
|
+
setObsSetSelection: setSingleObsSetSelection,
|
|
67
|
+
}] = useCoordination(
|
|
68
|
+
COMPONENT_COORDINATION_TYPES[ViewType.SINGLE_OBS_SET_SELECTOR],
|
|
69
|
+
{ obsSetSelection: obsSetSelectionScopes?.[1] },
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const singleObsSetSelection = singleObsSetSelectionArr?.[0];
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
// If multiObsSetSelection changes, there are multiple things that can occur:
|
|
77
|
+
// - length is one and does not match the current singleObsSetSelection
|
|
78
|
+
// -> we update singleObsSetSelection.
|
|
79
|
+
// - length is zero or does not contain the current singleObsSetSelection
|
|
80
|
+
// -> we set singleObsSetSelection to null or the first entry of the
|
|
81
|
+
// multiple selection array.
|
|
82
|
+
// - otherwise, do nothing.
|
|
83
|
+
|
|
84
|
+
if (!Array.isArray(multiObsSetSelection) || multiObsSetSelection.length === 0) {
|
|
85
|
+
setSingleObsSetSelection(null);
|
|
86
|
+
} else {
|
|
87
|
+
const multiContainsSingle = multiObsSetSelection.some(
|
|
88
|
+
setPath => isEqual(setPath, singleObsSetSelection),
|
|
89
|
+
);
|
|
90
|
+
if (!multiContainsSingle) {
|
|
91
|
+
setSingleObsSetSelection([multiObsSetSelection?.[0]]);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}, [multiObsSetSelection]);
|
|
95
|
+
|
|
96
|
+
const errors = [];
|
|
97
|
+
|
|
98
|
+
const isReady = useReady([]);
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<TitleInfo
|
|
102
|
+
title={title}
|
|
103
|
+
removeGridComponent={removeGridComponent}
|
|
104
|
+
theme={theme}
|
|
105
|
+
isReady={isReady}
|
|
106
|
+
helpText={helpText}
|
|
107
|
+
errors={errors}
|
|
108
|
+
withPadding={false}
|
|
109
|
+
>
|
|
110
|
+
{Array.isArray(multiObsSetSelection) && multiObsSetSelection.length > 0 ? (
|
|
111
|
+
<SingleCellSetSelector
|
|
112
|
+
theme={theme}
|
|
113
|
+
obsType={obsType}
|
|
114
|
+
obsSetColor={obsSetColor}
|
|
115
|
+
multiObsSetSelection={multiObsSetSelection}
|
|
116
|
+
singleObsSetSelection={singleObsSetSelection}
|
|
117
|
+
setSingleObsSetSelection={setSingleObsSetSelection}
|
|
118
|
+
/>
|
|
119
|
+
) : (
|
|
120
|
+
<p style={{ padding: '12px' }}>Select at least one {obsType} set.</p>
|
|
121
|
+
)}
|
|
122
|
+
</TitleInfo>
|
|
123
|
+
);
|
|
124
|
+
}
|
package/src/VolcanoPlot.js
CHANGED
|
@@ -58,7 +58,7 @@ export default function VolcanoPlot(props) {
|
|
|
58
58
|
return [null, null];
|
|
59
59
|
}
|
|
60
60
|
let xExtentResult = d3_extent(
|
|
61
|
-
computedData.flatMap(d => d3_extent(d.df.logFoldChange)),
|
|
61
|
+
computedData.flatMap(d => d3_extent(d.df.logFoldChange.filter(v => Number.isFinite(v)))),
|
|
62
62
|
);
|
|
63
63
|
const xAbsMax = Math.max(Math.abs(xExtentResult[0]), Math.abs(xExtentResult[1]));
|
|
64
64
|
xExtentResult = [-xAbsMax, xAbsMax];
|
|
@@ -207,7 +207,13 @@ export default function VolcanoPlot(props) {
|
|
|
207
207
|
filteredData.forEach((comparisonObject) => {
|
|
208
208
|
const obsSetG = g.append('g');
|
|
209
209
|
|
|
210
|
-
const { df:
|
|
210
|
+
const { df: rawFilteredDf, metadata } = comparisonObject;
|
|
211
|
+
// Points with a NaN logFoldChange or minusLog10p (e.g. missing/invalid p-value) cannot be
|
|
212
|
+
// positioned on the y-axis, even with clamping/jitter, so drop them here.
|
|
213
|
+
// Note that we still try to position points with -inf or inf values below, just not NaN.
|
|
214
|
+
const filteredDf = rawFilteredDf.filter(d => (
|
|
215
|
+
!Number.isNaN(d.minusLog10p) && !Number.isNaN(d.logFoldChange)
|
|
216
|
+
));
|
|
211
217
|
const coordinationValues = metadata.coordination_values;
|
|
212
218
|
|
|
213
219
|
const rawObsSetPath = coordinationValues.obsSetFilter
|
|
@@ -64,7 +64,7 @@ export default function VolcanoPlotOptions(props) {
|
|
|
64
64
|
valueLabelDisplay="auto"
|
|
65
65
|
step={1}
|
|
66
66
|
min={0}
|
|
67
|
-
max={
|
|
67
|
+
max={50}
|
|
68
68
|
/>
|
|
69
69
|
</TableCell>
|
|
70
70
|
</TableRow>
|
|
@@ -89,7 +89,7 @@ export default function VolcanoPlotOptions(props) {
|
|
|
89
89
|
valueLabelDisplay="auto"
|
|
90
90
|
step={0.5}
|
|
91
91
|
min={0}
|
|
92
|
-
max={
|
|
92
|
+
max={10}
|
|
93
93
|
/>
|
|
94
94
|
</TableCell>
|
|
95
95
|
</TableRow>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* eslint-disable no-unused-vars */
|
|
2
|
+
/* eslint-disable no-nested-ternary */
|
|
2
3
|
import React, { useMemo, useCallback } from 'react';
|
|
3
4
|
import {
|
|
4
5
|
TitleInfo,
|
|
@@ -122,6 +123,10 @@ export function VolcanoPlotSubscriber(props) {
|
|
|
122
123
|
setFeatureSelection([featureId]);
|
|
123
124
|
}, [setFeatureSelection]);
|
|
124
125
|
|
|
126
|
+
const anyNonEmpty = useMemo(() => featureStats?.some(
|
|
127
|
+
d => !d.metadata?.analysis_params?.is_empty,
|
|
128
|
+
), [featureStats]);
|
|
129
|
+
|
|
125
130
|
return (
|
|
126
131
|
<TitleInfo
|
|
127
132
|
title={title}
|
|
@@ -149,28 +154,35 @@ export function VolcanoPlotSubscriber(props) {
|
|
|
149
154
|
>
|
|
150
155
|
<div ref={containerRef} className={classes.vegaContainer}>
|
|
151
156
|
{featureStats ? (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
157
|
+
anyNonEmpty ? (
|
|
158
|
+
<VolcanoPlot
|
|
159
|
+
theme={theme}
|
|
160
|
+
width={width}
|
|
161
|
+
height={height}
|
|
162
|
+
obsType={obsType}
|
|
163
|
+
featureType={featureType}
|
|
164
|
+
obsSetsColumnNameMapping={obsSetsColumnNameMapping}
|
|
165
|
+
obsSetsColumnNameMappingReversed={obsSetsColumnNameMappingReversed}
|
|
166
|
+
sampleSetsColumnNameMapping={sampleSetsColumnNameMapping}
|
|
167
|
+
sampleSetsColumnNameMappingReversed={sampleSetsColumnNameMappingReversed}
|
|
168
|
+
sampleSetSelection={sampleSetSelection}
|
|
169
|
+
obsSetSelection={obsSetSelection}
|
|
170
|
+
obsSetColor={obsSetColor}
|
|
171
|
+
sampleSetColor={sampleSetColor}
|
|
172
|
+
data={featureStats}
|
|
173
|
+
onFeatureClick={onFeatureClick}
|
|
168
174
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
175
|
+
featurePointSignificanceThreshold={featurePointSignificanceThreshold}
|
|
176
|
+
featurePointFoldChangeThreshold={featurePointFoldChangeThreshold}
|
|
177
|
+
featureLabelSignificanceThreshold={featureLabelSignificanceThreshold}
|
|
178
|
+
featureLabelFoldChangeThreshold={featureLabelFoldChangeThreshold}
|
|
179
|
+
/>
|
|
180
|
+
) : (
|
|
181
|
+
<span>
|
|
182
|
+
Differential expression tests were not performed
|
|
183
|
+
for the currently selected groups due to insufficient data.
|
|
184
|
+
</span>
|
|
185
|
+
)
|
|
174
186
|
) : (
|
|
175
187
|
<span>Select at least one {obsType} set.</span>
|
|
176
188
|
)}
|
package/src/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { VolcanoPlotSubscriber } from './VolcanoPlotSubscriber.js';
|
|
|
8
8
|
export { CellSetCompositionBarPlotSubscriber } from './CellSetCompositionBarPlotSubscriber.js';
|
|
9
9
|
export { FeatureSetEnrichmentBarPlotSubscriber } from './FeatureSetEnrichmentBarPlotSubscriber.js';
|
|
10
10
|
export { FeatureStatsTableSubscriber } from './FeatureStatsTableSubscriber.js';
|
|
11
|
+
export { SingleCellSetSelectorSubscriber } from './SingleCellSetSelectorSubscriber.js';
|
|
11
12
|
export { default as CellSetSizesPlot } from './CellSetSizesPlot.js';
|
|
12
13
|
export { default as CellSetExpressionPlot } from './CellSetExpressionPlot.js';
|
|
13
14
|
export { default as ExpressionHistogram } from './ExpressionHistogram.js';
|