mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-09 05:58:11 +08:00
color scale, button
This commit is contained in:
@@ -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 }}>
|
||||||
|
|||||||
@@ -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]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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",
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user