// jshint esversion: 6 import React from "react"; import _ from "lodash"; import { connect } from "react-redux"; import * as globals from "../../globals"; import styles from "./categorical.css"; import SectionHeader from "../framework/sectionHeader"; import Value from "./value"; import { alphabeticallySortedValues } from "./util"; import FaArrowRight from "react-icons/lib/fa/angle-right"; import FaArrowDown from "react-icons/lib/fa/angle-down"; import FaPaintBrush from "react-icons/lib/fa/paint-brush"; @connect(state => { return { colorAccessor: state.controls.colorAccessor, categoricalAsBooleansMap: state.controls.categoricalAsBooleansMap }; }) class Category extends React.Component { constructor(props) { super(props); this.state = { isChecked: true, isExpanded: false }; } componentDidUpdate() { const valuesAsBool = _.values( this.props.categoricalAsBooleansMap[this.props.metadataField] ); /* count categories toggled on by counting true values */ const categoriesToggledOn = _.values(valuesAsBool).filter(v => v).length; if (categoriesToggledOn === valuesAsBool.length) { /* everything is on, so not indeterminate */ this.checkbox.indeterminate = false; } else if (categoriesToggledOn === 0) { /* nothing is on, so no */ this.checkbox.indeterminate = false; } else if (categoriesToggledOn < valuesAsBool.length) { /* to be explicit... */ this.checkbox.indeterminate = true; } } handleColorChange() { this.props.dispatch({ type: "color by categorical metadata", colorAccessor: this.props.metadataField }); } toggleAll() { this.props.dispatch({ type: "categorical metadata filter all of these", metadataField: this.props.metadataField }); this.setState({ isChecked: true }); } toggleNone() { this.props.dispatch({ type: "categorical metadata filter none of these", metadataField: this.props.metadataField, value: this.props.value }); this.setState({ isChecked: false }); } renderCategoryItems() { return _.map(alphabeticallySortedValues(this.props.values), (v, i) => { return ( ); }); } handleToggleAllClick() { // || this.checkbox.indeterminate === false if (this.state.isChecked) { console.log("checked, firing toggle none"); this.toggleNone(); } else if (!this.state.isChecked) { console.log("!checked, firing toggle all"); this.toggleAll(); } } render() { return (

{ this.setState({ isExpanded: !this.state.isExpanded }); }} > {this.state.isExpanded ? : } {this.props.metadataField} (this.checkbox = el)} checked={this.state.isChecked} type="checkbox" />

{this.state.isExpanded ? this.renderCategoryItems() : null}
); } } @connect(state => { const ranges = _.get("state.cells.cells.data.ranges", null); return { ranges }; }) class Categories extends React.Component { constructor(props) { super(props); this.state = {}; } render() { if (!this.props.ranges) return null; return (
{_.map(this.props.ranges, (value, key) => { const isColorField = key.includes("color") || key.includes("Color"); if (value.options && key !== "CellName" && !isColorField) { return ( ); } })}
); } } export default Categories; /* [on off] toggle hide deselected filters (shows a menu vs shows what you ordered in compact/narrative form. fold out animation.)

Sort by: Alphabetical / Count || Show counts: true / false || Collapse: all / none

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. */