adding and removing user defined genes

This commit is contained in:
Colin Megill
2018-10-15 11:20:52 -07:00
parent 5b2c07f105
commit 8d07b400be
5 changed files with 114 additions and 40 deletions
@@ -184,8 +184,21 @@ class HistogramBrush extends React.Component {
}
}
removeHistogram() {
const { dispatch, field, colorAccessor } = this.props;
dispatch({
type: "clear user defined gene",
data: field
});
if (field === colorAccessor) {
dispatch({
type: "reset colorscale"
});
}
}
render() {
const { field, ranges, colorAccessor } = this.props;
const { field, ranges, colorAccessor, isUserDefined } = this.props;
return (
<div
@@ -195,7 +208,22 @@ class HistogramBrush extends React.Component {
}}
id={`histogram_${field}`}
>
<p style={{ fontSize: globals.tiniestFontSize }}> {field} </p>
<div>
<span style={{ fontSize: globals.tiniestFontSize }}> {field} </span>
{isUserDefined ? (
<span
onClick={this.removeHistogram.bind(this)}
style={{
fontSize: globals.tiniestFontSize,
color: globals.blue,
cursor: "pointer",
marginLeft: 7
}}
>
remove
</span>
) : null}
</div>
<svg
width={this.width}
height={this.height}
+18 -8
View File
@@ -13,16 +13,17 @@ import HistogramBrush from "../brushableHistogram/";
metadata: _.get(state.controls.world, "obsAnnotations", null),
colorAccessor: state.controls.colorAccessor,
colorScale: state.controls.colorScale,
selectionUpdate: _.get(state.controls, "crossfilter.updateTime", null)
selectionUpdate: _.get(state.controls, "crossfilter.updateTime", null),
schema: _.get(state.controls.world, "schema", null)
};
})
class Continuous extends React.Component {
handleBrushAction(selection) {
const { dispatch } = this.props;
dispatch({
type: "continuous selection using parallel coords brushing",
data: selection
});
constructor(props) {
super(props);
this.hasContinuous = false;
this.continuousChecked = false;
this.state = {};
}
handleColorAction(key) {
@@ -36,11 +37,20 @@ class Continuous extends React.Component {
};
}
componentDidUpdate() {}
render() {
const { ranges, obsAnnotations } = this.props;
const { ranges, obsAnnotations, schema } = this.props;
if (schema && !this.continuousChecked) {
this.hasContinuous = _.some(schema.annotations.obs, d => {
return d.type === "int32" || d.type === "float32";
});
this.continuousChecked = true; /* only do this once */
}
return (
<div>
{this.hasContinuous ? <p> Continuous metadata </p> : null}
{_.map(ranges, (value, key) => {
const isColorField = key.includes("color") || key.includes("Color");
if (value.range && key !== "name" && !isColorField) {
@@ -9,17 +9,23 @@ import actions from "../../actions";
@connect()
class CellSetButton extends React.Component {
set() {
const { differential } = this.props;
const set = _.map(this.props.crossfilter.allFiltered(), "name");
this.props.dispatch({
type:
"store current cell selection as differential set " +
this.props.eitherCellSetOneOrTwo,
data: set
});
if (!differential.diffExp) {
/* diffexp needs to be cleared before we store a new set */
this.props.dispatch({
type:
"store current cell selection as differential set " +
this.props.eitherCellSetOneOrTwo,
data: set
});
}
}
render() {
const { differential } = this.props;
return (
<span style={{ marginRight: 10 }}>
<button
@@ -28,7 +34,9 @@ class CellSetButton extends React.Component {
borderRadius: 2,
padding: "0px 10px",
height: 30,
backgroundColor: globals.brightBlue,
backgroundColor: !differential.diffExp
? globals.brightBlue
: globals.lightGrey,
border: "none",
cursor: "pointer"
}}
@@ -47,7 +55,7 @@ class CellSetButton extends React.Component {
top: 0
}}
>
{this.props.differential[
{differential[
"celllist" + this.props.eitherCellSetOneOrTwo
]
? this.props.differential[
+27 -19
View File
@@ -36,19 +36,43 @@ class GeneExpression extends React.Component {
ctx: null,
axes: null,
dimensions: null,
gene: null
gene: ""
};
}
keyPress(e) {
if (e.keyCode == 13) {
this.handleClick();
}
}
handleClick() {
const { world, dispatch, userDefinedGenes } = this.props;
if (userDefinedGenes.indexOf(this.state.gene) !== -1) {
console.log("That gene already exists");
} else if (userDefinedGenes.length > 15) {
console.log(
"That's too many genes, you can have at most 15 user defined genes"
);
} else {
dispatch(actions.requestGeneExpressionCountsPOST([this.state.gene]));
dispatch({
type: "user defined gene",
data: this.state.gene
});
this.setState({ gene: "" });
}
}
render() {
const { world, userDefinedGenes } = this.props;
return (
<div>
<input
onKeyDown={this.keyPress.bind(this)}
onChange={e => {
this.setState({ gene: e.target.value });
}}
type="text"
value={this.state.gene}
/>
<button
style={{
@@ -59,23 +83,7 @@ class GeneExpression extends React.Component {
marginTop: 20,
padding: 0
}}
onClick={() => {
if (userDefinedGenes.indexOf(this.state.gene) !== -1) {
console.log("That gene already exists");
} else if (userDefinedGenes.length > 15) {
console.log(
"That's too many genes, you can have at most 15 user defined genes"
);
} else {
this.props.dispatch(
actions.requestGeneExpressionCountsPOST([this.state.gene])
);
this.props.dispatch({
type: "user defined gene",
data: this.state.gene
});
}
}}
onClick={this.handleClick.bind(this)}
>
<CirclePlus
style={{
@@ -101,7 +109,7 @@ class GeneExpression extends React.Component {
key={geneName}
field={geneName}
ranges={d3.extent(values)}
isUserSelected
isUserDefined
/>
);
}
+23 -3
View File
@@ -185,15 +185,35 @@ const Controls = (
varDataCache: worldVarDataCache
}
};
case "user defined gene":
case "user defined gene": {
const newUserDefinedGenes = state.userDefinedGenes.slice();
newUserDefinedGenes.push(action.data);
return {
...state,
userDefinedGenes: newUserDefinedGenes
};
case "clear user defined gene":
}
case "clear user defined gene": {
const { userDefinedGenes } = state;
const newUserDefinedGenes = _.filter(userDefinedGenes, d => {
return d !== action.data;
});
return {
...state,
userDefinedGenes: newUserDefinedGenes
};
}
case "reset colorscale": {
const { world } = state;
const colorName = new Array(world.nObs).fill(globals.defaultCellColor);
const colorRGB = _.map(colorName, c => parseRGB(c));
return {
...state,
colorName,
colorRGB,
colorAccessor: null
};
}
case "expression load error":
case "initial data load error": {
return {