mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-05 06:08:12 +08:00
render perf refinements (#1632)
* render performance improvements * improve render perf * remove logging * lint * improve memoziation
This commit is contained in:
@@ -3,25 +3,18 @@ import React from "react";
|
||||
import { AnchorButton, Tooltip } from "@blueprintjs/core";
|
||||
import { connect } from "react-redux";
|
||||
import { tooltipHoverOpenDelay } from "../../globals";
|
||||
import actions from "../../actions";
|
||||
|
||||
@connect()
|
||||
@connect((state) => ({
|
||||
differential: state.differential,
|
||||
}))
|
||||
class CellSetButton extends React.PureComponent {
|
||||
set() {
|
||||
const {
|
||||
differential,
|
||||
crossfilter,
|
||||
dispatch,
|
||||
eitherCellSetOneOrTwo,
|
||||
} = this.props;
|
||||
const { differential, dispatch, eitherCellSetOneOrTwo } = this.props;
|
||||
|
||||
let set = crossfilter.allSelectedLabels();
|
||||
if (set.length === 0) set = null;
|
||||
if (!differential.diffExp) {
|
||||
/* diffexp needs to be cleared before we store a new set */
|
||||
dispatch({
|
||||
type: `store current cell selection as differential set ${eitherCellSetOneOrTwo}`,
|
||||
data: set,
|
||||
});
|
||||
// disallow this action if the user has active differential expression results
|
||||
dispatch(actions.setCellSetFromSelection(eitherCellSetOneOrTwo));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// jshint esversion: 6
|
||||
import React from "react";
|
||||
import {
|
||||
Position,
|
||||
@@ -11,7 +10,7 @@ import {
|
||||
import { tooltipHoverOpenDelay } from "../../globals";
|
||||
import styles from "./menubar.css";
|
||||
|
||||
function Clip(props) {
|
||||
const Clip = React.memo((props) => {
|
||||
const {
|
||||
pendingClipPercentiles,
|
||||
clipPercentileMin,
|
||||
@@ -129,6 +128,6 @@ function Clip(props) {
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default Clip;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// jshint esversion: 6
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { Button, ButtonGroup, AnchorButton, Tooltip } from "@blueprintjs/core";
|
||||
@@ -8,15 +7,13 @@ import actions from "../../actions";
|
||||
import CellSetButton from "./cellSetButtons";
|
||||
|
||||
@connect((state) => ({
|
||||
config: state.config,
|
||||
crossfilter: state.obsCrossfilter,
|
||||
differential: state.differential,
|
||||
celllist1: state.differential?.celllist1,
|
||||
celllist2: state.differential?.celllist2,
|
||||
diffexpMayBeSlow: state.config?.parameters?.["diffexp-may-be-slow"] ?? false,
|
||||
diffexpCellcountMax: state.config?.limits?.["diffexp_cellcount_max"],
|
||||
}))
|
||||
class DiffexpButtons extends React.Component {
|
||||
class DiffexpButtons extends React.PureComponent {
|
||||
computeDiffExp = () => {
|
||||
const { dispatch, differential } = this.props;
|
||||
if (differential.celllist1 && differential.celllist2) {
|
||||
@@ -42,13 +39,7 @@ class DiffexpButtons extends React.Component {
|
||||
|
||||
render() {
|
||||
/* diffexp-related buttons may be disabled */
|
||||
const {
|
||||
differential,
|
||||
diffexpMayBeSlow,
|
||||
diffexpCellcountMax,
|
||||
crossfilter,
|
||||
dispatch,
|
||||
} = this.props;
|
||||
const { differential, diffexpMayBeSlow, diffexpCellcountMax } = this.props;
|
||||
|
||||
const haveBothCellSets =
|
||||
!!differential.celllist1 && !!differential.celllist2;
|
||||
@@ -72,17 +63,8 @@ class DiffexpButtons extends React.Component {
|
||||
|
||||
return (
|
||||
<ButtonGroup className={styles.menubarButton}>
|
||||
{/* eslint-disable react/jsx-props-no-spreading --- disable until eslint-config-airbnb v18.1.1*/}
|
||||
<CellSetButton
|
||||
{...{ differential, crossfilter, dispatch }}
|
||||
eitherCellSetOneOrTwo={1}
|
||||
/>
|
||||
<CellSetButton
|
||||
{...{ differential, crossfilter, dispatch }}
|
||||
eitherCellSetOneOrTwo={2}
|
||||
/>
|
||||
{/* eslint-enable react/jsx-props-no-spreading --- end disable*/}
|
||||
|
||||
<CellSetButton eitherCellSetOneOrTwo={1} />
|
||||
<CellSetButton eitherCellSetOneOrTwo={2} />
|
||||
{!differential.diffExp ? (
|
||||
<Tooltip
|
||||
content={warnMaxSizeExceeded ? tipMessageWarn : tipMessage}
|
||||
|
||||
@@ -12,32 +12,44 @@ import Subset from "./subset";
|
||||
import UndoRedoReset from "./undoRedo";
|
||||
import DiffexpButtons from "./diffexpButtons";
|
||||
|
||||
@connect((state) => ({
|
||||
annoMatrix: state.annoMatrix,
|
||||
crossfilter: state.obsCrossfilter,
|
||||
differential: state.differential,
|
||||
graphInteractionMode: state.controls.graphInteractionMode,
|
||||
clipPercentileMin: Math.round(100 * (state.annoMatrix?.clipRange?.[0] ?? 0)),
|
||||
clipPercentileMax: Math.round(100 * (state.annoMatrix?.clipRange?.[1] ?? 1)),
|
||||
userDefinedGenes: state.controls.userDefinedGenes,
|
||||
diffexpGenes: state.controls.diffexpGenes,
|
||||
colorAccessor: state.colors.colorAccessor,
|
||||
scatterplotXXaccessor: state.controls.scatterplotXXaccessor,
|
||||
scatterplotYYaccessor: state.controls.scatterplotYYaccessor,
|
||||
celllist1: state.differential.celllist1,
|
||||
celllist2: state.differential.celllist2,
|
||||
libraryVersions: state.config?.["library_versions"],
|
||||
undoDisabled: state["@@undoable/past"].length === 0,
|
||||
redoDisabled: state["@@undoable/future"].length === 0,
|
||||
aboutLink: state.config?.links?.["about-dataset"],
|
||||
disableDiffexp: state.config?.parameters?.["disable-diffexp"] ?? false,
|
||||
diffexpMayBeSlow: state.config?.parameters?.["diffexp-may-be-slow"] ?? false,
|
||||
showCentroidLabels: state.centroidLabels.showLabels,
|
||||
tosURL: state.config?.parameters?.["about_legal_tos"],
|
||||
privacyURL: state.config?.parameters?.["about_legal_privacy"],
|
||||
categoricalSelection: state.categoricalSelection,
|
||||
}))
|
||||
class MenuBar extends React.Component {
|
||||
@connect((state) => {
|
||||
const { annoMatrix } = state;
|
||||
const crossfilter = state.obsCrossfilter;
|
||||
const selectedCount = crossfilter.countSelected();
|
||||
|
||||
const subsetPossible =
|
||||
selectedCount !== 0 && selectedCount !== crossfilter.size(); // ie, not all are selected
|
||||
const subsetResetPossible =
|
||||
annoMatrix.nObs !== annoMatrix.schema.dataframe.nObs;
|
||||
|
||||
return {
|
||||
subsetPossible,
|
||||
subsetResetPossible,
|
||||
differential: state.differential,
|
||||
graphInteractionMode: state.controls.graphInteractionMode,
|
||||
clipPercentileMin: Math.round(100 * (annoMatrix?.clipRange?.[0] ?? 0)),
|
||||
clipPercentileMax: Math.round(100 * (annoMatrix?.clipRange?.[1] ?? 1)),
|
||||
userDefinedGenes: state.controls.userDefinedGenes,
|
||||
diffexpGenes: state.controls.diffexpGenes,
|
||||
colorAccessor: state.colors.colorAccessor,
|
||||
scatterplotXXaccessor: state.controls.scatterplotXXaccessor,
|
||||
scatterplotYYaccessor: state.controls.scatterplotYYaccessor,
|
||||
celllist1: state.differential.celllist1,
|
||||
celllist2: state.differential.celllist2,
|
||||
libraryVersions: state.config?.["library_versions"],
|
||||
undoDisabled: state["@@undoable/past"].length === 0,
|
||||
redoDisabled: state["@@undoable/future"].length === 0,
|
||||
aboutLink: state.config?.links?.["about-dataset"],
|
||||
disableDiffexp: state.config?.parameters?.["disable-diffexp"] ?? false,
|
||||
diffexpMayBeSlow:
|
||||
state.config?.parameters?.["diffexp-may-be-slow"] ?? false,
|
||||
showCentroidLabels: state.centroidLabels.showLabels,
|
||||
tosURL: state.config?.parameters?.["about_legal_tos"],
|
||||
privacyURL: state.config?.parameters?.["about_legal_privacy"],
|
||||
categoricalSelection: state.categoricalSelection,
|
||||
};
|
||||
})
|
||||
class MenuBar extends React.PureComponent {
|
||||
static isValidDigitKeyEvent(e) {
|
||||
/*
|
||||
Return true if this event is necessary to enter a percent number input.
|
||||
@@ -171,17 +183,14 @@ class MenuBar extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
subsetPossible = () => {
|
||||
const { crossfilter } = this.props;
|
||||
const count = crossfilter.countSelected();
|
||||
return (
|
||||
count !== 0 && count !== crossfilter.size() // ie, not all are selected
|
||||
);
|
||||
handleSubset = () => {
|
||||
const { dispatch } = this.props;
|
||||
dispatch(actions.subsetAction());
|
||||
};
|
||||
|
||||
subsetResetPossible = () => {
|
||||
const { annoMatrix } = this.props;
|
||||
return annoMatrix.nObs !== annoMatrix.schema.dataframe.nObs;
|
||||
handleSubsetReset = () => {
|
||||
const { dispatch } = this.props;
|
||||
dispatch(actions.resetSubsetAction());
|
||||
};
|
||||
|
||||
render() {
|
||||
@@ -201,6 +210,8 @@ class MenuBar extends React.Component {
|
||||
tosURL,
|
||||
categoricalSelection,
|
||||
colorAccessor,
|
||||
subsetPossible,
|
||||
subsetResetPossible,
|
||||
} = this.props;
|
||||
const { pendingClipPercentiles } = this.state;
|
||||
|
||||
@@ -309,14 +320,10 @@ class MenuBar extends React.Component {
|
||||
</Tooltip>
|
||||
</ButtonGroup>
|
||||
<Subset
|
||||
subsetPossible={this.subsetPossible()}
|
||||
subsetResetPossible={this.subsetResetPossible()}
|
||||
handleSubset={() => {
|
||||
dispatch(actions.subsetAction());
|
||||
}}
|
||||
handleSubsetReset={() => {
|
||||
dispatch(actions.resetSubsetAction());
|
||||
}}
|
||||
subsetPossible={subsetPossible}
|
||||
subsetResetPossible={subsetResetPossible}
|
||||
handleSubset={this.handleSubset}
|
||||
handleSubsetReset={this.handleSubsetReset}
|
||||
/>
|
||||
{disableDiffexp ? null : <DiffexpButtons />}
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import React from "react";
|
||||
import { Button, Popover, Menu, MenuItem, Position } from "@blueprintjs/core";
|
||||
import styles from "./menubar.css";
|
||||
|
||||
function InformationMenu(props) {
|
||||
const InformationMenu = React.memo((props) => {
|
||||
const { libraryVersions, aboutLink, tosURL, privacyURL } = props;
|
||||
return (
|
||||
<div className={`bp3-button-group ${styles.menubarButton}`}>
|
||||
@@ -72,6 +72,6 @@ function InformationMenu(props) {
|
||||
</Popover>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default InformationMenu;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { AnchorButton, ButtonGroup, Tooltip } from "@blueprintjs/core";
|
||||
import styles from "./menubar.css";
|
||||
import * as globals from "../../globals";
|
||||
|
||||
function Subset(props) {
|
||||
const Subset = React.memo((props) => {
|
||||
const {
|
||||
subsetPossible,
|
||||
subsetResetPossible,
|
||||
@@ -41,6 +41,6 @@ function Subset(props) {
|
||||
</Tooltip>
|
||||
</ButtonGroup>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default Subset;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// jshint esversion: 6
|
||||
import React from "react";
|
||||
import { AnchorButton, Tooltip } from "@blueprintjs/core";
|
||||
import { tooltipHoverOpenDelay } from "../../globals";
|
||||
import styles from "./menubar.css";
|
||||
|
||||
function InformationMenu(props) {
|
||||
const UndoRedo = React.memo((props) => {
|
||||
const { undoDisabled, redoDisabled, dispatch } = props;
|
||||
return (
|
||||
<div className={`bp3-button-group ${styles.menubarButton}`}>
|
||||
@@ -46,6 +45,6 @@ function InformationMenu(props) {
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default InformationMenu;
|
||||
export default UndoRedo;
|
||||
|
||||
Reference in New Issue
Block a user