mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-25 19:28:12 +08:00
feat: diffexp returns two genesets (#2230)
* feat: return two lists for diffexp (#2221) * sp * split out derive sort order, tests passing * sp * return diff exp results in two lists * update * copy implementation over to desktop * add tests for two lists * small fixes to complete backend implementation * accept new diffexp response * map diff exp response to genesets * delete ) * name diffexp genesets with population names * take constants out of state and allow width prop to override * shorten mini-histo properly truncate and resize depending on expansion * prepend new genesets * rename data within diffexp action * backend * move diffexp ttest to common code module, update tests * update for unit tests * reference actual var Co-authored-by: Madison Dunitz <madison.dunitz@chanzuckerberg.com> Co-authored-by: Madison Dunitz <dunitzm@gmail.com>
This commit is contained in:
co-authored by
Madison Dunitz
Madison Dunitz
parent
7ed53c0f5b
commit
28b526b3fc
@@ -26,7 +26,13 @@ const Histogram = ({
|
||||
/*
|
||||
Create the d3 histogram
|
||||
*/
|
||||
const { marginLeft, marginRight, marginBottom, marginTop } = margin;
|
||||
// This is just a constant that's flipped by parent's `mini` boolean
|
||||
const {
|
||||
LEFT: marginLeft,
|
||||
RIGHT: marginRight,
|
||||
BOTTOM: marginBottom,
|
||||
TOP: marginTop,
|
||||
} = margin;
|
||||
const { x, y, bins, binStart, binEnd, binWidth } = histogram;
|
||||
const svg = d3.select(svgRef.current);
|
||||
const binPadding = mini ? 0 : -1;
|
||||
|
||||
@@ -13,6 +13,23 @@ import HistogramFooter from "./footer";
|
||||
import StillLoading from "./loading";
|
||||
import ErrorLoading from "./error";
|
||||
|
||||
const MARGIN = {
|
||||
LEFT: 10, // Space for 0 tick label on X axis
|
||||
RIGHT: 54, // space for Y axis & labels
|
||||
BOTTOM: 25, // space for X axis & labels
|
||||
TOP: 3,
|
||||
};
|
||||
const WIDTH = 340 - MARGIN.LEFT - MARGIN.RIGHT;
|
||||
const HEIGHT = 135 - MARGIN.TOP - MARGIN.BOTTOM;
|
||||
const MARGIN_MINI = {
|
||||
LEFT: 0, // Space for 0 tick label on X axis
|
||||
RIGHT: 0, // space for Y axis & labels
|
||||
BOTTOM: 0, // space for X axis & labels
|
||||
TOP: 0,
|
||||
};
|
||||
const WIDTH_MINI = 120 - MARGIN_MINI.LEFT - MARGIN_MINI.RIGHT;
|
||||
const HEIGHT_MINI = 15 - MARGIN_MINI.TOP - MARGIN_MINI.BOTTOM;
|
||||
|
||||
@connect((state, ownProps) => {
|
||||
const { isObs, isUserDefined, isGeneSetSummary, field } = ownProps;
|
||||
const myName = makeContinuousDimensionName(
|
||||
@@ -44,34 +61,6 @@ class HistogramBrush extends React.PureComponent {
|
||||
}
|
||||
});
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const marginLeft = 10; // Space for 0 tick label on X axis
|
||||
const marginRight = 54; // space for Y axis & labels
|
||||
const marginBottom = 25; // space for X axis & labels
|
||||
const marginTop = 3;
|
||||
|
||||
this.state = {
|
||||
margin: {
|
||||
marginLeft,
|
||||
marginRight,
|
||||
marginBottom,
|
||||
marginTop,
|
||||
},
|
||||
width: 340 - marginLeft - marginRight,
|
||||
height: 135 - marginTop - marginBottom,
|
||||
marginMini: {
|
||||
marginLeft: 0, // Space for 0 tick label on X axis
|
||||
marginRight: 0, // space for Y axis & labels
|
||||
marginBottom: 0, // space for X axis & labels
|
||||
marginTop: 0,
|
||||
},
|
||||
widthMini: 120,
|
||||
heightMini: 15,
|
||||
};
|
||||
}
|
||||
|
||||
onBrush = (selection, x, eventType) => {
|
||||
const type = `continuous metadata histogram ${eventType}`;
|
||||
return () => {
|
||||
@@ -210,15 +199,8 @@ class HistogramBrush extends React.PureComponent {
|
||||
};
|
||||
|
||||
fetchAsyncProps = async () => {
|
||||
const { annoMatrix } = this.props;
|
||||
const {
|
||||
margin,
|
||||
width,
|
||||
height,
|
||||
marginMini,
|
||||
widthMini,
|
||||
heightMini,
|
||||
} = this.state;
|
||||
const { annoMatrix, width } = this.props;
|
||||
|
||||
const { isClipped } = annoMatrix;
|
||||
|
||||
const query = this.createQuery();
|
||||
@@ -246,12 +228,17 @@ class HistogramBrush extends React.PureComponent {
|
||||
: globals.blue,
|
||||
];
|
||||
|
||||
const histogram = this.calcHistogramCache(column, margin, width, height);
|
||||
const histogram = this.calcHistogramCache(
|
||||
column,
|
||||
MARGIN,
|
||||
width || WIDTH,
|
||||
HEIGHT
|
||||
);
|
||||
const miniHistogram = this.calcHistogramCache(
|
||||
column,
|
||||
marginMini,
|
||||
widthMini,
|
||||
heightMini
|
||||
MARGIN_MINI,
|
||||
width || WIDTH_MINI,
|
||||
HEIGHT_MINI
|
||||
);
|
||||
|
||||
const isSingleValue = summary.min === summary.max;
|
||||
@@ -275,7 +262,7 @@ class HistogramBrush extends React.PureComponent {
|
||||
};
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this -- instance method allows for memoization per annotation
|
||||
calcHistogramCache(col, margin, width, height) {
|
||||
calcHistogramCache(col, newMargin, newWidth, newHeight) {
|
||||
/*
|
||||
recalculate expensive stuff, notably bins, summaries, etc.
|
||||
*/
|
||||
@@ -283,7 +270,10 @@ class HistogramBrush extends React.PureComponent {
|
||||
const summary = col.summarize(); /* this is memoized, so it's free the second time you call it */
|
||||
const { min: domainMin, max: domainMax } = summary;
|
||||
const numBins = 40;
|
||||
const { marginTop, marginLeft } = margin; /* changes with mini */
|
||||
const {
|
||||
TOP: topMargin,
|
||||
LEFT: leftMargin,
|
||||
} = newMargin; /* changes with mini */
|
||||
|
||||
histogramCache.domain = [
|
||||
domainMin,
|
||||
@@ -293,7 +283,7 @@ class HistogramBrush extends React.PureComponent {
|
||||
histogramCache.x = d3
|
||||
.scaleLinear()
|
||||
.domain([domainMin, domainMax])
|
||||
.range([marginLeft, marginLeft + width]);
|
||||
.range([leftMargin, leftMargin + newWidth]);
|
||||
|
||||
histogramCache.bins = histogramContinuous(col, numBins, [
|
||||
domainMin,
|
||||
@@ -310,7 +300,7 @@ class HistogramBrush extends React.PureComponent {
|
||||
histogramCache.y = d3
|
||||
.scaleLinear()
|
||||
.domain([0, yMax])
|
||||
.range([marginTop + height, marginTop]);
|
||||
.range([topMargin + newHeight, topMargin]);
|
||||
|
||||
return histogramCache;
|
||||
}
|
||||
@@ -367,14 +357,12 @@ class HistogramBrush extends React.PureComponent {
|
||||
mini,
|
||||
setGenes,
|
||||
} = this.props;
|
||||
const {
|
||||
margin,
|
||||
width,
|
||||
height,
|
||||
marginMini,
|
||||
widthMini,
|
||||
heightMini,
|
||||
} = this.state;
|
||||
|
||||
let { width } = this.props;
|
||||
if (!width) {
|
||||
width = mini ? WIDTH_MINI : WIDTH;
|
||||
}
|
||||
|
||||
const fieldForId = field.replace(/\s/g, "_");
|
||||
const showScatterPlot = isUserDefined;
|
||||
|
||||
@@ -432,11 +420,11 @@ class HistogramBrush extends React.PureComponent {
|
||||
histogram={
|
||||
mini ? asyncProps.miniHistogram : asyncProps.histogram
|
||||
}
|
||||
width={mini ? widthMini : width}
|
||||
height={mini ? heightMini : height}
|
||||
width={width}
|
||||
height={mini ? HEIGHT_MINI : HEIGHT}
|
||||
onBrush={this.onBrush}
|
||||
onBrushEnd={this.onBrushEnd}
|
||||
margin={mini ? marginMini : margin}
|
||||
margin={mini ? MARGIN_MINI : MARGIN}
|
||||
isColorBy={isColorAccessor}
|
||||
selectionRange={continuousSelectionRange}
|
||||
mini={mini}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { AnchorButton, Icon } from "@blueprintjs/core";
|
||||
import { Button, Icon } from "@blueprintjs/core";
|
||||
import Truncate from "../util/truncate";
|
||||
import HistogramBrush from "../brushableHistogram";
|
||||
|
||||
import * as globals from "../../globals";
|
||||
import actions from "../../actions";
|
||||
|
||||
const MINI_HISTOGRAM_WIDTH = 110;
|
||||
|
||||
@connect((state, ownProps) => {
|
||||
const { gene } = ownProps;
|
||||
|
||||
@@ -65,7 +66,7 @@ class Gene extends React.Component {
|
||||
isScatterplotYYaccessor,
|
||||
} = this.props;
|
||||
const { geneIsExpanded } = this.state;
|
||||
const genesetNameLengthVisible = 310; /* this magic number determines how much of a long geneset name we see */
|
||||
const geneSymbolWidth = 60 + (geneIsExpanded ? MINI_HISTOGRAM_WIDTH : 0);
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -108,7 +109,8 @@ class Gene extends React.Component {
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
width: globals.leftSidebarWidth - genesetNameLengthVisible,
|
||||
width: geneSymbolWidth,
|
||||
display: "inline-block",
|
||||
}}
|
||||
data-testid={`${gene}:gene-label`}
|
||||
>
|
||||
@@ -117,11 +119,16 @@ class Gene extends React.Component {
|
||||
</Truncate>
|
||||
</div>
|
||||
{!geneIsExpanded ? (
|
||||
<HistogramBrush isUserDefined field={gene} mini />
|
||||
<HistogramBrush
|
||||
isUserDefined
|
||||
field={gene}
|
||||
mini
|
||||
width={MINI_HISTOGRAM_WIDTH}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
<div style={{ flexShrink: 0, marginLeft: 2 }}>
|
||||
<AnchorButton
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
data-testid={`delete-from-geneset-${gene}`}
|
||||
@@ -130,8 +137,7 @@ class Gene extends React.Component {
|
||||
style={{ fontWeight: 700, marginRight: 2 }}
|
||||
icon={<Icon icon="trash" iconSize={10} />}
|
||||
/>
|
||||
)
|
||||
<AnchorButton
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
data-testid={`plot-x-${gene}`}
|
||||
@@ -141,8 +147,8 @@ class Gene extends React.Component {
|
||||
style={{ fontWeight: 700, marginRight: 2 }}
|
||||
>
|
||||
x
|
||||
</AnchorButton>
|
||||
<AnchorButton
|
||||
</Button>
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
data-testid={`plot-y-${gene}`}
|
||||
@@ -152,8 +158,8 @@ class Gene extends React.Component {
|
||||
style={{ fontWeight: 700, marginRight: 2 }}
|
||||
>
|
||||
y
|
||||
</AnchorButton>
|
||||
<AnchorButton
|
||||
</Button>
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
data-testclass="maximize"
|
||||
@@ -164,7 +170,7 @@ class Gene extends React.Component {
|
||||
icon={<Icon icon="maximize" iconSize={10} />}
|
||||
style={{ marginRight: 2 }}
|
||||
/>
|
||||
<AnchorButton
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
data-testclass="colorby"
|
||||
|
||||
Reference in New Issue
Block a user