@vitessce/statistical-plots 3.5.7 → 3.5.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.
Files changed (51) hide show
  1. package/dist/{deflate-287e693d.js → deflate-1679ef33.js} +1 -1
  2. package/dist/{index-1f1b6355.js → index-0f4fe21d.js} +2065 -1061
  3. package/dist/index.js +9 -6
  4. package/dist/{jpeg-1b2c1d25.js → jpeg-280f0ee1.js} +1 -1
  5. package/dist/{lerc-4f010cd7.js → lerc-12264a36.js} +1 -1
  6. package/dist/{lzw-e60fb582.js → lzw-70f852cc.js} +1 -1
  7. package/dist/{packbits-a8bfe098.js → packbits-393c67b2.js} +1 -1
  8. package/dist/{raw-01dff90e.js → raw-d8d7ab7f.js} +1 -1
  9. package/dist/{webimage-6b926ce3.js → webimage-5d24a8e2.js} +1 -1
  10. package/dist-tsc/CellSetCompositionBarPlot.d.ts +5 -0
  11. package/dist-tsc/CellSetCompositionBarPlot.d.ts.map +1 -0
  12. package/dist-tsc/CellSetCompositionBarPlot.js +166 -0
  13. package/dist-tsc/CellSetCompositionBarPlotSubscriber.d.ts +2 -0
  14. package/dist-tsc/CellSetCompositionBarPlotSubscriber.d.ts.map +1 -0
  15. package/dist-tsc/CellSetCompositionBarPlotSubscriber.js +40 -0
  16. package/dist-tsc/FeatureSetEnrichmentBarPlot.d.ts +5 -0
  17. package/dist-tsc/FeatureSetEnrichmentBarPlot.d.ts.map +1 -0
  18. package/dist-tsc/FeatureSetEnrichmentBarPlot.js +164 -0
  19. package/dist-tsc/FeatureSetEnrichmentBarPlotSubscriber.d.ts +2 -0
  20. package/dist-tsc/FeatureSetEnrichmentBarPlotSubscriber.d.ts.map +1 -0
  21. package/dist-tsc/FeatureSetEnrichmentBarPlotSubscriber.js +51 -0
  22. package/dist-tsc/Treemap.d.ts.map +1 -1
  23. package/dist-tsc/Treemap.js +2 -12
  24. package/dist-tsc/TreemapSubscriber.d.ts.map +1 -1
  25. package/dist-tsc/TreemapSubscriber.js +1 -0
  26. package/dist-tsc/VolcanoPlot.d.ts +2 -0
  27. package/dist-tsc/VolcanoPlot.d.ts.map +1 -0
  28. package/dist-tsc/VolcanoPlot.js +230 -0
  29. package/dist-tsc/VolcanoPlotOptions.d.ts +2 -0
  30. package/dist-tsc/VolcanoPlotOptions.d.ts.map +1 -0
  31. package/dist-tsc/VolcanoPlotOptions.js +23 -0
  32. package/dist-tsc/VolcanoPlotSubscriber.d.ts +2 -0
  33. package/dist-tsc/VolcanoPlotSubscriber.d.ts.map +1 -0
  34. package/dist-tsc/VolcanoPlotSubscriber.js +33 -0
  35. package/dist-tsc/index.d.ts +3 -0
  36. package/dist-tsc/index.js +3 -0
  37. package/dist-tsc/utils.d.ts +9 -0
  38. package/dist-tsc/utils.d.ts.map +1 -0
  39. package/dist-tsc/utils.js +40 -0
  40. package/package.json +7 -7
  41. package/src/CellSetCompositionBarPlot.js +205 -0
  42. package/src/CellSetCompositionBarPlotSubscriber.js +151 -0
  43. package/src/FeatureSetEnrichmentBarPlot.js +203 -0
  44. package/src/FeatureSetEnrichmentBarPlotSubscriber.js +166 -0
  45. package/src/Treemap.js +2 -17
  46. package/src/TreemapSubscriber.js +1 -0
  47. package/src/VolcanoPlot.js +313 -0
  48. package/src/VolcanoPlotOptions.js +136 -0
  49. package/src/VolcanoPlotSubscriber.js +162 -0
  50. package/src/index.js +3 -0
  51. package/src/utils.js +47 -0
@@ -0,0 +1,151 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import React, { useMemo, useCallback } from 'react';
3
+ import {
4
+ TitleInfo,
5
+ useCoordination,
6
+ useLoaders,
7
+ useReady,
8
+ useGridItemSize,
9
+ useObsSetStatsData,
10
+ useMatchingLoader,
11
+ useColumnNameMapping,
12
+ } from '@vitessce/vit-s';
13
+ import {
14
+ ViewType,
15
+ COMPONENT_COORDINATION_TYPES,
16
+ ViewHelpMapping,
17
+ DataType,
18
+ } from '@vitessce/constants-internal';
19
+ import { capitalize } from '@vitessce/utils';
20
+ import CellSetCompositionBarPlot from './CellSetCompositionBarPlot.js';
21
+ import { useStyles } from './styles.js';
22
+ import { useRawSetPaths } from './utils.js';
23
+
24
+
25
+ export function CellSetCompositionBarPlotSubscriber(props) {
26
+ const {
27
+ coordinationScopes,
28
+ removeGridComponent,
29
+ theme,
30
+ helpText = ViewHelpMapping.OBS_SET_COMPOSITION_BAR_PLOT,
31
+ } = props;
32
+
33
+ const classes = useStyles();
34
+ const loaders = useLoaders();
35
+
36
+ // Get "props" from the coordination space.
37
+ const [{
38
+ dataset,
39
+ obsType,
40
+ sampleType,
41
+ featureType,
42
+ featureValueType,
43
+ obsFilter: cellFilter,
44
+ obsHighlight: cellHighlight,
45
+ obsSetSelection,
46
+ obsSetColor,
47
+ obsColorEncoding: cellColorEncoding,
48
+ additionalObsSets: additionalCellSets,
49
+ featurePointSignificanceThreshold,
50
+ featurePointFoldChangeThreshold,
51
+ featureLabelSignificanceThreshold,
52
+ featureLabelFoldChangeThreshold,
53
+ featureValueTransform,
54
+ featureValueTransformCoefficient,
55
+ gatingFeatureSelectionX,
56
+ gatingFeatureSelectionY,
57
+ featureSelection,
58
+ sampleSetSelection,
59
+ sampleSetColor,
60
+ }, {
61
+ setObsFilter: setCellFilter,
62
+ setObsSetSelection,
63
+ setObsHighlight: setCellHighlight,
64
+ setObsSetColor: setCellSetColor,
65
+ setObsColorEncoding: setCellColorEncoding,
66
+ setAdditionalObsSets: setAdditionalCellSets,
67
+ setFeaturePointSignificanceThreshold,
68
+ setFeaturePointFoldChangeThreshold,
69
+ setFeatureLabelSignificanceThreshold,
70
+ setFeatureLabelFoldChangeThreshold,
71
+ setFeatureValueTransform,
72
+ setFeatureValueTransformCoefficient,
73
+ setGatingFeatureSelectionX,
74
+ setGatingFeatureSelectionY,
75
+ setFeatureSelection,
76
+ setSampleSetSelection,
77
+ setSampleSetColor,
78
+ }] = useCoordination(
79
+ COMPONENT_COORDINATION_TYPES[ViewType.OBS_SET_COMPOSITION_BAR_PLOT],
80
+ coordinationScopes,
81
+ );
82
+ const [width, height, containerRef] = useGridItemSize();
83
+
84
+ const obsSetsLoader = useMatchingLoader(
85
+ loaders, dataset, DataType.OBS_SETS, { obsType },
86
+ );
87
+ const sampleSetsLoader = useMatchingLoader(
88
+ loaders, dataset, DataType.SAMPLE_SETS, { sampleType },
89
+ );
90
+ const obsSetsColumnNameMapping = useColumnNameMapping(obsSetsLoader);
91
+ const obsSetsColumnNameMappingReversed = useColumnNameMapping(obsSetsLoader, true);
92
+ const sampleSetsColumnNameMapping = useColumnNameMapping(sampleSetsLoader);
93
+ const sampleSetsColumnNameMappingReversed = useColumnNameMapping(sampleSetsLoader, true);
94
+
95
+ const rawSampleSetSelection = useRawSetPaths(sampleSetsColumnNameMapping, sampleSetSelection);
96
+ const rawObsSetSelection = useRawSetPaths(obsSetsColumnNameMapping, obsSetSelection);
97
+
98
+ const [{ obsSetStats }, obsSetStatsStatus] = useObsSetStatsData(
99
+ loaders, dataset, false,
100
+ { obsType, sampleType },
101
+ // These volcanoOptions are passed to ObsSetStatsAnndataLoader.loadMulti():
102
+ { sampleSetSelection: rawSampleSetSelection, obsSetSelection: rawObsSetSelection },
103
+ );
104
+
105
+ const isReady = useReady([
106
+ obsSetStatsStatus,
107
+ ]);
108
+
109
+ // Support a click handler which selects individual cell set bars.
110
+ const onBarSelect = useCallback((setNamePath, isShiftDown = false) => {
111
+ // TODO: Implement different behavior when isShiftDown
112
+ setObsSetSelection([setNamePath]);
113
+ }, [setObsSetSelection]);
114
+
115
+ // TODO: support the following options
116
+ // - Use logFoldChange vs. intercept+effect for the bar y-value.
117
+ // - Boolean flag to allow hiding non-significant bars.
118
+
119
+ return (
120
+ <TitleInfo
121
+ title={`${capitalize(obsType)} Set Composition Analysis Plot`}
122
+ removeGridComponent={removeGridComponent}
123
+ theme={theme}
124
+ isReady={isReady}
125
+ helpText={helpText}
126
+ >
127
+ <div ref={containerRef} className={classes.vegaContainer}>
128
+ {obsSetStats ? (
129
+ <CellSetCompositionBarPlot
130
+ theme={theme}
131
+ width={width}
132
+ height={height}
133
+ obsType={obsType}
134
+ obsSetsColumnNameMapping={obsSetsColumnNameMapping}
135
+ obsSetsColumnNameMappingReversed={obsSetsColumnNameMappingReversed}
136
+ sampleSetsColumnNameMapping={sampleSetsColumnNameMapping}
137
+ sampleSetsColumnNameMappingReversed={sampleSetsColumnNameMappingReversed}
138
+ sampleSetSelection={sampleSetSelection}
139
+ obsSetSelection={obsSetSelection}
140
+ obsSetColor={obsSetColor}
141
+ sampleSetColor={sampleSetColor}
142
+ data={obsSetStats}
143
+ onBarSelect={onBarSelect}
144
+ />
145
+ ) : (
146
+ <span>Select at least one {obsType} set.</span>
147
+ )}
148
+ </div>
149
+ </TitleInfo>
150
+ );
151
+ }
@@ -0,0 +1,203 @@
1
+ import React, { useCallback, useMemo } from 'react';
2
+ import { clamp } from 'lodash-es';
3
+ import { v4 as uuidv4 } from 'uuid';
4
+ import { VegaPlot, VEGA_THEMES } from '@vitessce/vega';
5
+ import { capitalize } from '@vitessce/utils';
6
+ import { getColorScale } from './utils.js';
7
+
8
+ /**
9
+ * Feature set enrichment test results displayed using a bar chart.
10
+ */
11
+ export default function FeatureSetEnrichmentBarPlot(props) {
12
+ const {
13
+ data,
14
+ theme,
15
+ width,
16
+ height,
17
+ marginRight = 200,
18
+ marginBottom = 120,
19
+ keyLength = 36,
20
+ featureType,
21
+ onBarSelect,
22
+ obsSetsColumnNameMappingReversed,
23
+ sampleSetsColumnNameMappingReversed,
24
+ sampleSetSelection,
25
+ obsSetSelection,
26
+ obsSetColor,
27
+ sampleSetColor,
28
+ pValueThreshold,
29
+ } = props;
30
+
31
+ const [obsSetColorScale, sampleSetColorScale] = useMemo(() => [
32
+ getColorScale(obsSetSelection, obsSetColor, theme),
33
+ getColorScale(sampleSetSelection, sampleSetColor, theme),
34
+ ], [obsSetSelection, sampleSetSelection, sampleSetColor, obsSetColor, theme]);
35
+
36
+ const computedData = useMemo(() => {
37
+ if (Array.isArray(data)) {
38
+ let result = [];
39
+ data.forEach((comparisonObject) => {
40
+ const { df, metadata } = comparisonObject;
41
+ const coordinationValues = metadata?.coordination_values;
42
+
43
+ const rawObsSetPath = coordinationValues.obsSetFilter
44
+ ? coordinationValues.obsSetFilter[0]
45
+ : coordinationValues.obsSetSelection[0];
46
+ const obsSetPath = [...rawObsSetPath];
47
+ obsSetPath[0] = obsSetsColumnNameMappingReversed[rawObsSetPath[0]];
48
+
49
+ const color = obsSetColorScale(obsSetPath);
50
+
51
+ df.featureSetName.forEach((featureSetName, i) => {
52
+ const key = uuidv4();
53
+ result.push({
54
+ key,
55
+ name: featureSetName,
56
+ term: df.featureSetTerm[i],
57
+ color,
58
+ obsSetPath,
59
+ obsSetPaths: [obsSetPath],
60
+ obsSetNameToPval: { [obsSetPath.at(-1)]: df.featureSetSignificance[i] },
61
+ keyName: `${key}${featureSetName}`,
62
+ featureSetSignificance: df.featureSetSignificance[i],
63
+ minusLog10p: -Math.log10(df.featureSetSignificance[i]),
64
+ // Color based on obsSet
65
+ });
66
+ });
67
+ });
68
+
69
+ // TODO: instead of filtering, perhaps use virtual scrolling
70
+ // (would require custom renderer / not using Vega-Lite).
71
+ result = result
72
+ .map(d => ({
73
+ ...d,
74
+ minusLog10p: Math.min(50, d.minusLog10p), // Clamp infinite values at 50
75
+ }))
76
+ .filter(d => d.featureSetSignificance <= pValueThreshold)
77
+ .toSorted((a, b) => a.featureSetSignificance - b.featureSetSignificance)
78
+ .reduce((a, h) => {
79
+ // Only add the pathway once if it appears for multiple cell types?
80
+ const match = a.find(d => d.name === h.name);
81
+ if (match) {
82
+ match.obsSetPaths.push(h.obsSetPath);
83
+ match.obsSetNameToPval[h.obsSetPath.at(-1)] = h.featureSetSignificance;
84
+ return a;
85
+ }
86
+ return [...a, h];
87
+ }, []);
88
+
89
+ const MAX_ROWS = 25;
90
+ result = result.slice(0, MAX_ROWS);
91
+ return result;
92
+ }
93
+ return null;
94
+ }, [data, sampleSetSelection, obsSetsColumnNameMappingReversed,
95
+ sampleSetsColumnNameMappingReversed, obsSetSelection,
96
+ obsSetColorScale, sampleSetColorScale, pValueThreshold,
97
+ ]);
98
+
99
+ // Get an array of keys for sorting purposes.
100
+ const keys = computedData.map(d => d.keyName);
101
+
102
+ const colorScale = {
103
+ // Manually set the color scale so that Vega-Lite does
104
+ // not choose the colors automatically.
105
+ domain: computedData.map(d => d.key),
106
+ range: computedData.map(d => d.color),
107
+ };
108
+ const captializedFeatureType = capitalize(featureType);
109
+
110
+ const spec = {
111
+ mark: { type: 'bar', stroke: 'black', cursor: 'pointer' },
112
+ params: [
113
+ {
114
+ name: 'bar_select',
115
+ select: {
116
+ type: 'point',
117
+ on: 'click[event.shiftKey === false]',
118
+ fields: ['name'],
119
+ empty: 'none',
120
+ },
121
+ },
122
+ {
123
+ name: 'shift_bar_select',
124
+ select: {
125
+ type: 'point',
126
+ on: 'click[event.shiftKey]',
127
+ fields: ['name'],
128
+ empty: 'none',
129
+ },
130
+ },
131
+ ],
132
+ encoding: {
133
+ y: {
134
+ field: 'keyName',
135
+ type: 'nominal',
136
+ axis: { labelExpr: `substring(datum.label, ${keyLength})` },
137
+ title: `${captializedFeatureType} Set`,
138
+ sort: keys,
139
+ },
140
+ x: {
141
+ field: 'minusLog10p',
142
+ type: 'quantitative',
143
+ title: '- log10 p-value',
144
+ },
145
+ color: {
146
+ field: 'key',
147
+ type: 'nominal',
148
+ scale: colorScale,
149
+ legend: null,
150
+ },
151
+ /*
152
+ fillOpacity: {
153
+ field: 'isCredibleEffect',
154
+ type: 'nominal',
155
+ scale: opacityScale,
156
+ },
157
+ strokeWidth: {
158
+ field: 'isReferenceSet',
159
+ type: 'nominal',
160
+ scale: strokeWidthScale,
161
+ },
162
+ */
163
+ tooltip: {
164
+ field: 'featureSetSignificance',
165
+ type: 'quantitative',
166
+ },
167
+ },
168
+ // TODO: for width, also subtract length of longest y-axis set name label.
169
+ width: clamp(width - marginRight, 10, Infinity),
170
+ height: clamp(height - marginBottom, 10, Infinity),
171
+ config: VEGA_THEMES[theme],
172
+ };
173
+
174
+ const handleSignal = (name, value) => {
175
+ if (name === 'bar_select') {
176
+ onBarSelect(value.obsSetPath);
177
+ } else if (name === 'shift_bar_select') {
178
+ onBarSelect(value.obsSetPath, true);
179
+ }
180
+ };
181
+
182
+ const signalListeners = { bar_select: handleSignal, shift_bar_select: handleSignal };
183
+ const getTooltipText = useCallback(item => ({
184
+ [`${captializedFeatureType} Set`]: item.datum.name,
185
+ 'Ontology Term': item.datum.term,
186
+ ...Object.fromEntries(
187
+ Object.entries(item.datum.obsSetNameToPval).map(([cellSetName, pVal]) => ([
188
+ `p-value for ${cellSetName}`,
189
+ pVal,
190
+ ])),
191
+ ),
192
+ }
193
+ ), [captializedFeatureType]);
194
+
195
+ return (
196
+ <VegaPlot
197
+ data={computedData}
198
+ spec={spec}
199
+ signalListeners={signalListeners}
200
+ getTooltipText={getTooltipText}
201
+ />
202
+ );
203
+ }
@@ -0,0 +1,166 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import React, { useCallback } from 'react';
3
+ import {
4
+ TitleInfo,
5
+ useCoordination,
6
+ useLoaders,
7
+ useReady,
8
+ useGridItemSize,
9
+ useFeatureSetStatsData,
10
+ useMatchingLoader,
11
+ useColumnNameMapping,
12
+ useAsyncFunction,
13
+ } from '@vitessce/vit-s';
14
+ import {
15
+ ViewType,
16
+ COMPONENT_COORDINATION_TYPES,
17
+ ViewHelpMapping,
18
+ DataType,
19
+ AsyncFunctionType,
20
+ } from '@vitessce/constants-internal';
21
+ import { capitalize } from '@vitessce/utils';
22
+ import FeatureSetEnrichmentBarPlot from './FeatureSetEnrichmentBarPlot.js';
23
+ import { useStyles } from './styles.js';
24
+ import { useRawSetPaths } from './utils.js';
25
+
26
+
27
+ export function FeatureSetEnrichmentBarPlotSubscriber(props) {
28
+ const {
29
+ coordinationScopes,
30
+ removeGridComponent,
31
+ theme,
32
+ helpText = ViewHelpMapping.FEATURE_SET_ENRICHMENT_BAR_PLOT,
33
+ } = props;
34
+
35
+ const classes = useStyles();
36
+ const loaders = useLoaders();
37
+ const transformFeature = useAsyncFunction(AsyncFunctionType.TRANSFORM_FEATURE);
38
+
39
+ // Get "props" from the coordination space.
40
+ const [{
41
+ dataset,
42
+ obsType,
43
+ sampleType,
44
+ featureType,
45
+ featureValueType,
46
+ obsFilter: cellFilter,
47
+ obsHighlight: cellHighlight,
48
+ obsSetSelection,
49
+ obsSetColor,
50
+ obsColorEncoding: cellColorEncoding,
51
+ additionalObsSets: additionalCellSets,
52
+ featurePointSignificanceThreshold,
53
+ featurePointFoldChangeThreshold,
54
+ featureLabelSignificanceThreshold,
55
+ featureLabelFoldChangeThreshold,
56
+ featureValueTransform,
57
+ featureValueTransformCoefficient,
58
+ gatingFeatureSelectionX,
59
+ gatingFeatureSelectionY,
60
+ featureSelection,
61
+ sampleSetSelection,
62
+ sampleSetColor,
63
+ }, {
64
+ setObsFilter: setCellFilter,
65
+ setObsSetSelection,
66
+ setObsHighlight: setCellHighlight,
67
+ setObsSetColor: setCellSetColor,
68
+ setObsColorEncoding: setCellColorEncoding,
69
+ setAdditionalObsSets: setAdditionalCellSets,
70
+ setFeaturePointSignificanceThreshold,
71
+ setFeaturePointFoldChangeThreshold,
72
+ setFeatureLabelSignificanceThreshold,
73
+ setFeatureLabelFoldChangeThreshold,
74
+ setFeatureValueTransform,
75
+ setFeatureValueTransformCoefficient,
76
+ setGatingFeatureSelectionX,
77
+ setGatingFeatureSelectionY,
78
+ setFeatureSelection,
79
+ setSampleSetSelection,
80
+ setSampleSetColor,
81
+ }] = useCoordination(
82
+ COMPONENT_COORDINATION_TYPES[ViewType.FEATURE_SET_ENRICHMENT_BAR_PLOT],
83
+ coordinationScopes,
84
+ );
85
+ const [width, height, containerRef] = useGridItemSize();
86
+
87
+ const obsSetsLoader = useMatchingLoader(
88
+ loaders, dataset, DataType.OBS_SETS, { obsType },
89
+ );
90
+ const sampleSetsLoader = useMatchingLoader(
91
+ loaders, dataset, DataType.SAMPLE_SETS, { sampleType },
92
+ );
93
+ const obsSetsColumnNameMapping = useColumnNameMapping(obsSetsLoader);
94
+ const obsSetsColumnNameMappingReversed = useColumnNameMapping(obsSetsLoader, true);
95
+ const sampleSetsColumnNameMapping = useColumnNameMapping(sampleSetsLoader);
96
+ const sampleSetsColumnNameMappingReversed = useColumnNameMapping(sampleSetsLoader, true);
97
+
98
+ const rawSampleSetSelection = useRawSetPaths(sampleSetsColumnNameMapping, sampleSetSelection);
99
+ const rawObsSetSelection = useRawSetPaths(obsSetsColumnNameMapping, obsSetSelection);
100
+
101
+ const [{ featureSetStats }, featureSetStatsStatus] = useFeatureSetStatsData(
102
+ loaders, dataset, false,
103
+ { obsType, featureType, sampleType },
104
+ // These volcanoOptions are passed to ObsSetStatsAnndataLoader.loadMulti():
105
+ { sampleSetSelection: rawSampleSetSelection, obsSetSelection: rawObsSetSelection },
106
+ );
107
+
108
+ const isReady = useReady([
109
+ featureSetStatsStatus,
110
+ ]);
111
+
112
+ // Support a click handler which selects individual cell set bars.
113
+ const onBarSelect = useCallback(async (featureSetName, featureSetTerm, isShiftDown = false) => {
114
+ // TODO: Implement different behavior when isShiftDown
115
+ // TODO: get feature IDs using AsyncFunction transformFeature
116
+ // (pathway term in, gene names out).
117
+ const kgNode = { nodeType: 'pathway', term: featureSetTerm };
118
+ const targetFeatureType = featureType;
119
+ // Will not work since transformFeature currently:
120
+ // - matches based on kgId (rather than term)
121
+ // - only knows about Reactome pathways (not GO terms).
122
+ // console.log(await transformFeature(kgNode, targetFeatureType))
123
+ // setFeatureSelection(featureIds);
124
+ }, [setFeatureSelection]);
125
+
126
+ // TODO: support the following options
127
+ // - p-value threshold for which bars to show
128
+ // - max number of bars to show
129
+ // - Boolean flag: should same pathway which appears multiple times
130
+ // be de-duplicated (one bar per pathway, using most-significant result)?
131
+
132
+ return (
133
+ <TitleInfo
134
+ title={`${capitalize(featureType)} Set Enrichment Plot`}
135
+ removeGridComponent={removeGridComponent}
136
+ theme={theme}
137
+ isReady={isReady}
138
+ helpText={helpText}
139
+ >
140
+ <div ref={containerRef} className={classes.vegaContainer}>
141
+ {featureSetStats ? (
142
+ <FeatureSetEnrichmentBarPlot
143
+ theme={theme}
144
+ width={width}
145
+ height={height}
146
+ obsType={obsType}
147
+ featureType={featureType}
148
+ obsSetsColumnNameMapping={obsSetsColumnNameMapping}
149
+ obsSetsColumnNameMappingReversed={obsSetsColumnNameMappingReversed}
150
+ sampleSetsColumnNameMapping={sampleSetsColumnNameMapping}
151
+ sampleSetsColumnNameMappingReversed={sampleSetsColumnNameMappingReversed}
152
+ sampleSetSelection={sampleSetSelection}
153
+ obsSetSelection={obsSetSelection}
154
+ obsSetColor={obsSetColor}
155
+ sampleSetColor={sampleSetColor}
156
+ data={featureSetStats}
157
+ onBarSelect={onBarSelect}
158
+ pValueThreshold={0.01}
159
+ />
160
+ ) : (
161
+ <span>Select at least one {obsType} set.</span>
162
+ )}
163
+ </div>
164
+ </TitleInfo>
165
+ );
166
+ }
package/src/Treemap.js CHANGED
@@ -1,13 +1,12 @@
1
1
  /* eslint-disable indent */
2
2
  /* eslint-disable camelcase */
3
3
  import React, { useMemo, useEffect, useRef } from 'react';
4
- import { scaleOrdinal } from 'd3-scale';
5
4
  import { select } from 'd3-selection';
6
5
  import { treemap, treemapBinary, hierarchy as d3_hierarchy } from 'd3-hierarchy';
7
6
  import { rollup as d3_rollup } from 'd3-array';
8
7
  import { isEqual } from 'lodash-es';
9
- import { colorArrayToString } from '@vitessce/sets-utils';
10
- import { getDefaultColor, pluralize as plur } from '@vitessce/utils';
8
+ import { pluralize as plur } from '@vitessce/utils';
9
+ import { getColorScale } from './utils.js';
11
10
 
12
11
  // Based on Observable's built-in DOM.uid function.
13
12
  // This is intended to be used with SVG clipPaths
@@ -21,20 +20,6 @@ function uidGenerator(prefix) {
21
20
  };
22
21
  }
23
22
 
24
- // Create a d3-scale ordinal scale mapping set paths to color strings.
25
- function getColorScale(setSelectionArr, setColorArr, theme) {
26
- return scaleOrdinal()
27
- .domain(setSelectionArr || [])
28
- .range(
29
- setSelectionArr
30
- ?.map(setNamePath => (
31
- setColorArr?.find(d => isEqual(d.path, setNamePath))?.color
32
- || getDefaultColor(theme)
33
- ))
34
- ?.map(colorArrayToString) || [],
35
- );
36
- }
37
-
38
23
  /**
39
24
  * Renders a treemap plot using D3.
40
25
  * References:
@@ -211,6 +211,7 @@ export function TreemapSubscriber(props) {
211
211
  ];
212
212
  }, [obsIndex, sampleEdges, sampleSets, obsSetColor,
213
213
  sampleSetColor, mergedObsSets, obsSetSelection, mergedSampleSets,
214
+ sampleSetSelection,
214
215
  // TODO: consider filtering-related coordination values
215
216
  ]);
216
217