Skip to content

Commit

Permalink
Further fixes to sparkline view; order by gene
Browse files Browse the repository at this point in the history
  • Loading branch information
slinnarsson committed Jan 24, 2016
1 parent 201107e commit df9d2d8
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 168 deletions.
17 changes: 1 addition & 16 deletions js/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,13 @@ function receiveGene(gene, list) {
}
}

function rowForGene(rowAttrs, gene) {
var index = -1;
Object.keys(rowAttrs).forEach((key)=>{
var temp = rowAttrs[key].indexOf(gene);
if(temp >= 0) {
index = temp;
}
});
return index;
}

// Thunk action creator, following http://rackt.org/redux/docs/advanced/AsyncActions.html
// Though its insides are different, you would use it just like any other action creator:
// store.dispatch(fetchgene(...))

export function fetchGene(rowAttrs, gene, cache) {
return dispatch => {
console.log("fetchGene");
var row = rowForGene(rowAttrs, gene, cache);
var row = rowAttrs["Gene"].indexOf(gene);
if(row == -1) {
return;
}
Expand All @@ -52,18 +40,15 @@ export function fetchGene(rowAttrs, gene, cache) {
// First, make known the fact that the request has been started
dispatch(requestGene(gene));
// Second, perform the request (async)
console.log("Requesting data.");
return fetch(`/row/${row}`)
.then(response => response.json())
.then(json => {
// Third, once the response comes in, dispatch an action to provide the data
dispatch(receiveGene(gene, json))
console.log("Received data.");
})
// Or, if it failed, dispatch an action to set the error flag
.catch(err => {
dispatch(requestGeneFailed(gene));
console.log("Failed to receive data.");
});
}
}
2 changes: 1 addition & 1 deletion js/heatmap-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class HeatmapView extends Component {
dataRange={[hs.dataBounds[0],hs.dataBounds[2]]}
screenRange={[hs.screenBounds[0],hs.screenBounds[2]]}
mode={hs.colMode}
/>
/>
<Heatmap
zoom={hs.zoom}
center={hs.center}
Expand Down
132 changes: 96 additions & 36 deletions js/landscape-sidepanel.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,54 @@
import React, { Component, PropTypes } from 'react';
import { fetchGene } from './actions.js';



export class LandscapeSidepanel extends Component {
render() {
var xOptions = Object.keys(this.props.colAttrs).sort().map((name)=> {
return <li key={name}><a onClick={(event)=>{this.props.onXCoordinateChange(name);}}>{name}</a></li>;
var start = performance.now();
var temp = this.render0();
console.log("Sidepanel: " + (performance.now() - start).toString());
return temp;
}
render0() {
var dispatch = this.props.dispatch;
var fi = this.props.fileInfo;
var ls = this.props.landscapeState;
var ds = this.props.dataState;

var temp = Object.keys(fi.colAttrs).sort();
temp.push("(gene)");
var xOptions = temp.map((name)=> {
return <li key={name}>
<a onClick={(event)=>dispatch({
type: 'SET_LANDSCAPE_PROPS',
xCoordinate: name
})}>
{name}
</a>
</li>;
});
//xOptions.push(<li key="(gene)"><a>(gene)</a></li>);

var yOptions = Object.keys(this.props.colAttrs).sort().map((name)=> {
return <li key={name}><a onClick={(event)=>{this.props.onYCoordinateChange(name);}}>{name}</a></li>;
var temp = Object.keys(fi.colAttrs).sort();
temp.push("(gene)");
var yOptions = temp.map((name)=> {
return <li key={name}><a onClick={(event)=>dispatch({
type: 'SET_LANDSCAPE_PROPS',
yCoordinate: name
})}>{name}</a></li>;
});
//yOptions.push(<li key="(gene)"><a>(gene)</a></li>);

var colorOptions = Object.keys(this.props.colAttrs).sort().map((name)=> {
return <li key={name}><a onClick={(event)=>{this.props.onColorAttrChange(name);}}>{name}</a></li>;
var temp = Object.keys(fi.colAttrs).sort();
temp.push("(gene)");
var colorOptions = temp.map((name)=> {
return <li key={name}><a onClick={(event)=>dispatch({
type: 'SET_LANDSCAPE_PROPS',
colorAttr: name
})}>{name}</a></li>;
});
colorOptions.push(<li key="(gene)"><a onClick={(event)=>{this.props.onColorAttrChange("(gene)");}}>(gene)</a></li>);

var isTSNE = (this.props.xCoordinate == '_tSNE1') && (this.props.yCoordinate == '_tSNE2');
var isPCA = (this.props.xCoordinate == '_PC1') && (this.props.yCoordinate == '_PC2');
var isTSNE = (ls.xCoordinate == '_tSNE1') && (ls.yCoordinate == '_tSNE2');
var isPCA = (ls.xCoordinate == '_PC1') && (ls.yCoordinate == '_PC2');

return(
<div className="panel panel-default">
Expand All @@ -33,14 +61,22 @@ export class LandscapeSidepanel extends Component {
<button
type="button"
className={"btn" + (isTSNE ? " btn-success" : " btn-default")}
onClick={(event=>{this.props.onXCoordinateChange('_tSNE1'); this.props.onYCoordinateChange('_tSNE2');})}
onClick={(event)=>dispatch({
type: 'SET_LANDSCAPE_PROPS',
xCoordinate: '_tSNE1',
yCoordinate: '_tSNE2'
})}
>tSNE</button>
</div>
<div className="btn-group" role="group">
<button
type="button"
className={"btn" + (isPCA ? " btn-success" : " btn-default")}
onClick={(event=>{this.props.onXCoordinateChange('_PC1'); this.props.onYCoordinateChange('_PC2');})}
onClick={(event)=>dispatch({
type: 'SET_LANDSCAPE_PROPS',
xCoordinate: '_PC1',
yCoordinate: '_PC2'
})}
>PCA</button>
</div>
</div>
Expand All @@ -50,49 +86,85 @@ export class LandscapeSidepanel extends Component {
<label>X Coordinate</label>
<div className="btn-group btn-block">
<button type="button" className="btn btn-block btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{this.props.xCoordinate + " "}<span className="caret"></span>
{ls.xCoordinate + " "}<span className="caret"></span>
</button>
<ul className="dropdown-menu btn-block scrollable-menu">
{xOptions}
</ul>
</div>
<div className="btn-group btn-block">
{ls.xCoordinate == "(gene)" ?
<input className="form-control" placeholder="Gene" value={ls.xGene} onChange={(event)=>{
dispatch({
type: 'SET_LANDSCAPE_PROPS',
xGene: event.target.value
});
dispatch(fetchGene(fi.rowAttrs, event.target.value, ds.genes));
}}/> :
<span></span>
}
</div>
</div>


<div className="form-group">
<label>Y Coordinate</label>
<div className="btn-group btn-block">
<button type="button" className="btn btn-block btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{this.props.yCoordinate + " "}<span className="caret"></span>
{ls.yCoordinate + " "}<span className="caret"></span>
</button>
<ul className="dropdown-menu btn-block scrollable-menu">
{yOptions}
</ul>
</div>
<div className="btn-group btn-block">
{ls.yCoordinate == "(gene)" ?
<input className="form-control" placeholder="Gene" value={ls.yGene} onChange={(event)=>{
dispatch({
type: 'SET_LANDSCAPE_PROPS',
yGene: event.target.value
});
dispatch(fetchGene(fi.rowAttrs, event.target.value, ds.genes));
}}/> :
<span></span>
}
</div>
</div>

<div className="form-group">
<label>Color</label>
<div className="btn-group btn-block">
<button type="button" className="btn btn-block btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{this.props.colorAttr + " "}<span className="caret"></span>
{ls.colorAttr + " "}<span className="caret"></span>
</button>
<ul className="dropdown-menu btn-block scrollable-menu">
{colorOptions}
</ul>
</div>
<div className="btn-group btn-block">
<button type="button" className="btn btn-block btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{this.props.colorMode + " "}<span className="caret"></span>
{ls.colorMode + " "}<span className="caret"></span>
</button>
<ul className="dropdown-menu">
<li key="Categorical"><a onClick={(event)=>{this.props.onColorModeChange("Categorical");}}>Categorical</a></li>
<li key="Heatmap"><a onClick={(event)=>{this.props.onColorModeChange("Heatmap");}}>Quantitative</a></li>
<li key="Categorical"><a onClick={(event)=>dispatch({
type: 'SET_LANDSCAPE_PROPS',
colorMode: 'Categorical'
})}>Categorical</a></li>
<li key="Heatmap"><a onClick={(event)=>dispatch({
type: 'SET_LANDSCAPE_PROPS',
colorMode: 'Heatmap'
})}>Quantitative</a></li>
</ul>
</div>
<div className="btn-group btn-block">
{this.props.colorAttr == "(gene)" ?
<input className="form-control" placeholder="Gene" value={this.props.colorGene} onChange={(event)=>{this.props.onColorGeneChange(event.target.value)}}/> :
{ls.colorAttr == "(gene)" ?
<input className="form-control" placeholder="Gene" value={ls.colorGene} onChange={(event)=>{
dispatch({
type: 'SET_LANDSCAPE_PROPS',
colorGene: event.target.value
});
dispatch(fetchGene(fi.rowAttrs, event.target.value, ds.genes));
}}/> :
<span></span>
}
</div>
Expand All @@ -106,19 +178,7 @@ export class LandscapeSidepanel extends Component {
}

LandscapeSidepanel.propTypes = {
colAttrs: PropTypes.object.isRequired,
xCoordinate: PropTypes.string.isRequired,
xGene: PropTypes.string.isRequired,
yCoordinate: PropTypes.string.isRequired,
yGene: PropTypes.string.isRequired,
colorAttr: PropTypes.string.isRequired,
colorMode: PropTypes.string.isRequired,
colorGene: PropTypes.string.isRequired,
onXCoordinateChange: PropTypes.func.isRequired,
onYCoordinateChange: PropTypes.func.isRequired,
onColorAttrChange: PropTypes.func.isRequired,
onColorModeChange: PropTypes.func.isRequired,
onColorGeneChange: PropTypes.func.isRequired,
onXGeneChange: PropTypes.func.isRequired,
onYGeneChange: PropTypes.func.isRequired
landscapeState: PropTypes.object.isRequired,
fileInfo: PropTypes.object.isRequired,
dataState: PropTypes.object.isRequired
}
51 changes: 23 additions & 28 deletions js/landscape-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,42 @@ export class LandscapeView extends Component {
return data;
}
render() {
var color = this.makeData(this.props.landscapeState.colorAttr, this.props.landscapeState.colorGene);
var x = this.makeData(this.props.landscapeState.xCoordinate, this.props.landscapeState.xGene);
var y = this.makeData(this.props.landscapeState.yCoordinate, this.props.landscapeState.yGene);
var start = performance.now();
var temp = this.render0();
console.log("View: " + (performance.now() - start).toString());
return temp;
}
render0() {
var dispatch = this.props.dispatch;
var fi = this.props.fileInfo;
var ls = this.props.landscapeState;
var ds = this.props.dataState;

var color = this.makeData(ls.colorAttr, ls.colorGene);
var x = this.makeData(ls.xCoordinate, ls.xGene);
var y = this.makeData(ls.yCoordinate, ls.yGene);
return (
<div className="container-fluid">
<div className="row">
<div className="col-xs-6 col-sm-3">
<LandscapeSidepanel
colAttrs={this.props.fileInfo.colAttrs}
xCoordinate={this.props.landscapeState.xCoordinate}
xGene={this.props.landscapeState.xGene}
yCoordinate={this.props.landscapeState.yCoordinate}
yGene={this.props.landscapeState.yGene}
colorAttr={this.props.landscapeState.colorAttr}
colorMode={this.props.landscapeState.colorMode}
colorGene={this.props.landscapeState.colorGene}

onXCoordinateChange={this.props.onXCoordinateChange}
onYCoordinateChange={this.props.onYCoordinateChange}
onColorModeChange={this.props.onColorModeChange}
onColorAttrChange={this.props.onColorAttrChange}
onXGeneChange={this.props.onXGeneChange}
onYGeneChange={this.props.onYGeneChange}
onColorGeneChange={this.props.onColorGeneChange}
fileInfo={fi}
landscapeState={ls}
dataState={ds}
dispatch={dispatch}
/>
</div>
<div className="col-xs-12 col-sm-9 no-line-space">
<Scatterplot
x={x}
y={y}
color={color}
colorMode={this.props.landscapeState.colorMode}
colorMode={ls.colorMode}
width={800}
height={600}
logScale={this.props.landscapeState.colorAttr == "(gene)"}
logScaleColor={ls.colorAttr == "(gene)"}
logScaleX={ls.xCoordinate == "(gene)"}
logScaleY={ls.yCoordinate == "(gene)"}
/>
</div>
</div>
Expand All @@ -62,11 +63,5 @@ LandscapeView.propTypes = {
dataState: PropTypes.object.isRequired,
landscapeState: PropTypes.object.isRequired,
fileInfo: PropTypes.object.isRequired,
onXCoordinateChange: PropTypes.func.isRequired,
onYCoordinateChange: PropTypes.func.isRequired,
onColorModeChange: PropTypes.func.isRequired,
onColorAttrChange: PropTypes.func.isRequired,
onColorGeneChange: PropTypes.func.isRequired,
onXGeneChange: PropTypes.func.isRequired,
onYGeneChange: PropTypes.func.isRequired
dispatch: PropTypes.func.isRequired
}
Loading

0 comments on commit df9d2d8

Please sign in to comment.