diff --git a/src/components/categorical/categorical.js b/src/components/categorical/categorical.js index 776063d6..28924289 100644 --- a/src/components/categorical/categorical.js +++ b/src/components/categorical/categorical.js @@ -8,38 +8,63 @@ import SectionHeader from "../framework/sectionHeader" import Value from "./value"; import { alphabeticallySortedValues } from "./util"; -const Category = ({metadataField, values}) => ( -
-

- {metadataField}: -

-
- { - _.map(alphabeticallySortedValues(values), (v, i) => { - return ( - - ) - }) - } -
-
-) +@connect() +class Category extends React.Component { + handleColorChange() { + this.props.dispatch({ + type: "color by categorical metadata", + colorAccessor: this.props.metadataField + }) + } + render() { + return ( +
+
+

+ {this.props.metadataField}: +

+ +
+
+ { + _.map(alphabeticallySortedValues(this.props.values), (v, i) => { + return ( + + ) + }) + } +
+
+ ) + } +} @connect((state) => { @@ -59,14 +84,22 @@ class Categories extends React.Component { 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" + key !== "CellName" && + !isColorField ) { return ( [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

diff --git a/src/components/categorical/value.js b/src/components/categorical/value.js index 2b3f75e6..a83b8159 100644 --- a/src/components/categorical/value.js +++ b/src/components/categorical/value.js @@ -9,20 +9,11 @@ import actions from "../../actions"; } }) class CategoryValue extends React.Component { - toggleOn() { - this.props.dispatch( - actions.attemptCategoricalMetadataSelection( - this.props.metadataField, - this.props.value - )) - } - toggleOff() { - this.props.dispatch( - actions.attemptCategoricalMetadataDeselection( - this.props.metadataField, - this.props.value - )) + + handleChange() { + console.log("dispatch", this.props.metadataField, this.props.value) } + render () { /* has this value for this category already been selected? */ @@ -40,9 +31,7 @@ class CategoryValue extends React.Component { return (
@@ -52,7 +41,7 @@ class CategoryValue extends React.Component { margin: 0, lineHeight: "1em" }}> - {this.props.value} + {this.props.value}

{ /* this is a hardcoded map of the things we need to keep an eye on and update global cell selection in response to */ const filterJustChanged = action.type === "color by expression" || - action.type === "color by continuous metadata" + action.type === "color by continuous metadata" || + action.type === "color by categorical metadata" ; if ( @@ -39,6 +40,7 @@ const updateCellSelectionMiddleware = (store) => { let currentSelectionWithUpdatedColors = s.controls.currentCellSelection.slice(0); let colorScale; + /* in plain language... @@ -48,6 +50,18 @@ const updateCellSelectionMiddleware = (store) => { This is available to all the draw functions as cell["__color__"] */ + if (action.type === "color by categorical metadata") { + + colorScale = d3.scaleOrdinal(d3.schemeCategory20); + + _.each(currentSelectionWithUpdatedColors, (cell, i) => { + currentSelectionWithUpdatedColors[i]["__color__"] = colorScale( + cell[action.colorAccessor] + ) + }) + + } + if (action.type === "color by continuous metadata") { colorScale = d3.scaleLinear() @@ -109,7 +123,17 @@ const updateCellSelectionMiddleware = (store) => { } - let modifiedAction = Object.assign({}, action, {currentSelectionWithUpdatedColors}) /* append the result of all the filters to the action the user just triggered */ + /* + append the result of all the filters to the action the user just triggered + */ + let modifiedAction = Object.assign( + {}, + action, + { + currentSelectionWithUpdatedColors, + colorScale + } + ) return next(modifiedAction); } diff --git a/src/reducers/controls.js b/src/reducers/controls.js index 9ecd1aa5..5bfea113 100644 --- a/src/reducers/controls.js +++ b/src/reducers/controls.js @@ -67,6 +67,11 @@ const Controls = (state = { colorAccessor: action.gene, currentCellSelection: action.currentSelectionWithUpdatedColors /* this comes from middleware */ }) + case "color by categorical metadata": + return Object.assign({}, state, { + colorAccessor: action.colorAccessor, /* pass the scale through additionally, and it's a legend! */ + currentCellSelection: action.currentSelectionWithUpdatedColors /* this comes from middleware */ + }) default: return state; }