Files
cellxgene/client/src/components/categorical/value.js
T
Bruce Martin 6b33315cbe Dataframe (#576)
* initial dataframe commit

* initial dataframe port of core app

* rename variables for clarity

* remove unused import

* comment out unused code

* fix array handling bug in crossfilter dimension creation

* allow creation of empty dataframes

* handle non-existent columns

* handle non-existent columns

* revise tests for new dataframe

* comments for clarity

* comments for clarity

* generate bulk add placeholder with real gene names

* fix bug in gene name adding

* more dataframe unit tests

* fix bug - subset from current world, not universe

* put cut and pasted code into a single function

* improve caching of crossfilter

* remove cascading update bug from graph

* more performance work

* improve state handling for scatterplot

* performance optimization of critical path

* add column summarization

* dataframe utils

* add callOnceLazy

* fix tests

* minor updates found during review

* fix misspelling

* remove RESTv02 from function names

* comment cleanup

* cut/icut col parameter defaults to null

* break up large test

* improve tests and comments on dataframe at/has functions
2019-02-22 11:31:34 -08:00

143 lines
3.7 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 &&
categoricalSelectionState[colorAccessor]
) {
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;