mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-03 15:48:11 +08:00
more linting
This commit is contained in:
@@ -11,12 +11,10 @@ import * as globals from "../../globals";
|
|||||||
import Value from "./value";
|
import Value from "./value";
|
||||||
import { alphabeticallySortedValues } from "./util";
|
import { alphabeticallySortedValues } from "./util";
|
||||||
|
|
||||||
@connect(state => {
|
@connect(state => ({
|
||||||
return {
|
colorAccessor: state.controls.colorAccessor,
|
||||||
colorAccessor: state.controls.colorAccessor,
|
categoricalAsBooleansMap: state.controls.categoricalAsBooleansMap
|
||||||
categoricalAsBooleansMap: state.controls.categoricalAsBooleansMap
|
}))
|
||||||
};
|
|
||||||
})
|
|
||||||
class Category extends React.Component {
|
class Category extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -27,9 +25,9 @@ class Category extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
const valuesAsBool = _.values(
|
const { categoricalAsBooleansMap, metadataField } = this.props;
|
||||||
this.props.categoricalAsBooleansMap[this.props.metadataField]
|
|
||||||
);
|
const valuesAsBool = _.values(categoricalAsBooleansMap[metadataField]);
|
||||||
/* count categories toggled on by counting true values */
|
/* count categories toggled on by counting true values */
|
||||||
const categoriesToggledOn = _.values(valuesAsBool).filter(v => v).length;
|
const categoriesToggledOn = _.values(valuesAsBool).filter(v => v).length;
|
||||||
|
|
||||||
@@ -46,55 +44,60 @@ class Category extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleColorChange() {
|
handleColorChange() {
|
||||||
this.props.dispatch({
|
const { dispatch, metadataField } = this.props;
|
||||||
|
dispatch({
|
||||||
type: "color by categorical metadata",
|
type: "color by categorical metadata",
|
||||||
colorAccessor: this.props.metadataField
|
colorAccessor: metadataField
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleAll() {
|
toggleAll() {
|
||||||
this.props.dispatch({
|
const { dispatch, metadataField } = this.props;
|
||||||
|
dispatch({
|
||||||
type: "categorical metadata filter all of these",
|
type: "categorical metadata filter all of these",
|
||||||
metadataField: this.props.metadataField
|
metadataField
|
||||||
});
|
});
|
||||||
this.setState({ isChecked: true });
|
this.setState({ isChecked: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleNone() {
|
toggleNone() {
|
||||||
this.props.dispatch({
|
const { dispatch, metadataField, value } = this.props;
|
||||||
|
dispatch({
|
||||||
type: "categorical metadata filter none of these",
|
type: "categorical metadata filter none of these",
|
||||||
metadataField: this.props.metadataField,
|
metadataField,
|
||||||
value: this.props.value
|
value
|
||||||
});
|
});
|
||||||
this.setState({ isChecked: false });
|
this.setState({ isChecked: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCategoryItems() {
|
|
||||||
return _.map(alphabeticallySortedValues(this.props.values), (v, i) => {
|
|
||||||
return (
|
|
||||||
<Value
|
|
||||||
key={v}
|
|
||||||
metadataField={this.props.metadataField}
|
|
||||||
count={this.props.values[v]}
|
|
||||||
value={v}
|
|
||||||
i={i}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleToggleAllClick() {
|
handleToggleAllClick() {
|
||||||
|
const { isChecked } = this.state;
|
||||||
// || this.checkbox.indeterminate === false
|
// || this.checkbox.indeterminate === false
|
||||||
if (this.state.isChecked) {
|
if (isChecked) {
|
||||||
console.log("checked, firing toggle none");
|
console.log("checked, firing toggle none");
|
||||||
this.toggleNone();
|
this.toggleNone();
|
||||||
} else if (!this.state.isChecked) {
|
} else if (!isChecked) {
|
||||||
console.log("!checked, firing toggle all");
|
console.log("!checked, firing toggle all");
|
||||||
this.toggleAll();
|
this.toggleAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderCategoryItems() {
|
||||||
|
const { values, metadataField } = this.props;
|
||||||
|
return _.map(alphabeticallySortedValues(values), (v, i) => (
|
||||||
|
<Value
|
||||||
|
key={v}
|
||||||
|
metadataField={metadataField}
|
||||||
|
count={values[v]}
|
||||||
|
value={v}
|
||||||
|
i={i}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { isExpanded, isChecked } = this.state;
|
||||||
|
const { metadataField, colorAccessor } = this.props;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -128,16 +131,16 @@ class Category extends React.Component {
|
|||||||
top: 2
|
top: 2
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
this.setState({ isExpanded: !this.state.isExpanded });
|
this.setState({ isExpanded: !isExpanded });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{this.state.isExpanded ? <FaArrowDown /> : <FaArrowRight />}
|
{isExpanded ? <FaArrowDown /> : <FaArrowRight />}
|
||||||
</span>
|
</span>
|
||||||
{this.props.metadataField}
|
{metadataField}
|
||||||
<input
|
<input
|
||||||
onChange={this.handleToggleAllClick.bind(this)}
|
onChange={this.handleToggleAllClick.bind(this)}
|
||||||
ref={el => (this.checkbox = el)}
|
ref={el => (this.checkbox = el)}
|
||||||
checked={this.state.isChecked}
|
checked={isChecked}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
@@ -148,7 +151,7 @@ class Category extends React.Component {
|
|||||||
// padding: this.props.colorAccessor === this.props.metadataField ? 3 : "auto",
|
// padding: this.props.colorAccessor === this.props.metadataField ? 3 : "auto",
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
color:
|
color:
|
||||||
this.props.colorAccessor === this.props.metadataField
|
colorAccessor === metadataField
|
||||||
? globals.brightBlue
|
? globals.brightBlue
|
||||||
: "black",
|
: "black",
|
||||||
// backgroundColor: this.props.colorAccessor === this.props.metadataField ? globals.brightBlue : "inherit",
|
// backgroundColor: this.props.colorAccessor === this.props.metadataField ? globals.brightBlue : "inherit",
|
||||||
@@ -162,7 +165,7 @@ class Category extends React.Component {
|
|||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>{this.state.isExpanded ? this.renderCategoryItems() : null}</div>
|
<div>{isExpanded ? this.renderCategoryItems() : null}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -181,7 +184,8 @@ class Categories extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.props.ranges) return null;
|
const { ranges } = this.props;
|
||||||
|
if (!ranges) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -194,7 +198,7 @@ class Categories extends React.Component {
|
|||||||
// overflow: "auto",
|
// overflow: "auto",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{_.map(this.props.ranges, (value, key) => {
|
{_.map(ranges, (value, key) => {
|
||||||
const isColorField = key.includes("color") || key.includes("Color");
|
const isColorField = key.includes("color") || key.includes("Color");
|
||||||
if (value.options && !isColorField && key !== "name") {
|
if (value.options && !isColorField && key !== "name") {
|
||||||
return (
|
return (
|
||||||
@@ -208,27 +212,3 @@ class Categories extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default Categories;
|
export default Categories;
|
||||||
|
|
||||||
/*
|
|
||||||
<SectionHeader text="Categorical Metadata"/>
|
|
||||||
[on off] toggle hide deselected filters (shows a menu vs shows what you ordered in compact/narrative form. fold out animation.)
|
|
||||||
|
|
||||||
<p> Sort by: Alphabetical / Count || Show counts: true / false || Collapse: all / none</p>
|
|
||||||
|
|
||||||
|
|
||||||
<p> <button> Field name [initial state] [create 2d graph] [explain part of 2d graph] </button> </p>
|
|
||||||
<p> <button> Field name [initial state] [create hypothesis] [validate hypothesis] </button> </p>
|
|
||||||
<p> <button> Field name [total] [selected in current filters] [selected in graph selection] </button> </p>
|
|
||||||
<p> <button> Tumor [400] [40] [4] </button> </p>
|
|
||||||
|
|
||||||
might be interesting to show them as an 👁 icon, or with a slash through it, to allow for visible or hidden state
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Each category has a color associated with it - ie., color by location should show up on these buttons,
|
|
||||||
Does colorby live here? Like a global, with the category labels at the top? If not, we have to
|
|
||||||
duplicate the category names somewhere else - but then, not all (like Cluster_2d_color) won't be listed here.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
// jshint esversion: 6
|
// jshint esversion: 6
|
||||||
export const alphabeticallySortedValues = values => {
|
export const alphabeticallySortedValues = values =>
|
||||||
return Object.keys(values).sort((a, b) => {
|
Object.keys(values).sort((a, b) => {
|
||||||
var textA = a.toUpperCase();
|
const textA = a.toUpperCase();
|
||||||
var textB = b.toUpperCase();
|
const textB = b.toUpperCase();
|
||||||
return textA < textB ? -1 : textA > textB ? 1 : 0;
|
return textA < textB ? -1 : textA > textB ? 1 : 0;
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,47 +1,51 @@
|
|||||||
// jshint esversion: 6
|
// jshint esversion: 6
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import * as globals from "../../globals";
|
|
||||||
import actions from "../../actions";
|
|
||||||
|
|
||||||
@connect(state => {
|
@connect(state => ({
|
||||||
return {
|
categoricalAsBooleansMap: state.controls.categoricalAsBooleansMap,
|
||||||
categoricalAsBooleansMap: state.controls.categoricalAsBooleansMap,
|
colorScale: state.controls.colorScale,
|
||||||
colorScale: state.controls.colorScale,
|
colorAccessor: state.controls.colorAccessor
|
||||||
colorAccessor: state.controls.colorAccessor
|
}))
|
||||||
};
|
|
||||||
})
|
|
||||||
class CategoryValue extends React.Component {
|
class CategoryValue extends React.Component {
|
||||||
toggleOff() {
|
toggleOff() {
|
||||||
this.props.dispatch({
|
const { dispatch, metadataField, value } = this.props;
|
||||||
|
dispatch({
|
||||||
type: "categorical metadata filter deselect",
|
type: "categorical metadata filter deselect",
|
||||||
metadataField: this.props.metadataField,
|
metadataField,
|
||||||
value: this.props.value
|
value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleOn() {
|
toggleOn() {
|
||||||
this.props.dispatch({
|
const { dispatch, metadataField, value } = this.props;
|
||||||
|
dispatch({
|
||||||
type: "categorical metadata filter select",
|
type: "categorical metadata filter select",
|
||||||
metadataField: this.props.metadataField,
|
metadataField,
|
||||||
value: this.props.value
|
value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.props.categoricalAsBooleansMap) return null;
|
const {
|
||||||
|
categoricalAsBooleansMap,
|
||||||
|
metadataField,
|
||||||
|
count,
|
||||||
|
value,
|
||||||
|
colorAccessor,
|
||||||
|
colorScale,
|
||||||
|
i
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
const selected = this.props.categoricalAsBooleansMap[
|
if (!categoricalAsBooleansMap) return null;
|
||||||
this.props.metadataField
|
|
||||||
][this.props.value];
|
const selected = categoricalAsBooleansMap[metadataField][value];
|
||||||
const c =
|
/* this is the color scale, so add swatches below */
|
||||||
this.props.metadataField ===
|
const c = metadataField === colorAccessor;
|
||||||
this.props
|
|
||||||
.colorAccessor; /* this is the color scale, so add swatches below */
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={this.props.i}
|
key={i}
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "baseline",
|
alignItems: "baseline",
|
||||||
@@ -66,22 +70,20 @@ class CategoryValue extends React.Component {
|
|||||||
checked={selected}
|
checked={selected}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
/>
|
/>
|
||||||
{this.props.value}
|
{value}
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
style={{
|
style={{
|
||||||
padding: "1px 10px",
|
padding: "1px 10px",
|
||||||
width: 80,
|
width: 80,
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
backgroundColor: c
|
backgroundColor: c ? colorScale(value) : "inherit",
|
||||||
? this.props.colorScale(this.props.value)
|
|
||||||
: "inherit",
|
|
||||||
color: c ? "white" : "black",
|
color: c ? "white" : "black",
|
||||||
margin: 0
|
margin: 0
|
||||||
// lineHeight: "1em"
|
// lineHeight: "1em"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{this.props.count}
|
{count}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -89,38 +91,3 @@ class CategoryValue extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default CategoryValue;
|
export default CategoryValue;
|
||||||
|
|
||||||
// toggleOnlyThis() {
|
|
||||||
// this.props.dispatch({
|
|
||||||
// type: "categorical metadata filter none of these",
|
|
||||||
// metadataField: this.props.metadataField,
|
|
||||||
// value: this.props.value
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// <span
|
|
||||||
// onClick={this.toggleOnlyThis.bind(this)}
|
|
||||||
// style={{
|
|
||||||
// fontFamily: globals.accentFont,
|
|
||||||
// fontSize: 10,
|
|
||||||
// fontWeight: 100,
|
|
||||||
// fontStyle: "italic",
|
|
||||||
// cursor: "pointer",
|
|
||||||
// }}>
|
|
||||||
// {"only"}
|
|
||||||
// </span>
|
|
||||||
|
|
||||||
// onClick={selected ? this.toggleOff.bind(this) : this.toggleOn.bind(this)}
|
|
||||||
// toggleOn() {
|
|
||||||
// this.props.dispatch(
|
|
||||||
// actions.attemptCategoricalMetadataSelection(
|
|
||||||
// this.props.metadataField,
|
|
||||||
// this.props.value
|
|
||||||
// ))
|
|
||||||
// }
|
|
||||||
// toggleOff() {
|
|
||||||
// this.props.dispatch(
|
|
||||||
// actions.attemptCategoricalMetadataDeselection(
|
|
||||||
// this.props.metadataField,
|
|
||||||
// this.props.value
|
|
||||||
// ))
|
|
||||||
// }
|
|
||||||
|
|||||||
Reference in New Issue
Block a user