@vitessce/statistical-plots 3.5.9 → 3.5.11
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-19841f78.js → deflate-b8c6daae.js} +1 -1
- package/dist/{index-dc733355.js → index-134a71c6.js} +33739 -15506
- package/dist/index.js +6 -5
- package/dist/{jpeg-a83077be.js → jpeg-1b818d11.js} +1 -1
- package/dist/{lerc-1edd075a.js → lerc-f38cbdfc.js} +1 -1
- package/dist/{lzw-9572eac3.js → lzw-1120aba9.js} +1 -1
- package/dist/{packbits-cce11fbc.js → packbits-2d02b5e3.js} +1 -1
- package/dist/{raw-f7587aff.js → raw-0887baec.js} +1 -1
- package/dist/{webimage-8d38cd8b.js → webimage-533922a5.js} +1 -1
- package/dist-tsc/CellSetCompositionBarPlot.d.ts.map +1 -1
- package/dist-tsc/CellSetCompositionBarPlot.js +31 -10
- package/dist-tsc/CellSetCompositionBarPlotSubscriber.js +1 -1
- package/dist-tsc/CellSetExpressionPlot.d.ts.map +1 -1
- package/dist-tsc/CellSetExpressionPlot.js +26 -10
- package/dist-tsc/CellSetExpressionPlotOptions.d.ts.map +1 -1
- package/dist-tsc/CellSetExpressionPlotOptions.js +11 -4
- package/dist-tsc/CellSetExpressionPlotSubscriber.d.ts.map +1 -1
- package/dist-tsc/CellSetExpressionPlotSubscriber.js +46 -11
- package/dist-tsc/DotPlot.d.ts.map +1 -1
- package/dist-tsc/DotPlot.js +59 -6
- package/dist-tsc/DotPlotSubscriber.d.ts.map +1 -1
- package/dist-tsc/DotPlotSubscriber.js +1 -1
- package/dist-tsc/FeatureSetEnrichmentBarPlot.d.ts.map +1 -1
- package/dist-tsc/FeatureSetEnrichmentBarPlot.js +7 -6
- package/dist-tsc/FeatureSetEnrichmentBarPlotSubscriber.d.ts.map +1 -1
- package/dist-tsc/FeatureSetEnrichmentBarPlotSubscriber.js +5 -2
- package/dist-tsc/FeatureStatsTable.d.ts +2 -0
- package/dist-tsc/FeatureStatsTable.d.ts.map +1 -0
- package/dist-tsc/FeatureStatsTable.js +81 -0
- package/dist-tsc/FeatureStatsTableSubscriber.d.ts +2 -0
- package/dist-tsc/FeatureStatsTableSubscriber.d.ts.map +1 -0
- package/dist-tsc/FeatureStatsTableSubscriber.js +28 -0
- package/dist-tsc/Treemap.d.ts.map +1 -1
- package/dist-tsc/Treemap.js +17 -3
- package/dist-tsc/TreemapSubscriber.d.ts.map +1 -1
- package/dist-tsc/TreemapSubscriber.js +15 -9
- package/dist-tsc/VolcanoPlot.d.ts.map +1 -1
- package/dist-tsc/VolcanoPlot.js +15 -46
- package/dist-tsc/VolcanoPlotSubscriber.d.ts.map +1 -1
- package/dist-tsc/VolcanoPlotSubscriber.js +4 -2
- package/dist-tsc/expr-hooks.d.ts.map +1 -1
- package/dist-tsc/expr-hooks.test.js +2 -1
- package/dist-tsc/index.d.ts +1 -0
- package/dist-tsc/index.js +1 -0
- package/dist-tsc/utils.d.ts +1 -0
- package/dist-tsc/utils.d.ts.map +1 -1
- package/dist-tsc/utils.js +56 -0
- package/package.json +8 -7
- package/src/CellSetCompositionBarPlot.js +38 -12
- package/src/CellSetCompositionBarPlotSubscriber.js +1 -1
- package/src/CellSetExpressionPlot.js +33 -10
- package/src/CellSetExpressionPlotOptions.js +39 -2
- package/src/CellSetExpressionPlotSubscriber.js +56 -13
- package/src/DotPlot.js +81 -11
- package/src/DotPlotSubscriber.js +3 -1
- package/src/FeatureSetEnrichmentBarPlot.js +7 -6
- package/src/FeatureSetEnrichmentBarPlotSubscriber.js +5 -2
- package/src/FeatureStatsTable.js +116 -0
- package/src/FeatureStatsTableSubscriber.js +133 -0
- package/src/Treemap.js +21 -3
- package/src/TreemapSubscriber.js +26 -11
- package/src/VolcanoPlot.js +16 -64
- package/src/VolcanoPlotSubscriber.js +6 -1
- package/src/expr-hooks.js +0 -1
- package/src/expr-hooks.test.js +2 -1
- package/src/index.js +1 -0
- package/src/utils.js +82 -1
package/dist/index.js
CHANGED
@@ -1,19 +1,20 @@
|
|
1
|
-
import { b,
|
1
|
+
import { b, f, C, e, a, i, D, h, E, F, c, d, T, V } from "./index-134a71c6.js";
|
2
2
|
import "react";
|
3
3
|
import "@vitessce/vit-s";
|
4
4
|
import "react-dom";
|
5
5
|
export {
|
6
6
|
b as CellSetCompositionBarPlotSubscriber,
|
7
|
-
|
7
|
+
f as CellSetExpressionPlot,
|
8
8
|
C as CellSetExpressionPlotSubscriber,
|
9
|
-
|
9
|
+
e as CellSetSizesPlot,
|
10
10
|
a as CellSetSizesPlotSubscriber,
|
11
|
-
|
11
|
+
i as DotPlot,
|
12
12
|
D as DotPlotSubscriber,
|
13
|
-
|
13
|
+
h as ExpressionHistogram,
|
14
14
|
E as ExpressionHistogramSubscriber,
|
15
15
|
F as FeatureBarPlotSubscriber,
|
16
16
|
c as FeatureSetEnrichmentBarPlotSubscriber,
|
17
|
+
d as FeatureStatsTableSubscriber,
|
17
18
|
T as TreemapSubscriber,
|
18
19
|
V as VolcanoPlotSubscriber
|
19
20
|
};
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { i as inflate_1 } from "./pako.esm-68f84e2a.js";
|
2
|
-
import { g as getDefaultExportFromCjs, B as BaseDecoder } from "./index-
|
2
|
+
import { g as getDefaultExportFromCjs, B as BaseDecoder } from "./index-134a71c6.js";
|
3
3
|
import "react";
|
4
4
|
import "@vitessce/vit-s";
|
5
5
|
import "react-dom";
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"CellSetCompositionBarPlot.d.ts","sourceRoot":"","sources":["../src/CellSetCompositionBarPlot.js"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"CellSetCompositionBarPlot.d.ts","sourceRoot":"","sources":["../src/CellSetCompositionBarPlot.js"],"names":[],"mappings":"AAUA;;GAEG;AACH,2EAyNC"}
|
@@ -2,14 +2,20 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useMemo } from 'react';
|
3
3
|
import { clamp, isEqual } from 'lodash-es';
|
4
4
|
import { v4 as uuidv4 } from 'uuid';
|
5
|
+
import { extent } from 'd3-array';
|
5
6
|
import { VegaPlot, VEGA_THEMES } from '@vitessce/vega';
|
6
7
|
import { capitalize } from '@vitessce/utils';
|
7
8
|
import { getColorScale } from './utils.js';
|
9
|
+
const MAX_BAR_SIZE = 40;
|
8
10
|
/**
|
9
11
|
* Cell set composition results displayed using a bar chart.
|
10
12
|
*/
|
11
13
|
export default function CellSetCompositionBarPlot(props) {
|
12
|
-
const { data, theme, width, height, marginRight = 200, marginBottom =
|
14
|
+
const { data, theme, width, height: heightProp, marginRight = 200, marginBottom = 60, keyLength = 36, obsType, onBarSelect, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, } = props;
|
15
|
+
const height = (Array.isArray(obsSetSelection)
|
16
|
+
&& ((heightProp - marginBottom) / obsSetSelection.length >= MAX_BAR_SIZE))
|
17
|
+
? MAX_BAR_SIZE * obsSetSelection.length + marginBottom
|
18
|
+
: heightProp;
|
13
19
|
const [obsSetColorScale, sampleSetColorScale] = useMemo(() => [
|
14
20
|
getColorScale(obsSetSelection, obsSetColor, theme),
|
15
21
|
getColorScale(sampleSetSelection, sampleSetColor, theme),
|
@@ -20,18 +26,15 @@ export default function CellSetCompositionBarPlot(props) {
|
|
20
26
|
const { df, metadata } = data[0];
|
21
27
|
// Return in array-of-objects form that Vega-Lite likes.
|
22
28
|
const referenceCellType = metadata?.analysis_params?.reference_cell_type;
|
29
|
+
const covariateValue = metadata?.analysis_params?.covariate_value;
|
23
30
|
const coordinationValues = metadata?.coordination_values;
|
24
31
|
const obsSetColumnName = coordinationValues?.obsSetSelection?.[0]?.[0];
|
25
32
|
const obsSetGroupName = obsSetsColumnNameMappingReversed?.[obsSetColumnName];
|
26
33
|
const sampleSetColumnName = coordinationValues?.sampleSetFilter?.[0]?.[0];
|
27
34
|
const sampleSetGroupName = sampleSetsColumnNameMappingReversed?.[sampleSetColumnName];
|
28
|
-
|
29
|
-
// so that we would no longer need to load/check the covariate column in the frontend.
|
30
|
-
const covariatePrefix = `${sampleSetColumnName}T.`;
|
31
|
-
const firstCovariateValue = df.covariate?.[0]?.substring(covariatePrefix.length);
|
32
|
-
const firstCovariateSetPath = [sampleSetGroupName, firstCovariateValue];
|
35
|
+
const covariateSetPath = [sampleSetGroupName, covariateValue];
|
33
36
|
let shouldSwapFoldChangeDirection = false;
|
34
|
-
if (isEqual(
|
37
|
+
if (isEqual(covariateSetPath, sampleSetSelection[0])) {
|
35
38
|
shouldSwapFoldChangeDirection = true;
|
36
39
|
}
|
37
40
|
return df.obsSetId.map((obsSetId, i) => {
|
@@ -69,12 +72,12 @@ export default function CellSetCompositionBarPlot(props) {
|
|
69
72
|
obsSetColorScale, sampleSetColorScale,
|
70
73
|
]);
|
71
74
|
// Get an array of keys for sorting purposes.
|
72
|
-
const keys = computedData
|
75
|
+
const keys = computedData?.map(d => d.keyName);
|
73
76
|
const colorScale = {
|
74
77
|
// Manually set the color scale so that Vega-Lite does
|
75
78
|
// not choose the colors automatically.
|
76
|
-
domain: computedData
|
77
|
-
range: computedData
|
79
|
+
domain: computedData?.map(d => d.key),
|
80
|
+
range: computedData?.map(d => d.color),
|
78
81
|
};
|
79
82
|
const captializedObsType = capitalize(obsType);
|
80
83
|
const opacityScale = {
|
@@ -85,6 +88,22 @@ export default function CellSetCompositionBarPlot(props) {
|
|
85
88
|
domain: [true, false],
|
86
89
|
range: [2.0, 0.5],
|
87
90
|
};
|
91
|
+
const xExtent = useMemo(() => {
|
92
|
+
if (computedData) {
|
93
|
+
const [min, max] = extent(computedData.map(d => d.logFoldChange));
|
94
|
+
const buffer = 1.05; // Ensure some extra space
|
95
|
+
const minAbs = Math.abs(min) * buffer;
|
96
|
+
const maxAbs = Math.abs(max) * buffer;
|
97
|
+
if (minAbs > maxAbs) {
|
98
|
+
return [-minAbs, minAbs];
|
99
|
+
}
|
100
|
+
return [-maxAbs, maxAbs];
|
101
|
+
}
|
102
|
+
return undefined;
|
103
|
+
}, [computedData]);
|
104
|
+
const xScale = {
|
105
|
+
domain: xExtent,
|
106
|
+
};
|
88
107
|
const spec = {
|
89
108
|
mark: { type: 'bar', stroke: 'black', cursor: 'pointer' },
|
90
109
|
params: [
|
@@ -120,6 +139,7 @@ export default function CellSetCompositionBarPlot(props) {
|
|
120
139
|
field: 'logFoldChange',
|
121
140
|
type: 'quantitative',
|
122
141
|
title: 'Log fold-change',
|
142
|
+
scale: xScale,
|
123
143
|
},
|
124
144
|
color: {
|
125
145
|
field: 'key',
|
@@ -136,6 +156,7 @@ export default function CellSetCompositionBarPlot(props) {
|
|
136
156
|
field: 'isReferenceSet',
|
137
157
|
type: 'nominal',
|
138
158
|
scale: strokeWidthScale,
|
159
|
+
legend: null,
|
139
160
|
},
|
140
161
|
tooltip: {
|
141
162
|
field: 'effectExpectedSample',
|
@@ -36,5 +36,5 @@ export function CellSetCompositionBarPlotSubscriber(props) {
|
|
36
36
|
// TODO: support the following options
|
37
37
|
// - Use logFoldChange vs. intercept+effect for the bar y-value.
|
38
38
|
// - Boolean flag to allow hiding non-significant bars.
|
39
|
-
return (_jsx(TitleInfo, { title: `${capitalize(obsType)} Set Composition Analysis Plot`, removeGridComponent: removeGridComponent, theme: theme, isReady: isReady, helpText: helpText, children: _jsx("div", { ref: containerRef, className: classes.vegaContainer, children: obsSetStats ? (_jsx(CellSetCompositionBarPlot, { theme: theme, width: width, height: height, obsType: obsType, obsSetsColumnNameMapping: obsSetsColumnNameMapping, obsSetsColumnNameMappingReversed: obsSetsColumnNameMappingReversed, sampleSetsColumnNameMapping: sampleSetsColumnNameMapping, sampleSetsColumnNameMappingReversed: sampleSetsColumnNameMappingReversed, sampleSetSelection: sampleSetSelection, obsSetSelection: obsSetSelection, obsSetColor: obsSetColor, sampleSetColor: sampleSetColor, data: obsSetStats, onBarSelect: onBarSelect })) : (_jsxs("span", { children: ["Select at least one ", obsType, " set."] })) }) }));
|
39
|
+
return (_jsx(TitleInfo, { title: `${capitalize(obsType)} Set Composition Analysis Plot`, removeGridComponent: removeGridComponent, theme: theme, isReady: isReady, helpText: helpText, children: _jsx("div", { ref: containerRef, className: classes.vegaContainer, children: obsSetStats ? (_jsx(CellSetCompositionBarPlot, { theme: theme, width: width, height: height, obsType: obsType, obsSetsColumnNameMapping: obsSetsColumnNameMapping, obsSetsColumnNameMappingReversed: obsSetsColumnNameMappingReversed, sampleSetsColumnNameMapping: sampleSetsColumnNameMapping, sampleSetsColumnNameMappingReversed: sampleSetsColumnNameMappingReversed, sampleSetSelection: sampleSetSelection, obsSetSelection: obsSetSelection, obsSetColor: obsSetColor, sampleSetColor: sampleSetColor, data: obsSetStats, onBarSelect: onBarSelect })) : (_jsxs("span", { children: ["Select at least one ", obsType, " set and a pair of ", sampleType, " sets."] })) }) }));
|
40
40
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"CellSetExpressionPlot.d.ts","sourceRoot":"","sources":["../src/CellSetExpressionPlot.js"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"CellSetExpressionPlot.d.ts","sourceRoot":"","sources":["../src/CellSetExpressionPlot.js"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qDAjBG;IAAwB,IAAI,EAApB,MAAM,EAAE;IAEM,SAAS,EAAvB,MAAM;IACU,MAAM,EAAtB,MAAM,EAAE;IAEM,KAAK,EAAnB,MAAM;IACQ,KAAK,EAAnB,MAAM;IACQ,MAAM,EAApB,MAAM;IACQ,WAAW,EAAzB,MAAM;IAGQ,YAAY,EAA1B,MAAM;IAGa,yBAAyB,EAA5C,MAAM,GAAC,IAAI;CAErB,eAgZA"}
|
@@ -9,6 +9,7 @@ import { area as d3_area, curveBasis } from 'd3-shape';
|
|
9
9
|
import { select } from 'd3-selection';
|
10
10
|
import { colorArrayToString } from '@vitessce/sets-utils';
|
11
11
|
import { capitalize } from '@vitessce/utils';
|
12
|
+
import { getColorScale } from './utils.js';
|
12
13
|
const scaleBand = vega_scale('band');
|
13
14
|
/**
|
14
15
|
* Gene expression histogram displayed as a bar chart,
|
@@ -32,20 +33,21 @@ const scaleBand = vega_scale('band');
|
|
32
33
|
* for the feature value transformation function.
|
33
34
|
*/
|
34
35
|
export default function CellSetExpressionPlot(props) {
|
35
|
-
const { yMin: yMinProp, yUnits, jitter,
|
36
|
+
const { yMin: yMinProp, xAxisTitle = null, yUnits, jitter, obsSetSelection, obsSetColor, sampleSetSelection, sampleSetColor, colors, data, theme, width, height, marginTop = 5, marginRight = 5, marginLeft = 50, marginBottom, obsType, featureType, featureValueType, featureValueTransformName, } = props;
|
36
37
|
const svgRef = useRef();
|
38
|
+
const obsSetColorScale = useMemo(() => getColorScale(obsSetSelection, obsSetColor, theme), [obsSetSelection, obsSetColor, theme]);
|
37
39
|
// Get the max characters in an axis label for autsizing the bottom margin.
|
38
40
|
const maxCharactersForLabel = useMemo(() => {
|
39
|
-
if (!
|
41
|
+
if (!obsSetSelection) {
|
40
42
|
return 0;
|
41
43
|
}
|
42
|
-
const cellSetNames =
|
44
|
+
const cellSetNames = obsSetSelection.map(d => d.at(-1));
|
43
45
|
return cellSetNames.reduce((acc, name) => {
|
44
46
|
// eslint-disable-next-line no-param-reassign
|
45
47
|
acc = acc === undefined || name.length > acc ? name.length : acc;
|
46
48
|
return acc;
|
47
49
|
}, 0);
|
48
|
-
}, [
|
50
|
+
}, [obsSetSelection]);
|
49
51
|
const isStratified = (Array.isArray(sampleSetSelection) && sampleSetSelection.length === 2);
|
50
52
|
useEffect(() => {
|
51
53
|
const domElement = svgRef.current;
|
@@ -54,7 +56,7 @@ export default function CellSetExpressionPlot(props) {
|
|
54
56
|
: '';
|
55
57
|
const unitSuffix = yUnits ? ` (${yUnits})` : '';
|
56
58
|
const yTitle = `${transformPrefix}${capitalize(featureValueType)}${unitSuffix}`;
|
57
|
-
const xTitle = `${capitalize(obsType)} Set`;
|
59
|
+
const xTitle = xAxisTitle ?? `${capitalize(obsType)} Set`;
|
58
60
|
// Use a square-root term because the angle of the labels is 45 degrees (see below)
|
59
61
|
// so the perpendicular distance to the bottom of the labels is proportional to the
|
60
62
|
// square root of the length of the labels along the imaginary hypotenuse.
|
@@ -102,7 +104,7 @@ export default function CellSetExpressionPlot(props) {
|
|
102
104
|
const innerHeight = height - autoMarginBottom;
|
103
105
|
const xGroup = scaleBand()
|
104
106
|
.range([marginLeft, width - marginRight])
|
105
|
-
.domain(
|
107
|
+
.domain(obsSetSelection)
|
106
108
|
.padding(0.1);
|
107
109
|
// For the y domain, use the yMin prop
|
108
110
|
// to support a use case such as 'Aspect Ratio',
|
@@ -256,17 +258,30 @@ export default function CellSetExpressionPlot(props) {
|
|
256
258
|
.selectAll('text')
|
257
259
|
.style('font-size', '11px');
|
258
260
|
// X-axis ticks
|
259
|
-
g
|
261
|
+
const xTickG = g
|
260
262
|
.append('g')
|
261
263
|
.attr('transform', `translate(0,${innerHeight})`)
|
262
|
-
.style('font-size', '14px')
|
263
|
-
|
264
|
+
.style('font-size', '14px');
|
265
|
+
xTickG.call(axisBottom(xGroup).tickFormat(d => d.at(-1)))
|
264
266
|
.selectAll('text')
|
265
267
|
.style('font-size', '11px')
|
266
268
|
.attr('dx', '-6px')
|
267
269
|
.attr('dy', '6px')
|
268
270
|
.attr('transform', 'rotate(-45)')
|
269
271
|
.style('text-anchor', 'end');
|
272
|
+
if (isStratified) {
|
273
|
+
// Associate each X tick with a cell type color,
|
274
|
+
// since in the stratified case the violins are colored
|
275
|
+
// by sample set.
|
276
|
+
const tickWidth = xGroup.bandwidth();
|
277
|
+
xTickG.selectAll('.tick')
|
278
|
+
.append('rect')
|
279
|
+
.attr('x', -tickWidth / 2)
|
280
|
+
// .attr("y", -innerHeight)
|
281
|
+
.attr('width', tickWidth)
|
282
|
+
.attr('height', 4)
|
283
|
+
.style('fill', d => obsSetColorScale(d));
|
284
|
+
}
|
270
285
|
// Y-axis title
|
271
286
|
g
|
272
287
|
.append('text')
|
@@ -333,7 +348,8 @@ export default function CellSetExpressionPlot(props) {
|
|
333
348
|
}, [width, height, data, marginLeft, marginBottom, colors,
|
334
349
|
jitter, theme, yMinProp, marginTop, marginRight, featureType,
|
335
350
|
featureValueType, featureValueTransformName, yUnits, obsType,
|
336
|
-
maxCharactersForLabel, sampleSetSelection,
|
351
|
+
maxCharactersForLabel, sampleSetSelection, isStratified,
|
352
|
+
obsSetColorScale,
|
337
353
|
]);
|
338
354
|
return (_jsx("svg", { ref: svgRef, style: {
|
339
355
|
top: 0,
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"CellSetExpressionPlotOptions.d.ts","sourceRoot":"","sources":["../src/CellSetExpressionPlotOptions.js"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"CellSetExpressionPlotOptions.d.ts","sourceRoot":"","sources":["../src/CellSetExpressionPlotOptions.js"],"names":[],"mappings":"AAUA,8EAyKC"}
|
@@ -4,16 +4,21 @@ import { useId } from 'react-aria';
|
|
4
4
|
import { TableCell, TableRow, TextField, Slider } from '@material-ui/core';
|
5
5
|
import { usePlotOptionsStyles, OptionsContainer, OptionSelect } from '@vitessce/vit-s';
|
6
6
|
import { GLSL_COLORMAPS } from '@vitessce/gl';
|
7
|
+
import { capitalize } from '@vitessce/utils';
|
8
|
+
const FEATURE_AGGREGATION_STRATEGIES = ['first', 'last', 'sum', 'mean'];
|
7
9
|
export default function CellSetExpressionPlotOptions(props) {
|
8
|
-
const { featureValueTransform, setFeatureValueTransform, featureValueTransformCoefficient, setFeatureValueTransformCoefficient, transformOptions, featureValuePositivityThreshold, setFeatureValuePositivityThreshold, featureValueColormap, setFeatureValueColormap, } = props;
|
10
|
+
const { featureValueTransform, setFeatureValueTransform, featureValueTransformCoefficient, setFeatureValueTransformCoefficient, transformOptions, featureValuePositivityThreshold, setFeatureValuePositivityThreshold, featureValueColormap, setFeatureValueColormap, featureAggregationStrategy, setFeatureAggregationStrategy, } = props;
|
9
11
|
const cellSetExpressionPlotOptionsId = useId();
|
10
12
|
const classes = usePlotOptionsStyles();
|
11
13
|
function handleFeatureValueColormapChange(event) {
|
12
14
|
setFeatureValueColormap(event.target.value);
|
13
15
|
}
|
14
|
-
|
16
|
+
function handleTransformChange(event) {
|
15
17
|
setFeatureValueTransform(event.target.value === '' ? null : event.target.value);
|
16
|
-
}
|
18
|
+
}
|
19
|
+
function handleFeatureAggregationStrategyChange(event) {
|
20
|
+
setFeatureAggregationStrategy(event.target.value);
|
21
|
+
}
|
17
22
|
function handlePositivityThresholdChange(event, value) {
|
18
23
|
setFeatureValuePositivityThreshold(value);
|
19
24
|
}
|
@@ -38,5 +43,7 @@ export default function CellSetExpressionPlotOptions(props) {
|
|
38
43
|
id: `cellset-expression-transform-select-${cellSetExpressionPlotOptionsId}`,
|
39
44
|
}, children: transformOptions.map(opt => (_jsx("option", { value: opt.value === null ? '' : opt.value, children: opt.name }, opt.name))) }) })] }), _jsxs(TableRow, { children: [_jsx(TableCell, { className: classes.labelCell, variant: "head", scope: "row", children: _jsx("label", { htmlFor: `cellset-expression-transform-coeff-${cellSetExpressionPlotOptionsId}`, children: "Transform Coefficient" }) }), _jsx(TableCell, { className: classes.inputCell, variant: "body", children: _jsx(TextField, { label: "Transform Coefficient", type: "number", onChange: handleTransformCoefficientChange, value: featureValueTransformCoefficient, InputLabelProps: {
|
40
45
|
shrink: true,
|
41
|
-
}, id: `cellset-expression-transform-coeff-${cellSetExpressionPlotOptionsId}` }) })] }),
|
46
|
+
}, id: `cellset-expression-transform-coeff-${cellSetExpressionPlotOptionsId}` }) })] }), setFeatureAggregationStrategy ? (_jsxs(TableRow, { children: [_jsx(TableCell, { className: classes.labelCell, variant: "head", scope: "row", children: _jsx("label", { htmlFor: `feature-aggregation-strategy-${cellSetExpressionPlotOptionsId}`, children: "Feature Aggregation Strategy" }) }), _jsx(TableCell, { className: classes.inputCell, variant: "body", children: _jsx(OptionSelect, { className: classes.select, value: featureAggregationStrategy ?? 'first', onChange: handleFeatureAggregationStrategyChange, inputProps: {
|
47
|
+
id: `feature-aggregation-strategy-${cellSetExpressionPlotOptionsId}`,
|
48
|
+
}, children: FEATURE_AGGREGATION_STRATEGIES.map(opt => (_jsx("option", { value: opt, children: capitalize(opt) }, opt))) }) })] })) : null, setFeatureValuePositivityThreshold ? (_jsxs(TableRow, { children: [_jsx(TableCell, { className: classes.labelCell, children: "Positivity Threshold" }), _jsx(TableCell, { className: classes.inputCell, children: _jsx(Slider, { classes: { root: classes.slider, valueLabel: classes.sliderValueLabel }, value: featureValuePositivityThreshold, onChange: handlePositivityThresholdChange, "aria-labelledby": "pos-threshold-slider", valueLabelDisplay: "auto", step: 1.0, min: 0.0, max: 100.0 }) })] }, "transform-coefficient-option-row")) : null] }));
|
42
49
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"CellSetExpressionPlotSubscriber.d.ts","sourceRoot":"","sources":["../src/CellSetExpressionPlotSubscriber.js"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"CellSetExpressionPlotSubscriber.d.ts","sourceRoot":"","sources":["../src/CellSetExpressionPlotSubscriber.js"],"names":[],"mappings":"AA0HA;;;;;;;;;GASG;AACH,uDALG;IAAwB,mBAAmB;IACrB,kBAAkB,EAAhC,MAAM;IAEQ,KAAK,EAAnB,MAAM;CAChB,eAwLA"}
|
@@ -8,6 +8,31 @@ import CellSetExpressionPlotOptions from './CellSetExpressionPlotOptions.js';
|
|
8
8
|
import CellSetExpressionPlot from './CellSetExpressionPlot.js';
|
9
9
|
import { useStyles } from './styles.js';
|
10
10
|
import { summarizeStratifiedExpressionData, histogramStratifiedExpressionData, } from './expr-hooks.js';
|
11
|
+
const DEFAULT_FEATURE_AGGREGATION_STRATEGY = 'first';
|
12
|
+
function featureSummary(geneSelection, featureAggregationStrategy) {
|
13
|
+
if (featureAggregationStrategy === 'first') {
|
14
|
+
return geneSelection?.[0];
|
15
|
+
}
|
16
|
+
if (featureAggregationStrategy === 'last') {
|
17
|
+
return geneSelection?.at(-1);
|
18
|
+
}
|
19
|
+
if (typeof featureAggregationStrategy === 'number') {
|
20
|
+
const i = featureAggregationStrategy;
|
21
|
+
return geneSelection?.[i];
|
22
|
+
}
|
23
|
+
if (featureAggregationStrategy === 'sum') {
|
24
|
+
// TODO: make these .join()-ed labels more scalable,
|
25
|
+
// in particular, if more than 10 or so elements.
|
26
|
+
return geneSelection?.join(' + ');
|
27
|
+
}
|
28
|
+
if (featureAggregationStrategy === 'mean') {
|
29
|
+
return `Mean of ${geneSelection?.join(', ')}`;
|
30
|
+
}
|
31
|
+
if (featureAggregationStrategy === 'difference') {
|
32
|
+
return geneSelection?.join(' - ');
|
33
|
+
}
|
34
|
+
return '';
|
35
|
+
}
|
11
36
|
/**
|
12
37
|
* Get expression data for the cells
|
13
38
|
* in the selected cell sets.
|
@@ -27,14 +52,14 @@ import { summarizeStratifiedExpressionData, histogramStratifiedExpressionData, }
|
|
27
52
|
* @param {number} featureValueTransformCoefficient A coefficient
|
28
53
|
* to be used in the transform function.
|
29
54
|
*/
|
30
|
-
function useExpressionByCellSet(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, cellSets, additionalCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient, theme, yMinProp) {
|
55
|
+
function useExpressionByCellSet(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, cellSets, additionalCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient, theme, yMinProp, featureAggregationStrategy) {
|
31
56
|
const mergedCellSets = useMemo(() => mergeObsSets(cellSets, additionalCellSets), [cellSets, additionalCellSets]);
|
32
57
|
// From the expression matrix and the list of selected genes / cell sets,
|
33
58
|
// generate the array of data points for the plot.
|
34
59
|
const [expressionArr, expressionMax] = useMemo(() => {
|
35
60
|
const [stratifiedData, exprMax] = stratifyExpressionData(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, mergedCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient);
|
36
61
|
if (stratifiedData) {
|
37
|
-
const aggregateData = aggregateStratifiedExpressionData(stratifiedData, geneSelection);
|
62
|
+
const aggregateData = aggregateStratifiedExpressionData(stratifiedData, geneSelection, featureAggregationStrategy);
|
38
63
|
const summarizedData = summarizeStratifiedExpressionData(aggregateData, true);
|
39
64
|
const histogramData = histogramStratifiedExpressionData(summarizedData, 16, yMinProp);
|
40
65
|
return [histogramData, exprMax];
|
@@ -44,6 +69,7 @@ function useExpressionByCellSet(sampleEdges, sampleSets, sampleSetSelection, exp
|
|
44
69
|
mergedCellSets, cellSetSelection, cellSetColor,
|
45
70
|
featureValueTransform, featureValueTransformCoefficient,
|
46
71
|
yMinProp, sampleEdges, sampleSets, sampleSetSelection,
|
72
|
+
featureAggregationStrategy,
|
47
73
|
]);
|
48
74
|
// From the cell sets hierarchy and the list of selected cell sets,
|
49
75
|
// generate the array of set sizes data points for the bar plot.
|
@@ -63,11 +89,11 @@ function useExpressionByCellSet(sampleEdges, sampleSets, sampleSetSelection, exp
|
|
63
89
|
* @param {string} props.theme The name of the current Vitessce theme.
|
64
90
|
*/
|
65
91
|
export function CellSetExpressionPlotSubscriber(props) {
|
66
|
-
const { coordinationScopes, closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, jitter = false, yMin = null, yUnits = null, helpText = ViewHelpMapping.OBS_SET_FEATURE_VALUE_DISTRIBUTION, } = props;
|
92
|
+
const { coordinationScopes, closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, title, xAxisTitle, jitter = false, yMin = null, yUnits = null, helpText = ViewHelpMapping.OBS_SET_FEATURE_VALUE_DISTRIBUTION, } = props;
|
67
93
|
const classes = useStyles();
|
68
94
|
const loaders = useLoaders();
|
69
95
|
// Get "props" from the coordination space.
|
70
|
-
const [{ dataset, obsType, featureType, featureValueType, featureSelection: geneSelection, featureValueTransform, featureValueTransformCoefficient, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, additionalObsSets: additionalCellSets, sampleType, sampleSetSelection, sampleSetColor, }, { setFeatureValueTransform, setFeatureValueTransformCoefficient, setSampleSetColor, }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType.OBS_SET_FEATURE_VALUE_DISTRIBUTION], coordinationScopes);
|
96
|
+
const [{ dataset, obsType, featureType, featureValueType, featureSelection: geneSelection, featureValueTransform, featureValueTransformCoefficient, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, additionalObsSets: additionalCellSets, sampleType, sampleSetSelection, sampleSetColor, featureAggregationStrategy, }, { setFeatureValueTransform, setFeatureValueTransformCoefficient, setSampleSetColor, setFeatureAggregationStrategy, }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType.OBS_SET_FEATURE_VALUE_DISTRIBUTION], coordinationScopes);
|
71
97
|
const [width, height, containerRef] = useGridItemSize();
|
72
98
|
const transformOptions = VALUE_TRANSFORM_OPTIONS;
|
73
99
|
// Get data from loaders using the data hooks.
|
@@ -97,12 +123,21 @@ export function CellSetExpressionPlotSubscriber(props) {
|
|
97
123
|
sampleSetsUrls,
|
98
124
|
sampleEdgesUrls,
|
99
125
|
]);
|
100
|
-
const
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
126
|
+
const featureAggregationStrategyToUse = featureAggregationStrategy
|
127
|
+
?? DEFAULT_FEATURE_AGGREGATION_STRATEGY;
|
128
|
+
const [histogramData, setArr, exprMax] = useExpressionByCellSet(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, cellSets, additionalCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient, theme, yMin, featureAggregationStrategyToUse);
|
129
|
+
const featureSuffix = useMemo(() => {
|
130
|
+
const cleanedGeneSelection = geneSelection?.map(geneName => (featureLabelsMap?.get(geneName)
|
131
|
+
|| featureLabelsMap?.get(cleanFeatureId(geneName))
|
132
|
+
|| geneName));
|
133
|
+
if (Array.isArray(cleanedGeneSelection)) {
|
134
|
+
return featureSummary(cleanedGeneSelection, featureAggregationStrategyToUse);
|
135
|
+
}
|
136
|
+
return null;
|
137
|
+
}, [geneSelection, featureAggregationStrategyToUse]);
|
106
138
|
const selectedTransformName = transformOptions.find(o => o.value === featureValueTransform)?.name;
|
107
|
-
|
139
|
+
// Use empty string when firstGeneSelected is null
|
140
|
+
const titleSuffix = featureSuffix ? ` (${featureSuffix})` : '';
|
141
|
+
return (_jsx(TitleInfo, { title: title ? `${title}${titleSuffix}`
|
142
|
+
: `Expression by ${capitalize(obsType)} Set${titleSuffix}`, closeButtonVisible: closeButtonVisible, downloadButtonVisible: downloadButtonVisible, removeGridComponent: removeGridComponent, urls: urls, theme: theme, isReady: isReady, helpText: helpText, options: (_jsx(CellSetExpressionPlotOptions, { featureValueTransform: featureValueTransform, setFeatureValueTransform: setFeatureValueTransform, featureValueTransformCoefficient: featureValueTransformCoefficient, setFeatureValueTransformCoefficient: setFeatureValueTransformCoefficient, transformOptions: transformOptions, featureAggregationStrategy: featureAggregationStrategy, setFeatureAggregationStrategy: setFeatureAggregationStrategy })), children: _jsx("div", { ref: containerRef, className: classes.vegaContainer, children: histogramData ? (_jsx(CellSetExpressionPlot, { yMin: yMin, yUnits: yUnits, jitter: jitter, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, sampleSetSelection: sampleSetSelection, sampleSetColor: sampleSetColor, colors: setArr, data: histogramData, exprMax: exprMax, theme: theme, width: width, height: height, obsType: obsType, featureType: featureType, featureValueType: featureValueType, featureValueTransformName: selectedTransformName, xAxisTitle: xAxisTitle })) : (_jsxs("span", { children: ["Select a ", featureType, "."] })) }) }));
|
108
143
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"DotPlot.d.ts","sourceRoot":"","sources":["../src/DotPlot.js"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"DotPlot.d.ts","sourceRoot":"","sources":["../src/DotPlot.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;GAiBG;AACH,uCAdG;IAAwB,IAAI,EAApB,MAAM,EAAE;IAEM,KAAK,EAAnB,MAAM;IACQ,KAAK,EAAnB,MAAM;IACQ,MAAM,EAApB,MAAM;IACQ,WAAW,EAAzB,MAAM;IAGQ,YAAY,EAA1B,MAAM;IAGa,yBAAyB,EAA5C,MAAM,GAAC,IAAI;CAErB,eA4NA"}
|
package/dist-tsc/DotPlot.js
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import React from 'react';
|
2
|
+
import React, { useRef, useEffect, useCallback, useState, useMemo } from 'react';
|
3
3
|
import { clamp } from 'lodash-es';
|
4
4
|
import { VegaPlot, VEGA_THEMES } from '@vitessce/vega';
|
5
5
|
import { capitalize, pluralize as plur } from '@vitessce/utils';
|
6
|
+
import { select } from 'd3-selection';
|
7
|
+
import { getColorScale } from './utils.js';
|
6
8
|
/**
|
7
9
|
* Gene expression dot plot,
|
8
10
|
* implemented with the VegaPlot component.
|
@@ -22,7 +24,11 @@ import { capitalize, pluralize as plur } from '@vitessce/utils';
|
|
22
24
|
* for the feature value transformation function.
|
23
25
|
*/
|
24
26
|
export default function DotPlot(props) {
|
25
|
-
const { isStratified, transpose, data: rawData, theme, width, height, marginRight, marginBottom, obsType, keyLength = 36, featureType, featureValueType, featureValueTransformName,
|
27
|
+
const { isStratified, transpose, data: rawData, theme, width, height, marginRight, marginBottom, obsType, sampleType, keyLength = 36, featureType, featureValueType, featureValueTransformName,
|
28
|
+
// TODO: re-enable featureValueColormap coordination
|
29
|
+
// featureValueColormap,
|
30
|
+
obsSetSelection, obsSetColor, } = props;
|
31
|
+
const vegaContainerRef = useRef();
|
26
32
|
// Add a property `keyGroup` and `keyFeature` which concatenates the key and the name,
|
27
33
|
// which is both unique and can easily be converted
|
28
34
|
// back to the name by taking a substring.
|
@@ -59,11 +65,11 @@ export default function DotPlot(props) {
|
|
59
65
|
const autoMarginForSampleSet = marginRight
|
60
66
|
|| 30 + Math.sqrt(maxCharactersForSampleSet / 2) * 30;
|
61
67
|
const plotWidth = transpose
|
62
|
-
? clamp(width - autoMarginForFeature - 180, 10, Infinity) / (
|
68
|
+
? clamp(width - autoMarginForFeature - 180, 10, Infinity) / (obsSetSelection?.length || 1)
|
63
69
|
: clamp(width - autoMarginForGroup - autoMarginForSampleSet - 200, 10, Infinity);
|
64
70
|
const plotHeight = transpose
|
65
71
|
? clamp((height - autoMarginForGroup - autoMarginForSampleSet - 50), 10, Infinity)
|
66
|
-
: clamp((height - autoMarginForFeature - 80), 10, Infinity) / (
|
72
|
+
: clamp((height - autoMarginForFeature - 80), 10, Infinity) / (obsSetSelection?.length || 1);
|
67
73
|
// Get an array of keys for sorting purposes.
|
68
74
|
const groupKeys = data.map(d => d.keyGroup);
|
69
75
|
const featureKeys = data.map(d => d.keyFeature);
|
@@ -104,7 +110,8 @@ export default function DotPlot(props) {
|
|
104
110
|
type: 'quantitative',
|
105
111
|
title: meanTransform,
|
106
112
|
scale: {
|
107
|
-
scheme: featureValueColormap,
|
113
|
+
// scheme: featureValueColormap,
|
114
|
+
scheme: 'greys',
|
108
115
|
},
|
109
116
|
legend: {
|
110
117
|
direction: 'horizontal',
|
@@ -125,6 +132,11 @@ export default function DotPlot(props) {
|
|
125
132
|
legend: {
|
126
133
|
symbolFillColor: 'white',
|
127
134
|
},
|
135
|
+
scale: { domain: [0, 100] },
|
136
|
+
},
|
137
|
+
tooltip: {
|
138
|
+
field: 'pctPosInGroup',
|
139
|
+
type: 'quantitative',
|
128
140
|
},
|
129
141
|
},
|
130
142
|
width: plotWidth,
|
@@ -140,5 +152,46 @@ export default function DotPlot(props) {
|
|
140
152
|
} : {}),
|
141
153
|
},
|
142
154
|
};
|
143
|
-
|
155
|
+
const getTooltipText = useCallback(item => ({
|
156
|
+
[`${capitalize(featureType)}`]: item.datum.feature,
|
157
|
+
[`${capitalize(obsType)} Set`]: item.datum.group,
|
158
|
+
...(isStratified
|
159
|
+
? ({ [`${capitalize(sampleType)} Set`]: item.datum.secondaryGroup })
|
160
|
+
: {}),
|
161
|
+
[`Percentage of ${plur(obsType, 2)} in set`]: item.datum.pctPosInGroup,
|
162
|
+
[meanTransform.join(' ')]: item.datum.meanExpInGroup,
|
163
|
+
}), [featureType, obsType, featureValueType, featureValueTransformName]);
|
164
|
+
const obsSetColorScale = useMemo(() => getColorScale(obsSetSelection, obsSetColor, theme), [obsSetSelection, obsSetColor, theme]);
|
165
|
+
const [vegaRenderIncrement, setVegaRenderIncrement] = useState(0);
|
166
|
+
useEffect(() => {
|
167
|
+
// If the dot plot is stratified by both obsSet and sampleSet,
|
168
|
+
// then we want to add cell set colors.
|
169
|
+
// TODO: do we also want to add these color bars
|
170
|
+
// when only stratified by obsSet?
|
171
|
+
const domElement = vegaContainerRef.current;
|
172
|
+
// Here, we assume that the Vega SVG renderer is being used.
|
173
|
+
const svg = select(domElement)
|
174
|
+
.select('svg');
|
175
|
+
// We use the following CSS selector to identify all of
|
176
|
+
// the <line> elements that we are interested to modify.
|
177
|
+
const tickEls = svg.selectAll('g.root g.column_footer g.role-axis g.role-axis-domain line');
|
178
|
+
tickEls
|
179
|
+
.attr('stroke-width', 5)
|
180
|
+
.attr('dy', 2.5)
|
181
|
+
.attr('stroke', (d, i) => {
|
182
|
+
const obsSetPath = obsSetSelection?.[i];
|
183
|
+
return obsSetColorScale(obsSetPath);
|
184
|
+
});
|
185
|
+
}, [vegaContainerRef, vegaRenderIncrement, obsSetSelection, obsSetColorScale]);
|
186
|
+
// We want to increment the counter whenever we detect that VegaPlot
|
187
|
+
// has re-rendered.
|
188
|
+
const onNewView = useCallback(() => {
|
189
|
+
setVegaRenderIncrement(prev => prev + 1);
|
190
|
+
}, []);
|
191
|
+
// This is kind of hacky, since it is possible that the useEffect runs prior
|
192
|
+
// to the Vega rendering, but in practice it seems to work.
|
193
|
+
useEffect(() => {
|
194
|
+
setVegaRenderIncrement(prev => prev + 1);
|
195
|
+
}, [rawData]);
|
196
|
+
return (_jsx("div", { ref: vegaContainerRef, children: _jsx(VegaPlot, { data: data, spec: spec, onNewView: onNewView, getTooltipText: getTooltipText, renderer: "svg" }) }));
|
144
197
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"DotPlotSubscriber.d.ts","sourceRoot":"","sources":["../src/DotPlotSubscriber.js"],"names":[],"mappings":"AAmBA;;;;;;;GAOG;AACH,yCALG;IAAwB,mBAAmB;IACrB,kBAAkB,EAAhC,MAAM;IAEQ,KAAK,EAAnB,MAAM;CAChB,
|
1
|
+
{"version":3,"file":"DotPlotSubscriber.d.ts","sourceRoot":"","sources":["../src/DotPlotSubscriber.js"],"names":[],"mappings":"AAmBA;;;;;;;GAOG;AACH,yCALG;IAAwB,mBAAmB;IACrB,kBAAkB,EAAhC,MAAM;IAEQ,KAAK,EAAnB,MAAM;CAChB,eAsJA"}
|
@@ -50,5 +50,5 @@ export function DotPlotSubscriber(props) {
|
|
50
50
|
]);
|
51
51
|
const [resultArr, meanExpressionMax] = useExpressionSummaries(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, cellSets, additionalCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient, posThreshold, featureLabelsMap);
|
52
52
|
const selectedTransformName = transformOptions.find(o => o.value === featureValueTransform)?.name;
|
53
|
-
return (_jsx(TitleInfo, { title: title, removeGridComponent: removeGridComponent, urls: urls, theme: theme, isReady: isReady, helpText: helpText, options: (_jsx(CellSetExpressionPlotOptions, { featureValueTransform: featureValueTransform, setFeatureValueTransform: setFeatureValueTransform, featureValueTransformCoefficient: featureValueTransformCoefficient, setFeatureValueTransformCoefficient: setFeatureValueTransformCoefficient, transformOptions: transformOptions, featureValuePositivityThreshold: posThreshold, setFeatureValuePositivityThreshold: setPosThreshold, featureValueColormap: featureValueColormap, setFeatureValueColormap: setFeatureValueColormap })), children: _jsx("div", { ref: containerRef, className: classes.vegaContainer, children: resultArr ? (_jsx(DotPlot, { isStratified: isStratified, transpose: transpose, domainMax: meanExpressionMax, data: resultArr, theme: theme, width: width, height: height, obsType: obsType, featureType: featureType, featureValueType: featureValueType, featureValueTransformName: selectedTransformName, featureValueColormap: featureValueColormap,
|
53
|
+
return (_jsx(TitleInfo, { title: title, removeGridComponent: removeGridComponent, urls: urls, theme: theme, isReady: isReady, helpText: helpText, options: (_jsx(CellSetExpressionPlotOptions, { featureValueTransform: featureValueTransform, setFeatureValueTransform: setFeatureValueTransform, featureValueTransformCoefficient: featureValueTransformCoefficient, setFeatureValueTransformCoefficient: setFeatureValueTransformCoefficient, transformOptions: transformOptions, featureValuePositivityThreshold: posThreshold, setFeatureValuePositivityThreshold: setPosThreshold, featureValueColormap: featureValueColormap, setFeatureValueColormap: setFeatureValueColormap })), children: _jsx("div", { ref: containerRef, className: classes.vegaContainer, children: resultArr ? (_jsx(DotPlot, { isStratified: isStratified, transpose: transpose, domainMax: meanExpressionMax, data: resultArr, theme: theme, width: width, height: height, obsType: obsType, sampleType: sampleType, featureType: featureType, featureValueType: featureValueType, featureValueTransformName: selectedTransformName, featureValueColormap: featureValueColormap, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor })) : (_jsxs("span", { children: ["Select at least one ", featureType, "."] })) }) }));
|
54
54
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FeatureSetEnrichmentBarPlot.d.ts","sourceRoot":"","sources":["../src/FeatureSetEnrichmentBarPlot.js"],"names":[],"mappings":"AAOA;;GAEG;AACH,
|
1
|
+
{"version":3,"file":"FeatureSetEnrichmentBarPlot.d.ts","sourceRoot":"","sources":["../src/FeatureSetEnrichmentBarPlot.js"],"names":[],"mappings":"AAOA;;GAEG;AACH,6EAiMC"}
|
@@ -9,7 +9,7 @@ import { getColorScale } from './utils.js';
|
|
9
9
|
* Feature set enrichment test results displayed using a bar chart.
|
10
10
|
*/
|
11
11
|
export default function FeatureSetEnrichmentBarPlot(props) {
|
12
|
-
const { data, theme, width, height, marginRight =
|
12
|
+
const { data, theme, width, height, marginRight = 300, marginBottom = 120, keyLength = 36, featureType, onBarSelect, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, pValueThreshold, } = props;
|
13
13
|
const [obsSetColorScale, sampleSetColorScale] = useMemo(() => [
|
14
14
|
getColorScale(obsSetSelection, obsSetColor, theme),
|
15
15
|
getColorScale(sampleSetSelection, sampleSetColor, theme),
|
@@ -62,7 +62,7 @@ export default function FeatureSetEnrichmentBarPlot(props) {
|
|
62
62
|
}
|
63
63
|
return [...a, h];
|
64
64
|
}, []);
|
65
|
-
const MAX_ROWS =
|
65
|
+
const MAX_ROWS = 50;
|
66
66
|
result = result.slice(0, MAX_ROWS);
|
67
67
|
return result;
|
68
68
|
}
|
@@ -88,7 +88,7 @@ export default function FeatureSetEnrichmentBarPlot(props) {
|
|
88
88
|
select: {
|
89
89
|
type: 'point',
|
90
90
|
on: 'click[event.shiftKey === false]',
|
91
|
-
fields: ['name'],
|
91
|
+
fields: ['name', 'term'],
|
92
92
|
empty: 'none',
|
93
93
|
},
|
94
94
|
},
|
@@ -97,7 +97,7 @@ export default function FeatureSetEnrichmentBarPlot(props) {
|
|
97
97
|
select: {
|
98
98
|
type: 'point',
|
99
99
|
on: 'click[event.shiftKey]',
|
100
|
-
fields: ['name'],
|
100
|
+
fields: ['name', 'term'],
|
101
101
|
empty: 'none',
|
102
102
|
},
|
103
103
|
},
|
@@ -145,10 +145,11 @@ export default function FeatureSetEnrichmentBarPlot(props) {
|
|
145
145
|
};
|
146
146
|
const handleSignal = (name, value) => {
|
147
147
|
if (name === 'bar_select') {
|
148
|
-
onBarSelect(value.
|
148
|
+
onBarSelect(value.name?.[0], value.term?.[0]);
|
149
149
|
}
|
150
150
|
else if (name === 'shift_bar_select') {
|
151
|
-
|
151
|
+
// Name and term may be arrays
|
152
|
+
onBarSelect(value.name, value.term, true);
|
152
153
|
}
|
153
154
|
};
|
154
155
|
const signalListeners = { bar_select: handleSignal, shift_bar_select: handleSignal };
|