diff --git a/client/src/components/categorical/category/index.js b/client/src/components/categorical/category/index.js
index d8366104..af8daba0 100644
--- a/client/src/components/categorical/category/index.js
+++ b/client/src/components/categorical/category/index.js
@@ -44,6 +44,8 @@ const LABEL_WIDTH_ANNO = LABEL_WIDTH - ANNO_BUTTON_WIDTH;
schema,
crossfilter: state.obsCrossfilter,
isUserAnno,
+ genesets: state.genesets.genesets,
+ differential: state.differential,
};
})
class Category extends React.PureComponent {
@@ -142,9 +144,16 @@ class Category extends React.PureComponent {
*/
const { schema } = annoMatrix;
const { colorAccessor, colorMode } = colors;
+ const { genesets, differential } = this.props;
let colorDataPromise = Promise.resolve(null);
if (colorAccessor) {
- const query = createColorQuery(colorMode, colorAccessor, schema);
+ const query = createColorQuery(
+ colorMode,
+ colorAccessor,
+ schema,
+ genesets,
+ differential.diffExp
+ );
if (query) colorDataPromise = annoMatrix.fetch(...query);
}
const [categoryData, colorData] = await Promise.all([
diff --git a/client/src/components/continuousLegend/index.js b/client/src/components/continuousLegend/index.js
index 5087ab59..da2746f2 100644
--- a/client/src/components/continuousLegend/index.js
+++ b/client/src/components/continuousLegend/index.js
@@ -106,16 +106,26 @@ const continuous = (selectorId, colorScale, colorAccessor) => {
@connect((state) => ({
annoMatrix: state.annoMatrix,
colors: state.colors,
+ genesets: state.genesets.genesets,
+ differential: state.differential,
}))
class ContinuousLegend extends React.Component {
async componentDidUpdate(prevProps) {
- const { annoMatrix, colors } = this.props;
+ const { annoMatrix, colors, genesets, differential } = this.props;
if (!colors || !annoMatrix) return;
if (colors !== prevProps?.colors || annoMatrix !== prevProps?.annoMatrix) {
const { schema } = annoMatrix;
const { colorMode, colorAccessor, userColors } = colors;
- const colorQuery = createColorQuery(colorMode, colorAccessor, schema);
+
+ const colorQuery = createColorQuery(
+ colorMode,
+ colorAccessor,
+ schema,
+ genesets,
+ differential.diffExp
+ );
+
const colorDf = colorQuery ? await annoMatrix.fetch(...colorQuery) : null;
const colorTable = createColorTable(
colorMode,
diff --git a/client/src/components/geneExpression/geneSet.js b/client/src/components/geneExpression/geneSet.js
index 39ab5ef8..23614a87 100644
--- a/client/src/components/geneExpression/geneSet.js
+++ b/client/src/components/geneExpression/geneSet.js
@@ -184,7 +184,12 @@ class GeneSet extends React.Component {
)}
-
+
diff --git a/client/src/components/geneExpression/menus/genesetMenus.js b/client/src/components/geneExpression/menus/genesetMenus.js
index 129098d6..9082ed68 100644
--- a/client/src/components/geneExpression/menus/genesetMenus.js
+++ b/client/src/components/geneExpression/menus/genesetMenus.js
@@ -1,12 +1,14 @@
import React from "react";
import { connect } from "react-redux";
+import { Tooltip2 } from "@blueprintjs/popover2";
+
import {
Button,
+ AnchorButton,
Menu,
MenuItem,
Popover,
Position,
- Tooltip,
Icon,
PopoverInteractionKind,
} from "@blueprintjs/core";
@@ -18,6 +20,7 @@ import AddGeneToGenesetDialogue from "./addGeneToGenesetDialogue";
@connect((state) => {
return {
genesetsUI: state.genesetsUI,
+ colorAccessor: state.colors.colorAccessor,
};
})
class GenesetMenus extends React.PureComponent {
@@ -43,19 +46,41 @@ class GenesetMenus extends React.PureComponent {
});
};
+ handleColorByEntireGeneset = () => {
+ const { dispatch, geneset } = this.props;
+
+ dispatch({
+ type: "color by geneset mean expression",
+ geneset,
+ });
+ };
+
handleDeleteCategory = () => {
const { dispatch, geneset } = this.props;
dispatch(actions.genesetDelete(geneset));
};
render() {
- const { geneset, genesetsEditable, createText } = this.props;
+ const {
+ geneset,
+ genesetsEditable,
+ createText,
+ colorAccessor,
+ isOpen,
+ toggleSummaryHisto,
+ } = this.props;
+
+ const isColorBy = geneset === colorAccessor;
+ const genesetClosed = !isOpen;
+ const showingAllGenes = !toggleSummaryHisto;
+
+ const notShowingSummary = genesetClosed || showingAllGenes;
return (
<>
- {genesetsEditable ? (
+ {genesetsEditable && (
<>
-
-
+
- }
- />
+
+ }
+ />
+
>
- ) : null}
+ )}
>
);
}
diff --git a/client/src/components/graph/graph.js b/client/src/components/graph/graph.js
index 86ccc2b3..94ed820e 100644
--- a/client/src/components/graph/graph.js
+++ b/client/src/components/graph/graph.js
@@ -76,6 +76,8 @@ function createModelTF() {
graphInteractionMode: state.controls.graphInteractionMode,
colors: state.colors,
pointDilation: state.pointDilation,
+ genesets: state.genesets.genesets,
+ differential: state.differential,
}))
class Graph extends React.Component {
static createReglState(canvas) {
@@ -526,6 +528,7 @@ class Graph extends React.Component {
colorsProp,
pointDilation
);
+
const { currentDimNames } = layoutChoice;
const X = layoutDf.col(currentDimNames[0]).asArray();
const Y = layoutDf.col(currentDimNames[1]).asArray();
@@ -782,10 +785,17 @@ class Graph extends React.Component {
}
createColorByQuery(colors) {
- const { annoMatrix } = this.props;
+ const { annoMatrix, genesets, differential } = this.props;
const { schema } = annoMatrix;
const { colorMode, colorAccessor } = colors;
- return createColorQuery(colorMode, colorAccessor, schema);
+
+ return createColorQuery(
+ colorMode,
+ colorAccessor,
+ schema,
+ genesets,
+ differential.diffExp
+ );
}
renderPoints(
diff --git a/client/src/components/graph/overlays/centroidLabels.js b/client/src/components/graph/overlays/centroidLabels.js
index 65f22215..21427b25 100644
--- a/client/src/components/graph/overlays/centroidLabels.js
+++ b/client/src/components/graph/overlays/centroidLabels.js
@@ -14,6 +14,8 @@ export default
dilatedValue: state.pointDilation.categoryField,
categoricalSelection: state.categoricalSelection,
showLabels: state.centroidLabels?.showLabels,
+ genesets: state.genesets.genesets,
+ differential: state.differential,
}))
class CentroidLabels extends PureComponent {
static watchAsync(props, prevProps) {
@@ -74,10 +76,16 @@ class CentroidLabels extends PureComponent {
};
colorByQuery() {
- const { annoMatrix, colors } = this.props;
+ const { annoMatrix, colors, genesets, differential } = this.props;
const { schema } = annoMatrix;
const { colorMode, colorAccessor } = colors;
- return createColorQuery(colorMode, colorAccessor, schema);
+ return createColorQuery(
+ colorMode,
+ colorAccessor,
+ schema,
+ genesets,
+ differential.diffExp
+ );
}
async fetchData() {
diff --git a/client/src/components/scatterplot/scatterplot.js b/client/src/components/scatterplot/scatterplot.js
index b70fd4ae..6aa94b24 100644
--- a/client/src/components/scatterplot/scatterplot.js
+++ b/client/src/components/scatterplot/scatterplot.js
@@ -53,6 +53,7 @@ const getYScale = memoize(getScale);
differential: state.differential,
crossfilter,
+ genesets: state.genesets.genesets,
};
})
class Scatterplot extends React.PureComponent {
@@ -313,10 +314,16 @@ class Scatterplot extends React.PureComponent {
}
createColorByQuery(colors) {
- const { annoMatrix } = this.props;
+ const { annoMatrix, genesets, differential } = this.props;
const { schema } = annoMatrix;
const { colorMode, colorAccessor } = colors;
- return createColorQuery(colorMode, colorAccessor, schema);
+ return createColorQuery(
+ colorMode,
+ colorAccessor,
+ schema,
+ genesets,
+ differential
+ );
}
updateColorTable(colors, colorDf) {
diff --git a/client/src/reducers/colors.js b/client/src/reducers/colors.js
index a95b51ce..39d021a1 100644
--- a/client/src/reducers/colors.js
+++ b/client/src/reducers/colors.js
@@ -4,8 +4,8 @@ Color By UI state
const ColorsReducer = (
state = {
- colorMode: null,
- colorAccessor: null,
+ colorMode: null /* by continuous, by expression */,
+ colorAccessor: null /* tissue, Apod */,
},
action,
nextSharedState,
@@ -96,6 +96,21 @@ const ColorsReducer = (
};
}
+ case "color by geneset mean expression": {
+ /* toggle between this mode and reset */
+ const resetCurrent =
+ action.type === state.colorMode &&
+ action.geneset === state.colorAccessor;
+ const colorMode = !resetCurrent ? action.type : null;
+ const colorAccessor = !resetCurrent ? action.geneset : null;
+
+ return {
+ ...state,
+ colorMode,
+ colorAccessor,
+ };
+ }
+
default: {
return state;
}
diff --git a/client/src/reducers/undoableConfig.js b/client/src/reducers/undoableConfig.js
index e1907c3a..d18270ad 100644
--- a/client/src/reducers/undoableConfig.js
+++ b/client/src/reducers/undoableConfig.js
@@ -80,6 +80,7 @@ const saveOnActions = new Set([
"color by categorical metadata",
"color by continuous metadata",
"color by expression",
+ "color by geneset mean expression",
"show centroid labels for category",
diff --git a/client/src/util/stateManager/colorHelpers.js b/client/src/util/stateManager/colorHelpers.js
index 4692d48c..c931e77a 100644
--- a/client/src/util/stateManager/colorHelpers.js
+++ b/client/src/util/stateManager/colorHelpers.js
@@ -12,8 +12,15 @@ import { range } from "../range";
given a color mode & accessor, generate an annoMatrix query that will
fulfill it
*/
-export function createColorQuery(colorMode, colorByAccessor, schema) {
- if (!colorMode || !colorByAccessor || !schema) return null;
+export function createColorQuery(
+ colorMode,
+ colorByAccessor,
+ schema,
+ genesets,
+ diffExp
+) {
+ if (!colorMode || !colorByAccessor || !schema || !genesets) return null;
+
switch (colorMode) {
case "color by categorical metadata":
case "color by continuous metadata": {
@@ -33,6 +40,38 @@ export function createColorQuery(colorMode, colorByAccessor, schema) {
},
];
}
+ case "color by geneset mean expression": {
+ const varIndex = schema?.annotations?.var?.index;
+
+ if (!varIndex) return null;
+ if (!genesets) return null;
+
+ let _geneset;
+ let _setGenes;
+
+ if (colorByAccessor === "Temp DiffExp Set") {
+ _geneset = diffExp;
+ _setGenes = _geneset.map((diffexpResultItem) => {
+ const geneName = diffexpResultItem[0];
+ return geneName;
+ });
+ } else {
+ _geneset = genesets.get(colorByAccessor);
+ _setGenes = [..._geneset.genes.keys()];
+ }
+
+ return [
+ "X",
+ {
+ summarize: {
+ method: "mean",
+ field: "var",
+ column: varIndex,
+ values: _setGenes,
+ },
+ },
+ ];
+ }
default: {
return null;
}
@@ -86,6 +125,11 @@ function _createColorTable(
const { min, max } = col.summarize();
return createColorsByContinuousMetadata(col.asArray(), min, max);
}
+ case "color by geneset mean expression": {
+ const col = colorByData.icol(0);
+ const { min, max } = col.summarize();
+ return createColorsByContinuousMetadata(col.asArray(), min, max);
+ }
default: {
return defaultColors(schema.dataframe.nObs);
}