filter on categorical with checkboxes

This commit is contained in:
Colin Megill
2017-12-24 01:38:25 -08:00
parent 87e8d5b1b1
commit 3486e5b1ca
2 changed files with 80 additions and 17 deletions
+22 -15
View File
@@ -5,28 +5,31 @@ import actions from "../../actions";
@connect((state) => { @connect((state) => {
return { return {
selectedMetadata: state.selectedMetadata categoricalAsBooleansMap: state.controls.categoricalAsBooleansMap
} }
}) })
class CategoryValue extends React.Component { class CategoryValue extends React.Component {
handleChange() { toggleOff() {
console.log("dispatch", this.props.metadataField, this.props.value) this.props.dispatch({
type: "categorical metadata filter deselect",
metadataField: this.props.metadataField,
value: this.props.value
});
}
toggleOn() {
this.props.dispatch({
type: "categorical metadata filter select",
metadataField: this.props.metadataField,
value: this.props.value
});
} }
render () { render () {
if (!this.props.categoricalAsBooleansMap) return null
/* has this value for this category already been selected? */ const selected = this.props.categoricalAsBooleansMap[this.props.metadataField][this.props.value]
let selected = false;
if (!this.props.selectedMetadata) { /* there is no selected metadata */
selected = false;
} else if (
this.props.selectedMetadata[this.props.metadataField] && /* the key {Location: []} is present */
this.props.selectedMetadata[this.props.metadataField].indexOf(this.props.value) > -1 /* "Tumor" exists in {Location: ["Tumor"]} */
) {
selected = true;
}
return ( return (
<div <div
@@ -41,7 +44,11 @@ class CategoryValue extends React.Component {
margin: 0, margin: 0,
lineHeight: "1em" lineHeight: "1em"
}}> }}>
<input onChange={this.handleChange.bind(this)} checked={true} type="checkbox"/> {this.props.value} <input
onChange={selected ? this.toggleOff.bind(this) : this.toggleOn.bind(this)}
checked={selected}
type="checkbox"/>
{this.props.value}
</p> </p>
<p style={{ <p style={{
margin: 0, margin: 0,
@@ -27,7 +27,9 @@ const updateCellSelectionMiddleware = (store) => {
const filterJustChanged = const filterJustChanged =
action.type === "continuous selection using parallel coords brushing" || action.type === "continuous selection using parallel coords brushing" ||
action.type === "graph brush selection change" || action.type === "graph brush selection change" ||
action.type === "graph brush deselect" action.type === "graph brush deselect" ||
action.type === "categorical metadata filter deselect" ||
action.type === "categorical metadata filter select"
; ;
if ( if (
@@ -110,7 +112,61 @@ const updateCellSelectionMiddleware = (store) => {
}) })
} }
let modifiedAction = Object.assign({}, action, {newSelection}) /* append the result of all the filters to the action the user just triggered */ /*
1. figure out if the users have unchecked boxes
2. put them in an array
3. filter on them
*/
let newCategoricalAsBooleansMap = s.controls.categoricalAsBooleansMap;
/*
...spread for merge: https://github.com/reactjs/redux/issues/432
we do the update here instead of the reducer because we need it for the reactive computation
*/
if (action.type === "categorical metadata filter select") {
newCategoricalAsBooleansMap = {
...s.controls.categoricalAsBooleansMap,
[action.metadataField]: {
...s.controls.categoricalAsBooleansMap[action.metadataField],
[action.value]: true
}
}
} else if (action.type === "categorical metadata filter deselect") {
newCategoricalAsBooleansMap = {
...s.controls.categoricalAsBooleansMap,
[action.metadataField]: {
...s.controls.categoricalAsBooleansMap[action.metadataField],
[action.value]: false
}
}
}
const inactiveCategories = [];
_.each(newCategoricalAsBooleansMap, (options, category) => {
_.each(options, (isActive, option) => {
if (!isActive) {
console.log("category: ", category, "option:", option)
inactiveCategories.push({category, option})
}
})
})
if (inactiveCategories.length > 0) {
_.each(inactiveCategories, (d) => {
_.each(newSelection, (cell, i) => {
if (cell[d.category] === d.option) {
newSelection[i]["__selected__"] = false;
}
})
})
}
let modifiedAction = Object.assign({}, action, {
newSelection,
newCategoricalAsBooleansMap,
}) /* append the result of all the filters to the action the user just triggered */
return next(modifiedAction); return next(modifiedAction);
} }