mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-26 19:48:12 +08:00
* create occupancy component * occupancy working * centering, width, flex spacing * add is-number * extend sort to cover string + int * proof of concept sorted occupancy * handle undefined occupancy entry, cleanup * only render occupancy when colorby is cat * cleanup unused vars * cleanup
139 lines
3.6 KiB
JavaScript
139 lines
3.6 KiB
JavaScript
// jshint esversion: 6
|
|
import { connect } from "react-redux";
|
|
import React from "react";
|
|
import _ from "lodash";
|
|
import Occupancy from "./occupancy";
|
|
import { countCategoryValues2D } from "../../util/stateManager/worldUtil";
|
|
import * as globals from "../../globals";
|
|
|
|
@connect(state => ({
|
|
categoricalSelectionState: state.controls.categoricalSelectionState,
|
|
colorScale: state.controls.colorScale,
|
|
colorAccessor: state.controls.colorAccessor,
|
|
schema: _.get(state.controls.world, "schema", null),
|
|
world: state.controls.world
|
|
}))
|
|
class CategoryValue extends React.Component {
|
|
toggleOff() {
|
|
const { dispatch, metadataField, categoryIndex } = this.props;
|
|
dispatch({
|
|
type: "categorical metadata filter deselect",
|
|
metadataField,
|
|
categoryIndex
|
|
});
|
|
}
|
|
|
|
toggleOn() {
|
|
const { dispatch, metadataField, categoryIndex } = this.props;
|
|
dispatch({
|
|
type: "categorical metadata filter select",
|
|
metadataField,
|
|
categoryIndex
|
|
});
|
|
}
|
|
|
|
render() {
|
|
const {
|
|
categoricalSelectionState,
|
|
metadataField,
|
|
categoryIndex,
|
|
colorAccessor,
|
|
colorScale,
|
|
i,
|
|
schema,
|
|
world
|
|
} = this.props;
|
|
|
|
if (!categoricalSelectionState) return null;
|
|
|
|
const category = categoricalSelectionState[metadataField];
|
|
const selected = category.categorySelected[categoryIndex];
|
|
const count = category.categoryCounts[categoryIndex];
|
|
const value = category.categoryValues[categoryIndex];
|
|
const displayString = String(
|
|
category.categoryValues[categoryIndex]
|
|
).valueOf();
|
|
|
|
/* this is the color scale, so add swatches below */
|
|
const isColorBy = metadataField === colorAccessor;
|
|
let categories = null;
|
|
let occupancy = null;
|
|
|
|
if (isColorBy && schema) {
|
|
categories = _.filter(schema.annotations.obs, {
|
|
name: colorAccessor
|
|
})[0].categories;
|
|
}
|
|
|
|
if (colorAccessor && !isColorBy) {
|
|
occupancy = countCategoryValues2D(
|
|
metadataField,
|
|
colorAccessor,
|
|
world.obsAnnotations
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div
|
|
key={i}
|
|
style={{
|
|
display: "flex",
|
|
alignItems: "baseline",
|
|
justifyContent: "space-between"
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
margin: 0,
|
|
padding: 0,
|
|
userSelect: "none",
|
|
width: globals.leftSidebarWidth - 130,
|
|
display: "flex",
|
|
justifyContent: "space-between"
|
|
}}
|
|
>
|
|
<label className="bp3-control bp3-checkbox">
|
|
<input
|
|
onChange={
|
|
selected ? this.toggleOff.bind(this) : this.toggleOn.bind(this)
|
|
}
|
|
checked={selected}
|
|
type="checkbox"
|
|
/>
|
|
<span className="bp3-control-indicator" />
|
|
{displayString}
|
|
</label>
|
|
<span style={{ flexShrink: 0 }}>
|
|
{colorAccessor &&
|
|
!isColorBy &&
|
|
categoricalSelectionState[colorAccessor] ? (
|
|
<Occupancy
|
|
occupancy={occupancy.get(
|
|
category.categoryValues[categoryIndex]
|
|
)}
|
|
{...this.props}
|
|
/>
|
|
) : null}
|
|
</span>
|
|
</div>
|
|
<span>
|
|
<span>{count}</span>
|
|
<svg
|
|
style={{
|
|
marginLeft: 5,
|
|
width: 11,
|
|
height: 11,
|
|
backgroundColor:
|
|
isColorBy && categories
|
|
? colorScale(categories.indexOf(value))
|
|
: "inherit"
|
|
}}
|
|
/>
|
|
</span>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default CategoryValue;
|