@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.
Files changed (67) hide show
  1. package/dist/{deflate-19841f78.js → deflate-b8c6daae.js} +1 -1
  2. package/dist/{index-dc733355.js → index-134a71c6.js} +33739 -15506
  3. package/dist/index.js +6 -5
  4. package/dist/{jpeg-a83077be.js → jpeg-1b818d11.js} +1 -1
  5. package/dist/{lerc-1edd075a.js → lerc-f38cbdfc.js} +1 -1
  6. package/dist/{lzw-9572eac3.js → lzw-1120aba9.js} +1 -1
  7. package/dist/{packbits-cce11fbc.js → packbits-2d02b5e3.js} +1 -1
  8. package/dist/{raw-f7587aff.js → raw-0887baec.js} +1 -1
  9. package/dist/{webimage-8d38cd8b.js → webimage-533922a5.js} +1 -1
  10. package/dist-tsc/CellSetCompositionBarPlot.d.ts.map +1 -1
  11. package/dist-tsc/CellSetCompositionBarPlot.js +31 -10
  12. package/dist-tsc/CellSetCompositionBarPlotSubscriber.js +1 -1
  13. package/dist-tsc/CellSetExpressionPlot.d.ts.map +1 -1
  14. package/dist-tsc/CellSetExpressionPlot.js +26 -10
  15. package/dist-tsc/CellSetExpressionPlotOptions.d.ts.map +1 -1
  16. package/dist-tsc/CellSetExpressionPlotOptions.js +11 -4
  17. package/dist-tsc/CellSetExpressionPlotSubscriber.d.ts.map +1 -1
  18. package/dist-tsc/CellSetExpressionPlotSubscriber.js +46 -11
  19. package/dist-tsc/DotPlot.d.ts.map +1 -1
  20. package/dist-tsc/DotPlot.js +59 -6
  21. package/dist-tsc/DotPlotSubscriber.d.ts.map +1 -1
  22. package/dist-tsc/DotPlotSubscriber.js +1 -1
  23. package/dist-tsc/FeatureSetEnrichmentBarPlot.d.ts.map +1 -1
  24. package/dist-tsc/FeatureSetEnrichmentBarPlot.js +7 -6
  25. package/dist-tsc/FeatureSetEnrichmentBarPlotSubscriber.d.ts.map +1 -1
  26. package/dist-tsc/FeatureSetEnrichmentBarPlotSubscriber.js +5 -2
  27. package/dist-tsc/FeatureStatsTable.d.ts +2 -0
  28. package/dist-tsc/FeatureStatsTable.d.ts.map +1 -0
  29. package/dist-tsc/FeatureStatsTable.js +81 -0
  30. package/dist-tsc/FeatureStatsTableSubscriber.d.ts +2 -0
  31. package/dist-tsc/FeatureStatsTableSubscriber.d.ts.map +1 -0
  32. package/dist-tsc/FeatureStatsTableSubscriber.js +28 -0
  33. package/dist-tsc/Treemap.d.ts.map +1 -1
  34. package/dist-tsc/Treemap.js +17 -3
  35. package/dist-tsc/TreemapSubscriber.d.ts.map +1 -1
  36. package/dist-tsc/TreemapSubscriber.js +15 -9
  37. package/dist-tsc/VolcanoPlot.d.ts.map +1 -1
  38. package/dist-tsc/VolcanoPlot.js +15 -46
  39. package/dist-tsc/VolcanoPlotSubscriber.d.ts.map +1 -1
  40. package/dist-tsc/VolcanoPlotSubscriber.js +4 -2
  41. package/dist-tsc/expr-hooks.d.ts.map +1 -1
  42. package/dist-tsc/expr-hooks.test.js +2 -1
  43. package/dist-tsc/index.d.ts +1 -0
  44. package/dist-tsc/index.js +1 -0
  45. package/dist-tsc/utils.d.ts +1 -0
  46. package/dist-tsc/utils.d.ts.map +1 -1
  47. package/dist-tsc/utils.js +56 -0
  48. package/package.json +8 -7
  49. package/src/CellSetCompositionBarPlot.js +38 -12
  50. package/src/CellSetCompositionBarPlotSubscriber.js +1 -1
  51. package/src/CellSetExpressionPlot.js +33 -10
  52. package/src/CellSetExpressionPlotOptions.js +39 -2
  53. package/src/CellSetExpressionPlotSubscriber.js +56 -13
  54. package/src/DotPlot.js +81 -11
  55. package/src/DotPlotSubscriber.js +3 -1
  56. package/src/FeatureSetEnrichmentBarPlot.js +7 -6
  57. package/src/FeatureSetEnrichmentBarPlotSubscriber.js +5 -2
  58. package/src/FeatureStatsTable.js +116 -0
  59. package/src/FeatureStatsTableSubscriber.js +133 -0
  60. package/src/Treemap.js +21 -3
  61. package/src/TreemapSubscriber.js +26 -11
  62. package/src/VolcanoPlot.js +16 -64
  63. package/src/VolcanoPlotSubscriber.js +6 -1
  64. package/src/expr-hooks.js +0 -1
  65. package/src/expr-hooks.test.js +2 -1
  66. package/src/index.js +1 -0
  67. package/src/utils.js +82 -1
@@ -1 +1 @@
1
- {"version":3,"file":"FeatureSetEnrichmentBarPlotSubscriber.d.ts","sourceRoot":"","sources":["../src/FeatureSetEnrichmentBarPlotSubscriber.js"],"names":[],"mappings":"AA0BA,+EA2IC"}
1
+ {"version":3,"file":"FeatureSetEnrichmentBarPlotSubscriber.d.ts","sourceRoot":"","sources":["../src/FeatureSetEnrichmentBarPlotSubscriber.js"],"names":[],"mappings":"AA0BA,+EA8IC"}
@@ -39,8 +39,11 @@ export function FeatureSetEnrichmentBarPlotSubscriber(props) {
39
39
  // Will not work since transformFeature currently:
40
40
  // - matches based on kgId (rather than term)
41
41
  // - only knows about Reactome pathways (not GO terms).
42
- // console.log(await transformFeature(kgNode, targetFeatureType))
43
- // setFeatureSelection(featureIds);
42
+ const targetsInPathway = await transformFeature(kgNode, targetFeatureType);
43
+ const featureIds = targetsInPathway
44
+ .filter((d, i) => i < 10) // TODO: do not limit the number of genes here
45
+ .map(d => d.label);
46
+ setFeatureSelection(featureIds);
44
47
  }, [setFeatureSelection]);
45
48
  // TODO: support the following options
46
49
  // - p-value threshold for which bars to show
@@ -0,0 +1,2 @@
1
+ export default function FeatureStatsTable(props: any): JSX.Element;
2
+ //# sourceMappingURL=FeatureStatsTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureStatsTable.d.ts","sourceRoot":"","sources":["../src/FeatureStatsTable.js"],"names":[],"mappings":"AAWA,mEAwGC"}
@@ -0,0 +1,81 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useMemo, useState, useCallback } from 'react';
3
+ import { DataGrid } from '@mui/x-data-grid';
4
+ import { capitalize } from '@vitessce/utils';
5
+ import { useFilteredVolcanoData } from './utils.js';
6
+ const ROW_ID_DELIMITER = '___';
7
+ const INITIAL_SORT_MODEL = [
8
+ // We initially set the sorting this way
9
+ { field: 'logFoldChange', sort: 'desc' },
10
+ ];
11
+ export default function FeatureStatsTable(props) {
12
+ const { obsType, featureType, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, data, setFeatureSelection, featurePointSignificanceThreshold, featurePointFoldChangeThreshold, } = props;
13
+ const [
14
+ // eslint-disable-next-line no-unused-vars
15
+ computedData, filteredData,] = useFilteredVolcanoData({
16
+ data,
17
+ obsSetsColumnNameMappingReversed,
18
+ sampleSetsColumnNameMappingReversed,
19
+ featurePointFoldChangeThreshold,
20
+ featurePointSignificanceThreshold,
21
+ sampleSetSelection,
22
+ });
23
+ // Reference: https://v4.mui.com/api/data-grid/data-grid/
24
+ const columns = useMemo(() => ([
25
+ {
26
+ field: 'featureId',
27
+ headerName: capitalize(featureType),
28
+ width: 200,
29
+ editable: false,
30
+ },
31
+ {
32
+ field: 'logFoldChange',
33
+ headerName: 'Log Fold-Change',
34
+ width: 200,
35
+ editable: false,
36
+ },
37
+ {
38
+ field: 'featureSignificance',
39
+ headerName: 'P-value',
40
+ width: 200,
41
+ editable: false,
42
+ },
43
+ {
44
+ field: 'obsSetName',
45
+ headerName: `${capitalize(obsType)} Set`,
46
+ width: 200,
47
+ editable: false,
48
+ },
49
+ ]), [obsType, featureType]);
50
+ const rows = useMemo(() => {
51
+ let result = [];
52
+ if (filteredData) {
53
+ filteredData.forEach((comparisonObject) => {
54
+ const { df, metadata } = comparisonObject;
55
+ const coordinationValues = metadata.coordination_values;
56
+ const rawObsSetPath = coordinationValues.obsSetFilter
57
+ ? coordinationValues.obsSetFilter[0]
58
+ : coordinationValues.obsSetSelection[0];
59
+ const obsSetPath = [...rawObsSetPath];
60
+ obsSetPath[0] = obsSetsColumnNameMappingReversed[rawObsSetPath[0]];
61
+ const obsSetName = obsSetPath.at(-1);
62
+ result = result.concat(df.map(row => ({
63
+ ...row,
64
+ id: `${row.featureId}${ROW_ID_DELIMITER}${obsSetName}`,
65
+ obsSetName,
66
+ })));
67
+ });
68
+ }
69
+ return result;
70
+ }, [filteredData, obsSetsColumnNameMappingReversed]);
71
+ const onSelectionModelChange = useCallback((rowIds) => {
72
+ const featureIds = rowIds.map(rowId => rowId.split(ROW_ID_DELIMITER)[0]);
73
+ setFeatureSelection(featureIds);
74
+ }, []);
75
+ const rowSelectionModel = useMemo(() => [], []);
76
+ const [sortModel, setSortModel] = useState(INITIAL_SORT_MODEL);
77
+ const getRowId = useCallback(row => row.id, []);
78
+ return (_jsx(DataGrid, { density: "compact", rows: rows, columns: columns, pageSize: 10,
79
+ // checkboxSelection // TODO: uncomment to enable multiple-row selection
80
+ onSelectionModelChange: onSelectionModelChange, rowSelectionModel: rowSelectionModel, getRowId: getRowId, sortModel: sortModel, onSortModelChange: setSortModel }));
81
+ }
@@ -0,0 +1,2 @@
1
+ export function FeatureStatsTableSubscriber(props: any): JSX.Element;
2
+ //# sourceMappingURL=FeatureStatsTableSubscriber.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureStatsTableSubscriber.d.ts","sourceRoot":"","sources":["../src/FeatureStatsTableSubscriber.js"],"names":[],"mappings":"AAoBA,qEAgHC"}
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /* eslint-disable no-unused-vars */
3
+ import React from 'react';
4
+ import { TitleInfo, useCoordination, useLoaders, useReady, useFeatureStatsData, useMatchingLoader, useColumnNameMapping, } from '@vitessce/vit-s';
5
+ import { ViewType, COMPONENT_COORDINATION_TYPES, ViewHelpMapping, DataType, } from '@vitessce/constants-internal';
6
+ import FeatureStatsTable from './FeatureStatsTable.js';
7
+ import { useRawSetPaths } from './utils.js';
8
+ export function FeatureStatsTableSubscriber(props) {
9
+ const { title = 'Differential Expression Results', coordinationScopes, removeGridComponent, theme, helpText = ViewHelpMapping.FEATURE_STATS_TABLE, } = props;
10
+ const loaders = useLoaders();
11
+ // Get "props" from the coordination space.
12
+ const [{ dataset, obsType, sampleType, featureType, featureValueType, obsFilter: cellFilter, obsHighlight: cellHighlight, obsSetSelection, obsSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, featurePointSignificanceThreshold, featurePointFoldChangeThreshold, featureValueTransform, featureValueTransformCoefficient, gatingFeatureSelectionX, gatingFeatureSelectionY, featureSelection, sampleSetSelection, sampleSetColor, }, { setObsFilter: setCellFilter, setObsSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setFeaturePointSignificanceThreshold, setFeaturePointFoldChangeThreshold, setFeatureValueTransform, setFeatureValueTransformCoefficient, setGatingFeatureSelectionX, setGatingFeatureSelectionY, setFeatureSelection, setSampleSetSelection, setSampleSetColor, }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType.FEATURE_STATS_TABLE], coordinationScopes);
13
+ const obsSetsLoader = useMatchingLoader(loaders, dataset, DataType.OBS_SETS, { obsType });
14
+ const sampleSetsLoader = useMatchingLoader(loaders, dataset, DataType.SAMPLE_SETS, { sampleType });
15
+ const obsSetsColumnNameMapping = useColumnNameMapping(obsSetsLoader);
16
+ const obsSetsColumnNameMappingReversed = useColumnNameMapping(obsSetsLoader, true);
17
+ const sampleSetsColumnNameMapping = useColumnNameMapping(sampleSetsLoader);
18
+ const sampleSetsColumnNameMappingReversed = useColumnNameMapping(sampleSetsLoader, true);
19
+ const rawSampleSetSelection = useRawSetPaths(sampleSetsColumnNameMapping, sampleSetSelection);
20
+ const rawObsSetSelection = useRawSetPaths(obsSetsColumnNameMapping, obsSetSelection);
21
+ const [{ featureStats }, featureStatsStatus] = useFeatureStatsData(loaders, dataset, false, { obsType, featureType, sampleType },
22
+ // These volcanoOptions are passed to FeatureStatsAnndataLoader.loadMulti():
23
+ { sampleSetSelection: rawSampleSetSelection, obsSetSelection: rawObsSetSelection });
24
+ const isReady = useReady([
25
+ featureStatsStatus,
26
+ ]);
27
+ return (_jsx(TitleInfo, { title: title, removeGridComponent: removeGridComponent, theme: theme, isReady: isReady, helpText: helpText, withPadding: false, children: featureStats ? (_jsx(FeatureStatsTable, { theme: theme, obsType: obsType, featureType: featureType, obsSetsColumnNameMapping: obsSetsColumnNameMapping, obsSetsColumnNameMappingReversed: obsSetsColumnNameMappingReversed, sampleSetsColumnNameMapping: sampleSetsColumnNameMapping, sampleSetsColumnNameMappingReversed: sampleSetsColumnNameMappingReversed, sampleSetSelection: sampleSetSelection, obsSetSelection: obsSetSelection, obsSetColor: obsSetColor, sampleSetColor: sampleSetColor, data: featureStats, featureSelection: featureSelection, setFeatureSelection: setFeatureSelection, featurePointSignificanceThreshold: featurePointSignificanceThreshold, featurePointFoldChangeThreshold: featurePointFoldChangeThreshold })) : (_jsxs("p", { style: { padding: '12px' }, children: ["Select at least one ", obsType, " set."] })) }));
28
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"Treemap.d.ts","sourceRoot":"","sources":["../src/Treemap.js"],"names":[],"mappings":"AAsBA;;;;;;;;GAQG;AACH,yDAkLC"}
1
+ {"version":3,"file":"Treemap.d.ts","sourceRoot":"","sources":["../src/Treemap.js"],"names":[],"mappings":"AAsBA;;;;;;;;GAQG;AACH,yDAoMC"}
@@ -71,6 +71,9 @@ export default function Treemap(props) {
71
71
  const svgRef = useRef();
72
72
  useEffect(() => {
73
73
  const domElement = svgRef.current;
74
+ if (!width || !height) {
75
+ return;
76
+ }
74
77
  const svg = select(domElement);
75
78
  svg.selectAll('g').remove();
76
79
  svg
@@ -78,7 +81,7 @@ export default function Treemap(props) {
78
81
  .attr('height', height)
79
82
  .attr('viewBox', [0, 0, width, height])
80
83
  .attr('style', 'font: 10px sans-serif');
81
- if (!treemapLeaves || !obsSetSelection || !sampleSetSelection) {
84
+ if (!treemapLeaves || !obsSetSelection) {
82
85
  return;
83
86
  }
84
87
  // Add a group for each leaf of the hierarchy.
@@ -130,14 +133,25 @@ export default function Treemap(props) {
130
133
  })
131
134
  .append('use')
132
135
  .attr('xlink:href', d => d.leafUid.href);
136
+ const hasSampleSetSelection = Array.isArray(sampleSetSelection);
133
137
  // Append multiline text.
134
138
  leaf.append('text')
135
139
  .attr('clip-path', d => `url(${d.clipUid.href})`)
136
140
  .selectAll('tspan')
137
141
  .data(d => ([
138
142
  // Each element in this array corresponds to a line of text.
139
- d.data?.[0]?.at(-1),
140
- d.parent?.data?.[0]?.at(-1),
143
+ ...(hasSampleSetSelection
144
+ ? ([
145
+ d.data?.[0]?.at(-1),
146
+ d.parent?.data?.[0]?.at(-1),
147
+ ]) : ([
148
+ // Only use the cell set name
149
+ // for the line of text
150
+ // (since no sample set selection)
151
+ hierarchyLevels[0] === 'obsSet'
152
+ ? d.parent?.data?.[0].at(-1)
153
+ : d.data?.[0].at(-1),
154
+ ])),
141
155
  `${d.data?.[1].toLocaleString()} ${plur(obsType, d.data?.[1])}`,
142
156
  ]))
143
157
  .join('tspan')
@@ -1 +1 @@
1
- {"version":3,"file":"TreemapSubscriber.d.ts","sourceRoot":"","sources":["../src/TreemapSubscriber.js"],"names":[],"mappings":"AAyBA,2DAiPC"}
1
+ {"version":3,"file":"TreemapSubscriber.d.ts","sourceRoot":"","sources":["../src/TreemapSubscriber.js"],"names":[],"mappings":"AAyBA,2DAgQC"}
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /* eslint-disable no-unused-vars */
3
3
  import React, { useMemo, useCallback } from 'react';
4
4
  import { TitleInfo, useCoordination, useLoaders, useUrls, useReady, useGridItemSize, useObsFeatureMatrixIndices, useObsSetsData, useSampleEdgesData, useSampleSetsData, } from '@vitessce/vit-s';
@@ -43,8 +43,6 @@ export function TreemapSubscriber(props) {
43
43
  ]);
44
44
  const mergedObsSets = useMemo(() => mergeObsSets(obsSets, additionalObsSets), [obsSets, additionalObsSets]);
45
45
  const mergedSampleSets = useMemo(() => mergeObsSets(sampleSets, null), [sampleSets]);
46
- const obsCount = obsIndex?.length || 0;
47
- const sampleCount = sampleIndex?.length || 0;
48
46
  // TODO: use obsFilter / sampleFilter to display
49
47
  // _all_ cells/samples in gray / transparent in background,
50
48
  // and use obsSetSelection/sampleSetSelection to display
@@ -66,12 +64,12 @@ export function TreemapSubscriber(props) {
66
64
  obsResult.get(cellSetKey).set(sampleSetKey, 0);
67
65
  });
68
66
  });
69
- const sampleSetSizes = treeToSetSizesBySetNames(mergedSampleSets, sampleSetSelection, sampleSetSelection, sampleSetColor, theme);
67
+ const sampleSetSizes = hasSampleSetSelection ? treeToSetSizesBySetNames(mergedSampleSets, sampleSetSelection, sampleSetSelection, sampleSetColor, theme) : null;
70
68
  sampleSetKeys.forEach((sampleSetKey) => {
71
- const sampleSetSize = sampleSetSizes.find(d => isEqual(d.setNamePath, sampleSetKey))?.size;
69
+ const sampleSetSize = sampleSetSizes?.find(d => isEqual(d.setNamePath, sampleSetKey))?.size;
72
70
  sampleResult.set(sampleSetKey, sampleSetSize || 0);
73
71
  });
74
- if (mergedObsSets && obsSetSelection) {
72
+ if (mergedObsSets && obsSetSelection && obsIndex) {
75
73
  const sampleIdToSetMap = sampleSets && sampleSetSelection
76
74
  ? treeToSelectedSetMap(sampleSets, sampleSetSelection)
77
75
  : null;
@@ -80,7 +78,9 @@ export function TreemapSubscriber(props) {
80
78
  const obsId = obsIndex[i];
81
79
  const cellSet = cellIdToSetMap?.get(obsId);
82
80
  const sampleId = sampleEdges?.get(obsId);
83
- const sampleSet = sampleId ? sampleIdToSetMap?.get(sampleId) : null;
81
+ const sampleSet = sampleId && hasSampleSetSelection
82
+ ? sampleIdToSetMap?.get(sampleId)
83
+ : null;
84
84
  if (hasSampleSetSelection && !sampleSet) {
85
85
  // Skip this sample if it is not in the selected sample set.
86
86
  // eslint-disable-next-line no-continue
@@ -96,11 +96,17 @@ export function TreemapSubscriber(props) {
96
96
  ];
97
97
  }, [obsIndex, sampleEdges, sampleSets, obsSetColor,
98
98
  sampleSetColor, mergedObsSets, obsSetSelection, mergedSampleSets,
99
- sampleSetSelection,
99
+ sampleSetSelection, obsIndex,
100
100
  // TODO: consider filtering-related coordination values
101
101
  ]);
102
+ const totalObsCount = obsIndex?.length || 0;
103
+ const totalSampleCount = sampleIndex?.length || 0;
104
+ const selectedObsCount = obsCounts.reduce((a, h) => a + h.value, 0);
105
+ const selectedSampleCount = sampleCounts.reduce((a, h) => a + h.value, 0);
106
+ const unselectedObsCount = totalObsCount - selectedObsCount;
107
+ const unselectedSampleCount = totalSampleCount - selectedSampleCount;
102
108
  const onNodeClick = useCallback((obsSetPath) => {
103
109
  setObsSetSelection([obsSetPath]);
104
110
  }, [setObsSetSelection]);
105
- return (_jsx(TitleInfo, { title: `Treemap of ${capitalize(plur(obsType, 2))}`, info: `${commaNumber(obsCount)} ${plur(obsType, obsCount)} from ${commaNumber(sampleCount)} ${plur(sampleType, sampleCount)}`, removeGridComponent: removeGridComponent, urls: urls, theme: theme, isReady: isReady, helpText: helpText, options: (_jsx(TreemapOptions, { obsType: obsType, sampleType: sampleType, obsColorEncoding: obsColorEncoding, setObsColorEncoding: setObsColorEncoding, hierarchyLevels: hierarchyLevels || DEFAULT_HIERARCHY_LEVELS, setHierarchyLevels: setHierarchyLevels })), children: _jsx("div", { ref: containerRef, className: classes.vegaContainer, children: _jsx(Treemap, { obsCounts: obsCounts, sampleCounts: sampleCounts, obsColorEncoding: obsColorEncoding, hierarchyLevels: hierarchyLevels || DEFAULT_HIERARCHY_LEVELS, theme: theme, width: width, height: height, obsType: obsType, sampleType: sampleType, obsSetColor: obsSetColor, sampleSetColor: sampleSetColor, obsSetSelection: obsSetSelection, sampleSetSelection: sampleSetSelection, onNodeClick: onNodeClick }) }) }));
111
+ return (_jsxs(TitleInfo, { title: `Treemap of ${capitalize(plur(obsType, 2))}`, info: `${commaNumber(selectedObsCount)} ${plur(obsType, selectedObsCount)} from ${commaNumber(selectedSampleCount)} ${plur(sampleType, selectedSampleCount)}`, removeGridComponent: removeGridComponent, urls: urls, theme: theme, isReady: isReady, helpText: helpText, withPadding: false, options: (_jsx(TreemapOptions, { obsType: obsType, sampleType: sampleType, obsColorEncoding: obsColorEncoding, setObsColorEncoding: setObsColorEncoding, hierarchyLevels: hierarchyLevels || DEFAULT_HIERARCHY_LEVELS, setHierarchyLevels: setHierarchyLevels })), children: [_jsx("div", { ref: containerRef, className: classes.vegaContainer, children: _jsx(Treemap, { obsCounts: obsCounts, sampleCounts: sampleCounts, obsColorEncoding: obsColorEncoding, hierarchyLevels: hierarchyLevels || DEFAULT_HIERARCHY_LEVELS, theme: theme, width: width, height: Math.max(height * (selectedObsCount / totalObsCount), 40), obsType: obsType, sampleType: sampleType, obsSetColor: obsSetColor, sampleSetColor: sampleSetColor, obsSetSelection: obsSetSelection, sampleSetSelection: sampleSetSelection, onNodeClick: onNodeClick }) }), _jsx("div", { style: { position: 'absolute', right: '2px', bottom: '2px', fontSize: '10px' }, children: unselectedObsCount > 0 ? (_jsx("span", { children: `${commaNumber(unselectedObsCount)} ${plur(obsType, unselectedObsCount)} from ${commaNumber(unselectedSampleCount)} ${plur(sampleType, unselectedSampleCount)} currently omitted` })) : null })] }));
106
112
  }
@@ -1 +1 @@
1
- {"version":3,"file":"VolcanoPlot.d.ts","sourceRoot":"","sources":["../src/VolcanoPlot.js"],"names":[],"mappings":"AAYA,6DA+SC"}
1
+ {"version":3,"file":"VolcanoPlot.d.ts","sourceRoot":"","sources":["../src/VolcanoPlot.js"],"names":[],"mappings":"AAWA,6DAgQC"}
@@ -6,21 +6,20 @@ import { scaleLinear } from 'd3-scale';
6
6
  import { axisBottom, axisLeft } from 'd3-axis';
7
7
  import { extent as d3_extent } from 'd3-array';
8
8
  import { select } from 'd3-selection';
9
- import { isEqual } from 'lodash-es';
10
9
  import { capitalize, getDefaultForegroundColor } from '@vitessce/utils';
11
10
  import { colorArrayToString } from '@vitessce/sets-utils';
12
- import { getColorScale } from './utils.js';
11
+ import { getColorScale, useFilteredVolcanoData } from './utils.js';
13
12
  export default function VolcanoPlot(props) {
14
- const { theme, width, height, obsType, featureType, obsSetsColumnNameMapping, sampleSetsColumnNameMapping, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, data, marginTop = 5, marginRight = 5, marginLeft = 50, marginBottom = 50, onFeatureClick, featurePointSignificanceThreshold, featurePointFoldChangeThreshold, featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold, } = props;
13
+ const { theme, width, height, obsType, featureType, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, data, marginTop = 5, marginRight = 5, marginLeft = 50, marginBottom = 50, onFeatureClick, featurePointSignificanceThreshold, featurePointFoldChangeThreshold, featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold, } = props;
15
14
  const svgRef = useRef();
16
- const computedData = useMemo(() => data.map(d => ({
17
- ...d,
18
- df: {
19
- ...d.df,
20
- minusLog10p: d.df.featureSignificance.map(v => -Math.log10(v)),
21
- logFoldChange: d.df.featureFoldChange.map(v => Math.log2(v)),
22
- },
23
- })), [data]);
15
+ const [computedData, filteredData] = useFilteredVolcanoData({
16
+ data,
17
+ obsSetsColumnNameMappingReversed,
18
+ sampleSetsColumnNameMappingReversed,
19
+ featurePointFoldChangeThreshold,
20
+ featurePointSignificanceThreshold,
21
+ sampleSetSelection,
22
+ });
24
23
  const [xExtent, yExtent] = useMemo(() => {
25
24
  if (!computedData) {
26
25
  return [null, null];
@@ -44,7 +43,7 @@ export default function VolcanoPlot(props) {
44
43
  .attr('height', height)
45
44
  .attr('viewBox', [0, 0, width, height])
46
45
  .attr('style', 'font: 10px sans-serif');
47
- if (!computedData || !xExtent || !yExtent) {
46
+ if (!filteredData || !xExtent || !yExtent) {
48
47
  return;
49
48
  }
50
49
  // Render scatterplot
@@ -89,13 +88,6 @@ export default function VolcanoPlot(props) {
89
88
  .text('log2 fold-change')
90
89
  .style('font-size', '12px')
91
90
  .style('fill', fgColor);
92
- // Get a mapping from column name to group name.
93
- const obsSetsColumnNameMappingReversed = Object.fromEntries(Object
94
- .entries(obsSetsColumnNameMapping)
95
- .map(([key, value]) => ([value, key])));
96
- const sampleSetsColumnNameMappingReversed = Object.fromEntries(Object
97
- .entries(sampleSetsColumnNameMapping)
98
- .map(([key, value]) => ([value, key])));
99
91
  // Horizontal and vertical rules to indicate currently-selected thresholds
100
92
  // Vertical lines
101
93
  const ruleColor = 'silver';
@@ -150,39 +142,15 @@ export default function VolcanoPlot(props) {
150
142
  .style('fill', fgColor);
151
143
  const g = svg.append('g');
152
144
  // Append a circle for each data point.
153
- computedData.forEach((comparisonObject) => {
145
+ filteredData.forEach((comparisonObject) => {
154
146
  const obsSetG = g.append('g');
155
- const { df, metadata } = comparisonObject;
147
+ const { df: filteredDf, metadata } = comparisonObject;
156
148
  const coordinationValues = metadata.coordination_values;
157
149
  const rawObsSetPath = coordinationValues.obsSetFilter
158
150
  ? coordinationValues.obsSetFilter[0]
159
151
  : coordinationValues.obsSetSelection[0];
160
152
  const obsSetPath = [...rawObsSetPath];
161
153
  obsSetPath[0] = obsSetsColumnNameMappingReversed[rawObsSetPath[0]];
162
- // Swap the foldchange direction if backwards with
163
- // respect to the current sampleSetSelection pair.
164
- // TODO: move this swapping into the computedData useMemo?
165
- let shouldSwapFoldChangeDirection = false;
166
- if (coordinationValues.sampleSetFilter
167
- && coordinationValues.sampleSetFilter.length === 2) {
168
- const rawSampleSetPathA = coordinationValues.sampleSetFilter[0];
169
- const sampleSetPathA = [...rawSampleSetPathA];
170
- sampleSetPathA[0] = sampleSetsColumnNameMappingReversed[rawSampleSetPathA[0]];
171
- const rawSampleSetPathB = coordinationValues.sampleSetFilter[1];
172
- const sampleSetPathB = [...rawSampleSetPathB];
173
- sampleSetPathB[0] = sampleSetsColumnNameMappingReversed[rawSampleSetPathB[0]];
174
- if (isEqual(sampleSetPathA, sampleSetSelection[1])
175
- && isEqual(sampleSetPathB, sampleSetSelection[0])) {
176
- shouldSwapFoldChangeDirection = true;
177
- }
178
- }
179
- const filteredDf = df.featureId.map((featureId, i) => ({
180
- featureId,
181
- logFoldChange: df.logFoldChange[i] * (shouldSwapFoldChangeDirection ? -1 : 1),
182
- featureSignificance: df.featureSignificance[i],
183
- minusLog10p: df.minusLog10p[i],
184
- })).filter(d => ((Math.abs(d.logFoldChange) >= (featurePointFoldChangeThreshold ?? 1.0))
185
- && (d.featureSignificance <= (featurePointSignificanceThreshold ?? 0.05))));
186
154
  const color = obsSetColorScale(obsSetPath);
187
155
  obsSetG.append('g')
188
156
  .selectAll('circle')
@@ -214,12 +182,13 @@ export default function VolcanoPlot(props) {
214
182
  .text(d => `${featureType}: ${d.featureId}\nin ${obsSetPath?.at(-1)}\nlog2 fold-change: ${d.logFoldChange}\np-value: ${d.featureSignificance}`);
215
183
  });
216
184
  }, [width, height, theme, sampleSetColor, sampleSetSelection,
217
- obsSetSelection, obsSetColor, featureType, computedData,
185
+ obsSetSelection, obsSetColor, featureType, filteredData,
218
186
  xExtent, yExtent, obsType,
219
187
  marginLeft, marginBottom, marginTop, marginRight,
220
188
  obsSetColorScale, sampleSetColorScale, onFeatureClick,
221
189
  featurePointSignificanceThreshold, featurePointFoldChangeThreshold,
222
190
  featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold,
191
+ obsSetsColumnNameMappingReversed,
223
192
  ]);
224
193
  return (_jsx("svg", { ref: svgRef, style: {
225
194
  top: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"VolcanoPlotSubscriber.d.ts","sourceRoot":"","sources":["../src/VolcanoPlotSubscriber.js"],"names":[],"mappings":"AAuBA,+DA0IC"}
1
+ {"version":3,"file":"VolcanoPlotSubscriber.d.ts","sourceRoot":"","sources":["../src/VolcanoPlotSubscriber.js"],"names":[],"mappings":"AAuBA,+DA+IC"}
@@ -8,7 +8,7 @@ import { useStyles } from './styles.js';
8
8
  import VolcanoPlotOptions from './VolcanoPlotOptions.js';
9
9
  import { useRawSetPaths } from './utils.js';
10
10
  export function VolcanoPlotSubscriber(props) {
11
- const { coordinationScopes, removeGridComponent, theme, helpText = ViewHelpMapping.VOLCANO_PLOT, } = props;
11
+ const { title = 'Volcano Plot', coordinationScopes, removeGridComponent, theme, helpText = ViewHelpMapping.VOLCANO_PLOT, } = props;
12
12
  const classes = useStyles();
13
13
  const loaders = useLoaders();
14
14
  // Get "props" from the coordination space.
@@ -17,7 +17,9 @@ export function VolcanoPlotSubscriber(props) {
17
17
  const obsSetsLoader = useMatchingLoader(loaders, dataset, DataType.OBS_SETS, { obsType });
18
18
  const sampleSetsLoader = useMatchingLoader(loaders, dataset, DataType.SAMPLE_SETS, { sampleType });
19
19
  const obsSetsColumnNameMapping = useColumnNameMapping(obsSetsLoader);
20
+ const obsSetsColumnNameMappingReversed = useColumnNameMapping(obsSetsLoader, true);
20
21
  const sampleSetsColumnNameMapping = useColumnNameMapping(sampleSetsLoader);
22
+ const sampleSetsColumnNameMappingReversed = useColumnNameMapping(sampleSetsLoader, true);
21
23
  const rawSampleSetSelection = useRawSetPaths(sampleSetsColumnNameMapping, sampleSetSelection);
22
24
  const rawObsSetSelection = useRawSetPaths(obsSetsColumnNameMapping, obsSetSelection);
23
25
  const [{ featureStats }, featureStatsStatus] = useFeatureStatsData(loaders, dataset, false, { obsType, featureType, sampleType },
@@ -29,5 +31,5 @@ export function VolcanoPlotSubscriber(props) {
29
31
  const onFeatureClick = useCallback((featureId) => {
30
32
  setFeatureSelection([featureId]);
31
33
  }, [setFeatureSelection]);
32
- return (_jsx(TitleInfo, { title: "Volcano Plot", removeGridComponent: removeGridComponent, theme: theme, isReady: isReady, helpText: helpText, options: (_jsx(VolcanoPlotOptions, { obsType: obsType, featureType: featureType, featurePointSignificanceThreshold: featurePointSignificanceThreshold, featurePointFoldChangeThreshold: featurePointFoldChangeThreshold, featureLabelSignificanceThreshold: featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold: featureLabelFoldChangeThreshold, setFeaturePointSignificanceThreshold: setFeaturePointSignificanceThreshold, setFeaturePointFoldChangeThreshold: setFeaturePointFoldChangeThreshold, setFeatureLabelSignificanceThreshold: setFeatureLabelSignificanceThreshold, setFeatureLabelFoldChangeThreshold: setFeatureLabelFoldChangeThreshold })), children: _jsx("div", { ref: containerRef, className: classes.vegaContainer, children: featureStats ? (_jsx(VolcanoPlot, { theme: theme, width: width, height: height, obsType: obsType, featureType: featureType, obsSetsColumnNameMapping: obsSetsColumnNameMapping, sampleSetsColumnNameMapping: sampleSetsColumnNameMapping, sampleSetSelection: sampleSetSelection, obsSetSelection: obsSetSelection, obsSetColor: obsSetColor, sampleSetColor: sampleSetColor, data: featureStats, onFeatureClick: onFeatureClick, featurePointSignificanceThreshold: featurePointSignificanceThreshold, featurePointFoldChangeThreshold: featurePointFoldChangeThreshold, featureLabelSignificanceThreshold: featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold: featureLabelFoldChangeThreshold })) : (_jsxs("span", { children: ["Select at least one ", obsType, " set."] })) }) }));
34
+ return (_jsx(TitleInfo, { title: title, removeGridComponent: removeGridComponent, theme: theme, isReady: isReady, helpText: helpText, options: (_jsx(VolcanoPlotOptions, { obsType: obsType, featureType: featureType, featurePointSignificanceThreshold: featurePointSignificanceThreshold, featurePointFoldChangeThreshold: featurePointFoldChangeThreshold, featureLabelSignificanceThreshold: featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold: featureLabelFoldChangeThreshold, setFeaturePointSignificanceThreshold: setFeaturePointSignificanceThreshold, setFeaturePointFoldChangeThreshold: setFeaturePointFoldChangeThreshold, setFeatureLabelSignificanceThreshold: setFeatureLabelSignificanceThreshold, setFeatureLabelFoldChangeThreshold: setFeatureLabelFoldChangeThreshold })), children: _jsx("div", { ref: containerRef, className: classes.vegaContainer, children: featureStats ? (_jsx(VolcanoPlot, { theme: theme, width: width, height: height, obsType: obsType, featureType: featureType, obsSetsColumnNameMapping: obsSetsColumnNameMapping, obsSetsColumnNameMappingReversed: obsSetsColumnNameMappingReversed, sampleSetsColumnNameMapping: sampleSetsColumnNameMapping, sampleSetsColumnNameMappingReversed: sampleSetsColumnNameMappingReversed, sampleSetSelection: sampleSetSelection, obsSetSelection: obsSetSelection, obsSetColor: obsSetColor, sampleSetColor: sampleSetColor, data: featureStats, onFeatureClick: onFeatureClick, featurePointSignificanceThreshold: featurePointSignificanceThreshold, featurePointFoldChangeThreshold: featurePointFoldChangeThreshold, featureLabelSignificanceThreshold: featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold: featureLabelFoldChangeThreshold })) : (_jsxs("span", { children: ["Select at least one ", obsType, " set."] })) }) }));
33
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"expr-hooks.d.ts","sourceRoot":"","sources":["../src/expr-hooks.js"],"names":[],"mappings":"AAiDA;;;;;;GAMG;AACH,8DAJW,GAAC,gBACD,GAAC,OA4BX;AAED;;;;;;GAMG;AACH,oEAJW,GAAC,aACD,GAAC,OAkBX;AAED;;;;;;;;GAQG;AACH,oEALW,GAAC,YACD,GAAC,YACD,GAAC;;;;;;;;;;;;;;;;;;;;;;;;EA4DX"}
1
+ {"version":3,"file":"expr-hooks.d.ts","sourceRoot":"","sources":["../src/expr-hooks.js"],"names":[],"mappings":"AAiDA;;;;;;GAMG;AACH,8DAJW,GAAC,gBACD,GAAC,OA4BX;AAED;;;;;;GAMG;AACH,oEAJW,GAAC,aACD,GAAC,OAiBX;AAED;;;;;;;;GAQG;AACH,oEALW,GAAC,YACD,GAAC,YACD,GAAC;;;;;;;;;;;;;;;;;;;;;;;;EA4DX"}
@@ -70,8 +70,9 @@ describe('Utility functions for processing expression data for statistical plots
70
70
  ];
71
71
  const featureValueTransform = null;
72
72
  const featureValueTransformCoefficient = 1;
73
+ const featureAggregationStrategy = 'first';
73
74
  const [result] = stratifyExpressionData(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, mergedCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient);
74
- const aggregateData = aggregateStratifiedExpressionData(result, geneSelection);
75
+ const aggregateData = aggregateStratifiedExpressionData(result, geneSelection, featureAggregationStrategy);
75
76
  const summaryResult = summarizeStratifiedExpressionData(aggregateData, true);
76
77
  expect(Array.from(summaryResult.keys())).toEqual([['Cell type', 'T cell'], ['Cell type', 'B cell']]);
77
78
  expect(Array.from(summaryResult.get(['Cell type', 'T cell']).keys())).toEqual([['Clinical groups', 'AKI'], ['Clinical groups', 'CKD']]);
@@ -7,6 +7,7 @@ export { TreemapSubscriber } from "./TreemapSubscriber.js";
7
7
  export { VolcanoPlotSubscriber } from "./VolcanoPlotSubscriber.js";
8
8
  export { CellSetCompositionBarPlotSubscriber } from "./CellSetCompositionBarPlotSubscriber.js";
9
9
  export { FeatureSetEnrichmentBarPlotSubscriber } from "./FeatureSetEnrichmentBarPlotSubscriber.js";
10
+ export { FeatureStatsTableSubscriber } from "./FeatureStatsTableSubscriber.js";
10
11
  export { default as CellSetSizesPlot } from "./CellSetSizesPlot.js";
11
12
  export { default as CellSetExpressionPlot } from "./CellSetExpressionPlot.js";
12
13
  export { default as ExpressionHistogram } from "./ExpressionHistogram.js";
package/dist-tsc/index.js CHANGED
@@ -7,6 +7,7 @@ export { TreemapSubscriber } from './TreemapSubscriber.js';
7
7
  export { VolcanoPlotSubscriber } from './VolcanoPlotSubscriber.js';
8
8
  export { CellSetCompositionBarPlotSubscriber } from './CellSetCompositionBarPlotSubscriber.js';
9
9
  export { FeatureSetEnrichmentBarPlotSubscriber } from './FeatureSetEnrichmentBarPlotSubscriber.js';
10
+ export { FeatureStatsTableSubscriber } from './FeatureStatsTableSubscriber.js';
10
11
  export { default as CellSetSizesPlot } from './CellSetSizesPlot.js';
11
12
  export { default as CellSetExpressionPlot } from './CellSetExpressionPlot.js';
12
13
  export { default as ExpressionHistogram } from './ExpressionHistogram.js';
@@ -6,4 +6,5 @@ export function getColorScale(setSelectionArr: any, setColorArr: any, theme: any
6
6
  * @returns {string[][]} Transformed set paths.
7
7
  */
8
8
  export function useRawSetPaths(columnNameMapping: Record<string, string>, setPaths: string[][]): string[][];
9
+ export function useFilteredVolcanoData(props: any): any[];
9
10
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.js"],"names":[],"mappings":"AAcA,0GAeC;AAGD;;;;;GAKG;AACH,kDAJW,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YACtB,MAAM,EAAE,EAAE,GACR,MAAM,EAAE,EAAE,CAUtB"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.js"],"names":[],"mappings":"AAcA,0GAeC;AAGD;;;;;GAKG;AACH,kDAJW,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YACtB,MAAM,EAAE,EAAE,GACR,MAAM,EAAE,EAAE,CAUtB;AAID,0DA6EC"}
package/dist-tsc/utils.js CHANGED
@@ -1,3 +1,4 @@
1
+ /* eslint-disable camelcase */
1
2
  import { useMemo } from 'react';
2
3
  import { isEqual } from 'lodash-es';
3
4
  import { colorArrayToString } from '@vitessce/sets-utils';
@@ -38,3 +39,58 @@ export function useRawSetPaths(columnNameMapping, setPaths) {
38
39
  return newSetPath;
39
40
  }), [columnNameMapping, setPaths]);
40
41
  }
42
+ // Data transformation hook function that is used both here
43
+ // and in the FeatureStatsTable view.
44
+ export function useFilteredVolcanoData(props) {
45
+ const { data, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, featurePointFoldChangeThreshold, featurePointSignificanceThreshold, sampleSetSelection, } = props;
46
+ const computedData = useMemo(() => data.map((d) => {
47
+ const { metadata } = d;
48
+ const coordinationValues = metadata.coordination_values;
49
+ const rawObsSetPath = coordinationValues.obsSetFilter
50
+ ? coordinationValues.obsSetFilter[0]
51
+ : coordinationValues.obsSetSelection[0];
52
+ const obsSetPath = [...rawObsSetPath];
53
+ obsSetPath[0] = obsSetsColumnNameMappingReversed[rawObsSetPath[0]];
54
+ // Swap the foldchange direction if backwards with
55
+ // respect to the current sampleSetSelection pair.
56
+ // TODO: move this swapping into the computedData useMemo?
57
+ let shouldSwapFoldChangeDirection = false;
58
+ if (coordinationValues.sampleSetFilter
59
+ && coordinationValues.sampleSetFilter.length === 2) {
60
+ const rawSampleSetPathA = coordinationValues.sampleSetFilter[0];
61
+ const sampleSetPathA = [...rawSampleSetPathA];
62
+ sampleSetPathA[0] = sampleSetsColumnNameMappingReversed[rawSampleSetPathA[0]];
63
+ const rawSampleSetPathB = coordinationValues.sampleSetFilter[1];
64
+ const sampleSetPathB = [...rawSampleSetPathB];
65
+ sampleSetPathB[0] = sampleSetsColumnNameMappingReversed[rawSampleSetPathB[0]];
66
+ if (isEqual(sampleSetPathA, sampleSetSelection[1])
67
+ && isEqual(sampleSetPathB, sampleSetSelection[0])) {
68
+ shouldSwapFoldChangeDirection = true;
69
+ }
70
+ }
71
+ return ({
72
+ ...d,
73
+ df: {
74
+ ...d.df,
75
+ minusLog10p: d.df.featureSignificance.map(v => -Math.log10(v)),
76
+ logFoldChange: d.df.featureFoldChange.map(v => (Math.log2(v) * (shouldSwapFoldChangeDirection ? -1 : 1))),
77
+ },
78
+ });
79
+ }), [
80
+ data, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed,
81
+ sampleSetSelection,
82
+ ]);
83
+ const filteredData = useMemo(() => computedData.map(obj => ({
84
+ ...obj,
85
+ // Instead of an object of one array per column,
86
+ // this is now an array of one object per row.
87
+ df: obj.df.featureId.map((featureId, i) => ({
88
+ featureId,
89
+ logFoldChange: obj.df.logFoldChange[i],
90
+ featureSignificance: obj.df.featureSignificance[i],
91
+ minusLog10p: obj.df.minusLog10p[i],
92
+ })).filter(d => ((Math.abs(d.logFoldChange) >= (featurePointFoldChangeThreshold ?? 1.0))
93
+ && (d.featureSignificance <= (featurePointSignificanceThreshold ?? 0.05)))),
94
+ })), [computedData, featurePointFoldChangeThreshold, featurePointSignificanceThreshold]);
95
+ return [computedData, filteredData];
96
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitessce/statistical-plots",
3
- "version": "3.5.9",
3
+ "version": "3.5.11",
4
4
  "author": "HIDIVE Lab at HMS",
5
5
  "homepage": "http://vitessce.io",
6
6
  "repository": {
@@ -17,6 +17,7 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "@material-ui/core": "~4.12.3",
20
+ "@mui/x-data-grid": "^4.0.2",
20
21
  "d3-array": "^2.4.0",
21
22
  "d3-scale": "^4.0.0",
22
23
  "d3-shape": "^3.2.0",
@@ -29,12 +30,12 @@
29
30
  "react-aria": "^3.28.0",
30
31
  "internmap": "^2.0.3",
31
32
  "uuid": "^9.0.0",
32
- "@vitessce/constants-internal": "3.5.9",
33
- "@vitessce/sets-utils": "3.5.9",
34
- "@vitessce/utils": "3.5.9",
35
- "@vitessce/vega": "3.5.9",
36
- "@vitessce/vit-s": "3.5.9",
37
- "@vitessce/gl": "3.5.9"
33
+ "@vitessce/constants-internal": "3.5.11",
34
+ "@vitessce/sets-utils": "3.5.11",
35
+ "@vitessce/utils": "3.5.11",
36
+ "@vitessce/vega": "3.5.11",
37
+ "@vitessce/vit-s": "3.5.11",
38
+ "@vitessce/gl": "3.5.11"
38
39
  },
39
40
  "devDependencies": {
40
41
  "react": "^18.0.0",