Skip to content

Commit

Permalink
added regulon backend integration
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukasz Kreft committed Feb 19, 2018
1 parent 3b5ecc8 commit 5da6d18
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 51 deletions.
4 changes: 2 additions & 2 deletions scope-client/src/components/AppSidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ export default class AppSidebar extends Component {
BackendAPI.getConnection().then((gbc) => {
gbc.services.scope.Main.getMyLooms(query, (error, response) => {
if (response !== null) {
console.log("Loaded .loom files: " + response.l.length);
this.setState({ myLooms: response.l });
console.log("Loaded .loom files: " + response.loomFilePath.length);
this.setState({ myLooms: response.loomFilePath });
} else {
console.log("No .loom files detected. You can import one via Import .loom link.");
}
Expand Down
41 changes: 27 additions & 14 deletions scope-client/src/components/common/API.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,60 @@ class API {
this.GBCConnection = new this.GBC("ws://localhost:8081/", 'src/proto/s.proto', { scope: { Main: 'localhost:50052' } }).connect();
this.activeLoom = null;
this.features = {
0: {type: '', value: ''},
1: {type: '', value: ''},
2: {type: '', value: ''}
'gene': {
0: {type: 'gene', value: ''},
1: {type: 'gene', value: ''},
2: {type: 'gene', value: ''}
},
'regulon': {
0: {type: 'regulon', value: ''},
1: {type: 'regulon', value: ''},
2: {type: 'regulon', value: ''}
},
};
this.featureChangeListeners = [];
this.activeLoomChangeListeners = [];
this.hasLogTranform = true;
this.hasCpmTranform = true;
}

getConnection() {
return this.GBCConnection;
}


getActiveLoom() {
return this.activeLoom;
}

setActiveLoom(loom) {
this.activeLoom = loom;
this.activeLoomChangeListeners.forEach((listener) => {
listener(this.activeLoom);
})
}

getActiveLoom() {
return this.activeLoom;
onActiveLoomChange(listener) {
this.activeLoomChangeListeners.push(listener);
}


getActiveFeatures(type) {
return this.features[type];
}

setActiveFeature(featureId, featureType, featureValue) {
this.features[featureId] = { type: featureType, value: featureValue }
this.features[featureType][featureId] = { type: featureType, value: featureValue }
this.featureChangeListeners.forEach((listener) => {
listener(this.features);
listener(this.features[featureType]);
})
}

getActiveFeatures() {
return this.features;
}

onActiveFeaturesChange(listener) {
this.featureChangeListeners.push(listener);
}

onActiveLoomChange(listener) {
this.activeLoomChangeListeners.push(listener);
}


}

Expand Down
2 changes: 1 addition & 1 deletion scope-client/src/components/common/FeatureSearchBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default class FeatureSearchBar extends React.Component {
<Label color={this.colors[i]} style={querySearchLabel}></Label>
</Menu.Item>
<Menu.Item style={noPadding}>
<FeatureSearchBox key={i} id={i} color={this.colors[i]} type={type} locked={locked} />
<FeatureSearchBox key={i} id={i} color={this.colors[i]} type={type} locked={locked} value={this.props.activeFeatures[i].value} />
</Menu.Item>
</Menu>
</Menu.Item>
Expand Down
47 changes: 31 additions & 16 deletions scope-client/src/components/common/FeatureSearchBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ import { BackendAPI } from './API'

export default class FeatureSearch extends React.Component {

constructor() {
super()
constructor(props) {
super(props)
this.state = {
isLoading: false,
results: [],
value: ''
value: props.value
};
}

resetComponent() {
this.setState({ isLoading: false, results: [], value: '' })
BackendAPI.setActiveFeature(this.props.id, '', '');
BackendAPI.setActiveFeature(this.props.id, this.props.type, '');
}

handleResultSelect(e, { result }) {
Expand All @@ -29,21 +29,36 @@ export default class FeatureSearch extends React.Component {
setTimeout(() => {
if (this.state.value.length < 1) return this.resetComponent()
let query = {
lfp: BackendAPI.getActiveLoom(),
q: this.state.value
// featureType: this.props.type
// query: this.state.value
// loomFilePath: BackendAPI.getActiveLoom()
loomFilePath: BackendAPI.getActiveLoom(),
query: this.state.value
};
BackendAPI.getConnection().then((gbc) => {
gbc.services.scope.Main.getFeatures(query, (err, response) => {
let res = [];
if(response != null) {
let res_top = response.v.slice(0, 10).map((x) => {
return {"title": x}
});
// TODO: add featureType here
res = {"gene": {"name": this.props.type, "results":res_top}}
if (response != null) {
var genes = []
var regulons = []
for (var i = 0; i < response.feature.length; i++) {
if (response.featureType[i] == 'gene') {
genes.push({
"title": response.feature[i],
"type": response.featureType[i]
});
} else if (response.featureType[i] == 'regulon') {
regulons.push({
"title": response.feature[i],
"type": response.featureType[i]
});
}
};
genes = genes.slice(0, 10)
regulons = regulons.slice(0, 10)
let res = [];
if (this.props.type == 'gene') {
res = {"gene": {"name": this.props.type, "results":genes}}
}
if (this.props.type == 'regulon') {
res = {"regulon": {"name": this.props.type, "results":regulons}}
}
this.setState({
isLoading: false,
results: res,
Expand Down
38 changes: 29 additions & 9 deletions scope-client/src/components/common/TSNEViewer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,16 @@ export default class TSNEViewer extends Component {
if (this.props.loomFile != null) {
this.getPoints(this.props.loomFile);
}
if (this.props.activeFeatures != null) {
this.getFeatureColors(this.props.activeFeatures);
}
}

componentWillReceiveProps(nextProps) {
if (this.props.loomFile != nextProps.loomFile) {
this.getPoints(nextProps.loomFile);
}
console.log('props updated');
if (Object.is(this.props.activeFeatures, nextProps.activeFeatures)) {
console.log('new features');
this.getFeatureColors(nextProps.activeFeatures);
}
}
Expand Down Expand Up @@ -190,6 +191,7 @@ export default class TSNEViewer extends Component {
for (let i = 0; i < e.points.length; ++i)
this.updatePointColor(e.points[i],pts[e.points[i]].position.x,pts[e.points[i]].position.y,e.color)
this.endBenchmark();
this.clearLasso();
this.transformDataPoints();
}

Expand Down Expand Up @@ -361,7 +363,7 @@ export default class TSNEViewer extends Component {

getPoints(loomFile) {
let query = {
lfp: loomFile
loomFilePath: loomFile
};
this.startBenchmark("Getting point coordinates")
BackendAPI.getConnection().then((gbc) => {
Expand Down Expand Up @@ -415,17 +417,19 @@ export default class TSNEViewer extends Component {
getFeatureColors(features) {
this.startBenchmark("Getting point feature colors")
let query = {
lfp: this.props.loomFile,
f: [features[0].type, features[1].type, features[2].type],
e: [features[0].value, features[1].value, features[2].value],
lte: true, //this.props.logtransform
cpm: true //, this.props.cpmnormalise
loomFilePath: this.props.loomFile,
featureType: [features[0].type, features[1].type, features[2].type],
feature: [features[0].value, features[1].value, features[2].value],
hasLogTranform: true, //this.props.logtransform
hasCpmTranform: true //, this.props.cpmnormalise
};
BackendAPI.getConnection().then((gbc) => {
gbc.services.scope.Main.getCellColorByFeatures(query, (err, response) => {
if(response !== null) {
this.endBenchmark()
this.updateDataPoints(response.v)
this.updateDataPoints(response.color)
} else {
this.resetDataPoints()
}
});
});
Expand All @@ -447,6 +451,22 @@ export default class TSNEViewer extends Component {
this.transformDataPoints();
}

resetDataPoints() {
this.startBenchmark("Resetting point colors")
let pts = this.container.children;
let n = pts.length;
// Draw new data points
for (let i = 0; i < n; ++i) {
let point = this.getTexturedColorPoint(pts[i].position.x, pts[i].position.y, '000000')
this.container.addChildAt(point, n+i);
}
// Remove the first old data points (firstly rendered)
this.container.removeChildren(0, n)
this.endBenchmark();
// Call for rendering
this.transformDataPoints();
}

startBenchmark(msg) {
this.setState({ benchmark: { t1: performance.now(), msg: msg } })
}
Expand Down
6 changes: 3 additions & 3 deletions scope-client/src/components/pages/Expression.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ export default class Expression extends Component {
super();
this.state = {
activeLoom: BackendAPI.getActiveLoom(),
activeFeatures: BackendAPI.getActiveFeatures()
activeFeatures: BackendAPI.getActiveFeatures('gene')
}
console.log('features', this.state.activeFeatures);
BackendAPI.onActiveLoomChange((loom) => {
this.setState({activeLoom: loom});
});
BackendAPI.onActiveFeaturesChange((features) => {
console.log('feature changed', features)
this.setState({activeFeatures: features});
});
}
Expand All @@ -29,7 +29,7 @@ export default class Expression extends Component {
</div>
<div style={{display: activeLoom != null ? 'block' : 'none'}}>
Select up to three genes to be displayed on tSNE <br />
<FeatureSearchBar type="gene" locked="1" />
<FeatureSearchBar type="gene" locked="1" activeFeatures={activeFeatures} />
<TSNEViewer width="1000" height="800" loomFile={activeLoom} activeFeatures={activeFeatures} />
</div>
</div>
Expand Down
13 changes: 9 additions & 4 deletions scope-client/src/components/pages/Regulon.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,29 @@ export default class Regulon extends Component {
constructor() {
super();
this.state = {
activeLoom: BackendAPI.getActiveLoom()
activeLoom: BackendAPI.getActiveLoom(),
activeFeatures: BackendAPI.getActiveFeatures('regulon')
}
console.log('features', this.state.activeFeatures);
BackendAPI.onActiveLoomChange((loom) => {
this.setState({activeLoom: loom});
});
BackendAPI.onActiveFeaturesChange((features) => {
this.setState({activeFeatures: features});
});
}

render() {
const { activeLoom } = this.state;
const { activeLoom, activeFeatures } = this.state;
return (
<div>
<div style={{display: activeLoom == null ? 'block' : 'none'}}>
Select the dataset to be analyzed
</div>
<div style={{display: activeLoom != null ? 'block' : 'none'}}>
Select up to three regulons to be displayed on tSNE <br />
<FeatureSearchBar type="regulon" locked="1" />
<TSNEViewer width="600" height="600" loomFile={activeLoom}/>
<FeatureSearchBar type="regulon" locked="1" activeFeatures={activeFeatures} />
<TSNEViewer width="1000" height="800" loomFile={activeLoom} activeFeatures={activeFeatures} />
</div>
</div>
);
Expand Down
2 changes: 0 additions & 2 deletions scope-client/src/components/pages/Welcome.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { Segment, Header } from 'semantic-ui-react'

export default class Welcome extends Component {



render() {
return (
<div>
Expand Down

0 comments on commit 5da6d18

Please sign in to comment.