color scale, button

This commit is contained in:
Colin Megill
2021-07-23 13:29:27 -07:00
parent 02e79d502f
commit 2462d4afb1
4 changed files with 48 additions and 21 deletions
@@ -36,6 +36,7 @@ const LABEL_WIDTH_ANNO = LABEL_WIDTH - ANNO_BUTTON_WIDTH;
const { metadataField } = ownProps; const { metadataField } = ownProps;
const isUserAnno = schema?.annotations?.obsByName[metadataField]?.writable; const isUserAnno = schema?.annotations?.obsByName[metadataField]?.writable;
const categoricalSelection = state.categoricalSelection?.[metadataField]; const categoricalSelection = state.categoricalSelection?.[metadataField];
const isDotplotRows = metadataField === state.dotplot.row;
return { return {
colors: state.colors, colors: state.colors,
categoricalSelection, categoricalSelection,
@@ -45,7 +46,8 @@ const LABEL_WIDTH_ANNO = LABEL_WIDTH - ANNO_BUTTON_WIDTH;
crossfilter: state.obsCrossfilter, crossfilter: state.obsCrossfilter,
isUserAnno, isUserAnno,
genesets: state.genesets.genesets, genesets: state.genesets.genesets,
dotplot: state.layoutChoice.dotplot, layoutChoiceIsDotplot: state.layoutChoice.dotplot,
isDotplotRows,
}; };
}) })
class Category extends React.PureComponent { class Category extends React.PureComponent {
@@ -84,9 +86,9 @@ class Category extends React.PureComponent {
} }
handleColorChange = () => { handleColorChange = () => {
const { dispatch, metadataField, dotplot } = this.props; const { dispatch, metadataField, layoutChoiceIsDotplot } = this.props;
if (dotplot) { if (layoutChoiceIsDotplot) {
dispatch({ dispatch({
type: "set dotplot row", type: "set dotplot row",
data: metadataField, data: metadataField,
@@ -229,7 +231,8 @@ class Category extends React.PureComponent {
colors, colors,
annoMatrix, annoMatrix,
isUserAnno, isUserAnno,
dotplot, layoutChoiceIsDotplot,
isDotplotRows,
} = this.props; } = this.props;
const checkboxID = `category-select-${metadataField}`; const checkboxID = `category-select-${metadataField}`;
@@ -288,7 +291,8 @@ class Category extends React.PureComponent {
onCategoryToggleAllClick={handleCategoryToggleAllClick} onCategoryToggleAllClick={handleCategoryToggleAllClick}
onCategoryMenuClick={this.handleCategoryClick} onCategoryMenuClick={this.handleCategoryClick}
onCategoryMenuKeyPress={this.handleCategoryKeyPress} onCategoryMenuKeyPress={this.handleCategoryKeyPress}
dotplot={dotplot} layoutChoiceIsDotplot={layoutChoiceIsDotplot}
isDotplotRows={isDotplotRows}
/> />
); );
}} }}
@@ -383,7 +387,8 @@ const CategoryHeader = React.memo(
onCategoryMenuClick, onCategoryMenuClick,
onCategoryMenuKeyPress, onCategoryMenuKeyPress,
onCategoryToggleAllClick, onCategoryToggleAllClick,
dotplot, layoutChoiceIsDotplot,
isDotplotRows,
}) => { }) => {
/* /*
Render category name and controls (eg, color-by button). Render category name and controls (eg, color-by button).
@@ -482,10 +487,10 @@ const CategoryHeader = React.memo(
data-testclass="colorby" data-testclass="colorby"
data-testid={`colorby-${metadataField}`} data-testid={`colorby-${metadataField}`}
onClick={onColorChangeClick} onClick={onColorChangeClick}
active={isColorAccessor} active={isColorAccessor || isDotplotRows}
intent={isColorAccessor ? "primary" : "none"} intent={isColorAccessor || isDotplotRows ? "primary" : "none"}
disabled={isTruncated} disabled={isTruncated}
icon={dotplot ? "layout-grid" : "tint"} icon={layoutChoiceIsDotplot ? "layout-grid" : "tint"}
/> />
</Tooltip> </Tooltip>
</div> </div>
@@ -512,7 +517,8 @@ const CategoryRender = React.memo(
onCategoryMenuClick, onCategoryMenuClick,
onCategoryMenuKeyPress, onCategoryMenuKeyPress,
onCategoryToggleAllClick, onCategoryToggleAllClick,
dotplot, layoutChoiceIsDotplot,
isDotplotRows,
}) => { }) => {
/* /*
Render the core of the category, including checkboxes, controls, etc. Render the core of the category, including checkboxes, controls, etc.
@@ -557,7 +563,8 @@ const CategoryRender = React.memo(
onCategoryToggleAllClick={onCategoryToggleAllClick} onCategoryToggleAllClick={onCategoryToggleAllClick}
onCategoryMenuClick={onCategoryMenuClick} onCategoryMenuClick={onCategoryMenuClick}
onCategoryMenuKeyPress={onCategoryMenuKeyPress} onCategoryMenuKeyPress={onCategoryMenuKeyPress}
dotplot={dotplot} layoutChoiceIsDotplot={layoutChoiceIsDotplot}
isDotplotRows={isDotplotRows}
/> />
</div> </div>
<div style={{ marginLeft: 26 }}> <div style={{ marginLeft: 26 }}>
+25 -7
View File
@@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import { connect, shallowEqual } from "react-redux"; import { connect, shallowEqual } from "react-redux";
// import * as d3 from "d3"; import * as d3 from "d3";
import memoize from "memoize-one"; import memoize from "memoize-one";
@@ -140,18 +140,34 @@ class Column extends React.Component {
const col = colorData.icol(0); const col = colorData.icol(0);
const range = col.summarize(); const range = col.summarize();
console.log(_geneSymbol, metadataField, categoryData);
const histogramMap = col.histogram( const histogramMap = col.histogram(
100, 100,
[range.min, range.max], [range.min, range.max],
groupBy groupBy
); );
// const dotColorScale = d3 const categories =
// .scaleLinear() annoMatrix?.schema?.annotations?.obsByName[metadataField]
// .domain([range.min, range.max]) ?.categories;
// .range([0, 1]); const cellCategories = groupBy.asArray();
const geneExpressions = col.asArray();
let mean;
const meanGeneExpressions = {};
for (const c of categories) {
const arr = [];
for (let i = 0; i < geneExpressions.length; i += 1) {
if (cellCategories[i] === c) {
arr.push(geneExpressions[i]);
}
}
mean = arr.reduce((a, b) => a + b) / arr.length;
meanGeneExpressions[c] = mean;
}
const columnColorScale = d3
.scaleLinear()
.domain(d3.extent(Object.values(meanGeneExpressions)))
.range([0, 1]);
return categorySummary.categoryValues.map( return categorySummary.categoryValues.map(
(val, _categoryValueIndex) => { (val, _categoryValueIndex) => {
@@ -165,6 +181,8 @@ class Column extends React.Component {
_geneIndex={_geneIndex} _geneIndex={_geneIndex}
colorData={colorData} colorData={colorData}
rowColumnSize={rowColumnSize} rowColumnSize={rowColumnSize}
columnColorScale={columnColorScale}
meanGeneExpression={meanGeneExpressions[val]}
/> />
); );
} }
+4 -2
View File
@@ -10,7 +10,8 @@ const Dot = (props) => {
_geneSymbol, _geneSymbol,
_geneIndex, _geneIndex,
rowColumnSize, rowColumnSize,
// dotColorScale, columnColorScale,
meanGeneExpression,
} = props; } = props;
const bins = histogramMap.has(categoryValue) const bins = histogramMap.has(categoryValue)
@@ -34,6 +35,7 @@ const Dot = (props) => {
/* TODO(colinmegill) #632 scale between correct dimensions */ /* TODO(colinmegill) #632 scale between correct dimensions */
const paddingEquivalentToRowColumnIndexOffset = 8; const paddingEquivalentToRowColumnIndexOffset = 8;
/* domain is some fraction of the cells expressing, percent as decimal */
const dotscale = d3 const dotscale = d3
.scaleLinear() .scaleLinear()
.domain([0, 1]) .domain([0, 1])
@@ -62,7 +64,7 @@ const Dot = (props) => {
cx="11" cx="11"
cy="-3.5" cy="-3.5"
style={{ style={{
fill: interpolateCool(Math.random()), fill: interpolateCool(columnColorScale(meanGeneExpression)),
fillOpacity: 1, fillOpacity: 1,
stroke: "none", stroke: "none",
}} }}
+1 -1
View File
@@ -276,7 +276,7 @@ class MenuBar extends React.PureComponent {
icon="layout-grid" icon="layout-grid"
onClick={this.handleDotplotToggle} onClick={this.handleDotplotToggle}
active={dotplotEnabled} active={dotplotEnabled}
intent={dotplotEnabled ? "primary" : "none"} intent={dotplotEnabled ? "success" : "none"}
/> />
</Tooltip> </Tooltip>
<Tooltip <Tooltip