mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-29 23:28:12 +08:00
subset embedding UI improvement (#1667)
* add user flag feature to annomatrix * add implicit subsetting for partial embeddings * lint * add embedding cell counts to embedding choice menu * layout
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import Async from "react-async";
|
||||
import {
|
||||
ButtonGroup,
|
||||
Popover,
|
||||
@@ -11,10 +12,11 @@ import {
|
||||
} from "@blueprintjs/core";
|
||||
import * as globals from "../../globals";
|
||||
import actions from "../../actions";
|
||||
import { getDiscreteCellEmbeddingRowIndex } from "../../util/stateManager/viewStackHelpers";
|
||||
|
||||
@connect((state) => {
|
||||
return {
|
||||
layoutChoice: state.layoutChoice,
|
||||
layoutChoice: state.layoutChoice, // TODO: really should clean up naming, s/layout/embedding/g
|
||||
schema: state.annoMatrix?.schema,
|
||||
crossfilter: state.obsCrossfilter,
|
||||
};
|
||||
@@ -32,6 +34,7 @@ class Embedding extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
const { layoutChoice, schema, crossfilter } = this.props;
|
||||
const { annoMatrix } = crossfilter;
|
||||
return (
|
||||
<ButtonGroup
|
||||
style={{
|
||||
@@ -61,7 +64,6 @@ class Embedding extends React.PureComponent {
|
||||
>
|
||||
{layoutChoice?.current}: {crossfilter.countSelected()} out of{" "}
|
||||
{crossfilter.size()} cells
|
||||
{/* BRUCE to extend 1559 */}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
}
|
||||
@@ -87,9 +89,9 @@ class Embedding extends React.PureComponent {
|
||||
selectedValue={layoutChoice.current}
|
||||
>
|
||||
{layoutChoice.available.map((name) => (
|
||||
<Radio
|
||||
label={`${name} ${schema?.dataframe?.nObs} cells`}
|
||||
value={name}
|
||||
<LayoutChoice
|
||||
annoMatrix={annoMatrix}
|
||||
layoutName={name}
|
||||
key={name}
|
||||
/>
|
||||
))}
|
||||
@@ -103,3 +105,41 @@ class Embedding extends React.PureComponent {
|
||||
}
|
||||
|
||||
export default Embedding;
|
||||
|
||||
const loadEmbeddingCounts = async ({ annoMatrix, layoutName }) => {
|
||||
const embedding = await annoMatrix.fetch("emb", layoutName);
|
||||
const discreteCellIndex = getDiscreteCellEmbeddingRowIndex(embedding);
|
||||
return { embedding, discreteCellIndex };
|
||||
};
|
||||
|
||||
const LayoutChoice = ({ annoMatrix, layoutName }) => {
|
||||
return (
|
||||
<Async
|
||||
promiseFn={loadEmbeddingCounts}
|
||||
annoMatrix={annoMatrix}
|
||||
layoutName={layoutName}
|
||||
>
|
||||
{({ data, error, isPending }) => {
|
||||
if (error) {
|
||||
/* log, as this is unexpected */
|
||||
console.error(error);
|
||||
}
|
||||
if (error || isPending) {
|
||||
/* still loading, or errored out - just omit counts (TODO: spinner?) */
|
||||
return <Radio label={`${layoutName}`} value={layoutName} />;
|
||||
}
|
||||
if (data) {
|
||||
const { embedding, discreteCellIndex } = data;
|
||||
const isAllCells = discreteCellIndex.size() === embedding.length;
|
||||
const sizeHint = `${discreteCellIndex.size()} ${
|
||||
isAllCells ? "(all) " : ""
|
||||
}cells`;
|
||||
return (
|
||||
<Radio label={`${layoutName}: ${sizeHint}`} value={layoutName} />
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}}
|
||||
</Async>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,6 +10,7 @@ import InformationMenu from "./infoMenu";
|
||||
import Subset from "./subset";
|
||||
import UndoRedoReset from "./undoRedo";
|
||||
import DiffexpButtons from "./diffexpButtons";
|
||||
import { getEmbSubsetView } from "../../util/stateManager/viewStackHelpers";
|
||||
|
||||
@connect((state) => {
|
||||
const { annoMatrix } = state;
|
||||
@@ -17,9 +18,11 @@ import DiffexpButtons from "./diffexpButtons";
|
||||
const selectedCount = crossfilter.countSelected();
|
||||
|
||||
const subsetPossible =
|
||||
selectedCount !== 0 && selectedCount !== crossfilter.size(); // ie, not all are selected
|
||||
const subsetResetPossible =
|
||||
annoMatrix.nObs !== annoMatrix.schema.dataframe.nObs;
|
||||
selectedCount !== 0 && selectedCount !== crossfilter.size(); // ie, not all and not none are selected
|
||||
const embSubsetView = getEmbSubsetView(annoMatrix);
|
||||
const subsetResetPossible = !embSubsetView
|
||||
? annoMatrix.nObs !== annoMatrix.schema.dataframe.nObs
|
||||
: annoMatrix.nObs !== embSubsetView.nObs;
|
||||
|
||||
return {
|
||||
subsetPossible,
|
||||
|
||||
Reference in New Issue
Block a user