@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
package/dist/index.js CHANGED
@@ -1,19 +1,20 @@
1
- import { b, e, C, d, a, h, D, f, E, F, c, T, V } from "./index-dc733355.js";
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
- e as CellSetExpressionPlot,
7
+ f as CellSetExpressionPlot,
8
8
  C as CellSetExpressionPlotSubscriber,
9
- d as CellSetSizesPlot,
9
+ e as CellSetSizesPlot,
10
10
  a as CellSetSizesPlotSubscriber,
11
- h as DotPlot,
11
+ i as DotPlot,
12
12
  D as DotPlotSubscriber,
13
- f as ExpressionHistogram,
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,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-dc733355.js";
1
+ import { B as BaseDecoder } from "./index-134a71c6.js";
2
2
  import "react";
3
3
  import "@vitessce/vit-s";
4
4
  import "react-dom";
@@ -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-dc733355.js";
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,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-dc733355.js";
1
+ import { B as BaseDecoder } from "./index-134a71c6.js";
2
2
  import "react";
3
3
  import "@vitessce/vit-s";
4
4
  import "react-dom";
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-dc733355.js";
1
+ import { B as BaseDecoder } from "./index-134a71c6.js";
2
2
  import "react";
3
3
  import "@vitessce/vit-s";
4
4
  import "react-dom";
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-dc733355.js";
1
+ import { B as BaseDecoder } from "./index-134a71c6.js";
2
2
  import "react";
3
3
  import "@vitessce/vit-s";
4
4
  import "react-dom";
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-dc733355.js";
1
+ import { B as BaseDecoder } from "./index-134a71c6.js";
2
2
  import "react";
3
3
  import "@vitessce/vit-s";
4
4
  import "react-dom";
@@ -1 +1 @@
1
- {"version":3,"file":"CellSetCompositionBarPlot.d.ts","sourceRoot":"","sources":["../src/CellSetCompositionBarPlot.js"],"names":[],"mappings":"AAOA;;GAEG;AACH,2EAkMC"}
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 = 120, keyLength = 36, obsType, onBarSelect, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, } = props;
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
- // See https://github.com/keller-mark/compasce/issues/30 which should simplify this logic once implemented,
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(firstCovariateSetPath, sampleSetSelection[0])) {
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.map(d => d.keyName);
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.map(d => d.key),
77
- range: computedData.map(d => d.color),
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":"AAaA;;;;;;;;;;;;;;;;;;;;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,eA0XA"}
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, cellSetSelection, sampleSetSelection, sampleSetColor, colors, data, theme, width, height, marginTop = 5, marginRight = 5, marginLeft = 50, marginBottom, obsType, featureType, featureValueType, featureValueTransformName, } = props;
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 (!cellSetSelection) {
41
+ if (!obsSetSelection) {
40
42
  return 0;
41
43
  }
42
- const cellSetNames = cellSetSelection.map(d => d.at(-1));
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
- }, [cellSetSelection]);
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(cellSetSelection)
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
- .call(axisBottom(xGroup).tickFormat(d => d.at(-1)))
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":"AAMA,8EAwIC"}
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
- const handleTransformChange = (event) => {
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}` }) })] }), 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] }));
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":"AAmGA;;;;;;;;;GASG;AACH,uDALG;IAAwB,mBAAmB;IACrB,kBAAkB,EAAhC,MAAM;IAEQ,KAAK,EAAnB,MAAM;CAChB,eAoKA"}
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 [histogramData, setArr, exprMax] = useExpressionByCellSet(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, cellSets, additionalCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient, theme, yMin);
101
- const firstGeneSelected = geneSelection && geneSelection.length >= 1
102
- ? (featureLabelsMap?.get(geneSelection[0])
103
- || featureLabelsMap?.get(cleanFeatureId(geneSelection[0]))
104
- || geneSelection[0])
105
- : null;
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
- return (_jsx(TitleInfo, { title: `Expression by ${capitalize(obsType)} Set${(firstGeneSelected ? ` (${firstGeneSelected})` : '')}`, 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 })), children: _jsx("div", { ref: containerRef, className: classes.vegaContainer, children: histogramData ? (_jsx(CellSetExpressionPlot, { yMin: yMin, yUnits: yUnits, jitter: jitter, cellSetSelection: cellSetSelection, sampleSetSelection: sampleSetSelection, sampleSetColor: sampleSetColor, colors: setArr, data: histogramData, exprMax: exprMax, theme: theme, width: width, height: height, obsType: obsType, featureType: featureType, featureValueType: featureValueType, featureValueTransformName: selectedTransformName })) : (_jsxs("span", { children: ["Select a ", featureType, "."] })) }) }));
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":"AAKA;;;;;;;;;;;;;;;;;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,eAwJA"}
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"}
@@ -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, featureValueColormap, cellSetSelection, } = props;
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) / (cellSetSelection?.length || 1)
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) / (cellSetSelection?.length || 1);
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
- return (_jsx(VegaPlot, { data: data, spec: spec }));
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,eAoJA"}
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, cellSetSelection: cellSetSelection })) : (_jsxs("span", { children: ["Select at least one ", featureType, "."] })) }) }));
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,6EAgMC"}
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 = 200, marginBottom = 120, keyLength = 36, featureType, onBarSelect, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, pValueThreshold, } = props;
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 = 25;
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.obsSetPath);
148
+ onBarSelect(value.name?.[0], value.term?.[0]);
149
149
  }
150
150
  else if (name === 'shift_bar_select') {
151
- onBarSelect(value.obsSetPath, true);
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 };