Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
a6b8041
alert boxes indicating validity of response
CaitlinOCallaghan Jun 11, 2018
5b45a6e
manually expand text box while rest of toolbar remains stationary
CaitlinOCallaghan Jun 11, 2018
48b56be
rephrase alert message
CaitlinOCallaghan Jun 11, 2018
443af65
take into account that min set size default is 5 and max is 200
CaitlinOCallaghan Jun 11, 2018
465f6a9
typo fix
CaitlinOCallaghan Jun 12, 2018
563579e
naming changes and comments
CaitlinOCallaghan Jun 12, 2018
f272f24
iterated name changes, data stored in map, input box is in editable d…
CaitlinOCallaghan Jun 13, 2018
3f9da72
alert boxes indicating validity of response
CaitlinOCallaghan Jun 11, 2018
62c268b
manually expand text box while rest of toolbar remains stationary
CaitlinOCallaghan Jun 11, 2018
a51ba53
rephrase alert message
CaitlinOCallaghan Jun 11, 2018
5047253
take into account that min set size default is 5 and max is 200
CaitlinOCallaghan Jun 11, 2018
f88efa7
typo fix
CaitlinOCallaghan Jun 12, 2018
99ae78d
naming changes and comments
CaitlinOCallaghan Jun 12, 2018
b37ab16
iterated name changes, data stored in map, input box is in editable d…
CaitlinOCallaghan Jun 13, 2018
7f036f0
divided large functions into multiple smaller functions, more comment…
CaitlinOCallaghan Jun 14, 2018
f55237a
further organization of functions and variable names
CaitlinOCallaghan Jun 14, 2018
f8c57aa
improve input status update, return genes in same order as typed
CaitlinOCallaghan Jun 15, 2018
5da1112
iterated response update
CaitlinOCallaghan Jun 15, 2018
7f342a8
store input data on state as a map, present invalid tokens in div for…
CaitlinOCallaghan Jun 19, 2018
431f6f6
input token methods stored in seperate file
CaitlinOCallaghan Jun 19, 2018
1ddd933
only send new tokens to validation service
CaitlinOCallaghan Jun 20, 2018
1918ded
Merge branch 'inputErrorCheck' of https://github.com/CaitlinOCallagha…
CaitlinOCallaghan Jun 20, 2018
699615b
comment out console.log and remove unnecessary css
CaitlinOCallaghan Jun 20, 2018
88d4d54
make Token-Input class a react component, render all input elements i…
CaitlinOCallaghan Jun 21, 2018
c7f1132
added change
CaitlinOCallaghan Jun 21, 2018
ca4494c
handle trailing spaces
CaitlinOCallaghan Jun 21, 2018
bbc6f46
move elements from InputToken component rendering to parent
CaitlinOCallaghan Jun 21, 2018
e5a7d08
move elements from InputToken component redering to parent, changes f…
CaitlinOCallaghan Jun 21, 2018
cc0e06a
use event listener instead of DOM
CaitlinOCallaghan Jun 22, 2018
32ca5e8
combine invalid input and gene input components
CaitlinOCallaghan Jun 26, 2018
e9a1ac9
lift state from token-input.js to index.js, use state for tracking al…
CaitlinOCallaghan Jun 26, 2018
2684bde
hide and show feedback box, hide toolbar
CaitlinOCallaghan Jun 27, 2018
87fb53e
auto expanding textareas
CaitlinOCallaghan Jun 27, 2018
c305b92
textarea styling, do not allow for manual resize
CaitlinOCallaghan Jun 28, 2018
dd5835f
empty graph so /enrichment will load on BaseNetworkView
CaitlinOCallaghan Jun 28, 2018
4baf17e
addressed error warnings, turned token-input rendering into a function
CaitlinOCallaghan Jun 29, 2018
5cdc483
merging development with inputErrorCheck
CaitlinOCallaghan Jun 29, 2018
8bf2341
change 'invalid' to 'unrecognized', only lift valid tokens to state (…
CaitlinOCallaghan Jun 29, 2018
5e67e38
change input-token.js to minimize number of functions, onClick 'submi…
CaitlinOCallaghan Jun 29, 2018
193f3de
send all tokens (valid and invalid) to index file for storage, improv…
CaitlinOCallaghan Jul 3, 2018
d8dcb1f
improved robustness, added catch
CaitlinOCallaghan Jul 3, 2018
9781fbf
use setState()
CaitlinOCallaghan Jul 3, 2018
9e72519
typo fix
CaitlinOCallaghan Jul 3, 2018
07807db
remove all instances of this.state = '' outside of constructor
CaitlinOCallaghan Jul 3, 2018
3385bb5
cleanup; added valid genes
jvwong Jul 4, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"react-router-dom": "^4.2.2",
"react-table": "^6.7.4",
"react-tabs": "^2.1.1",
"react-textarea-autosize": "^6.1.0",
"rethinkdb": "^2.3.3",
"sbgnml-to-cytoscape": "^4.0.4",
"serve-favicon": "^2.4.5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class BaseNetworkView extends React.Component {
layout.run();
}


changeMenu(menu) {
let resizeCyImmediate = () => this.state.cy.resize();
let resizeCyDebounced = _.debounce( resizeCyImmediate, 500 );
Expand Down Expand Up @@ -180,7 +181,7 @@ class BaseNetworkView extends React.Component {
// if 'titleContainer' exists from index file, unique title will render in 'div.title-container'
// default: metadata pathway name and database
const displayInfo = [
(this.props.titleContainer ? this.props.titleContainer : metadataTitles)
(this.props.titleContainer ? this.props.titleContainer() : metadataTitles)
];


Expand All @@ -196,7 +197,7 @@ class BaseNetworkView extends React.Component {
]),
h('div.title-container', displayInfo)
]),
h('div.view-toolbar', toolBar)
h('div.view-toolbar', {style: {display: this.props.closeToolBar == true ? 'none': 'inherit'}}, toolBar)
]),
h(Loader, {
loaded: !this.state.networkLoading,
Expand Down
109 changes: 65 additions & 44 deletions src/client/features/enrichment/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
const React = require('react');
const h = require('react-hyperscript');
//const queryString = require('query-string');
const _ = require('lodash');
//const Loader = require('react-loader');
//const queryString = require('query-string');

// const hideTooltips = require('../../common/cy/events/click').hideTooltips;
// const removeStyle= require('../../common/cy/manage-style').removeStyle;
// const make_cytoscape = require('../../common/cy/');
const make_cytoscape = require('../../common/cy/');
// const interactionsStylesheet= require('../../common/cy/interactions-stylesheet');
const TokenInput = require('./token-input');
const { BaseNetworkView } = require('../../common/components');
//const { getLayoutConfig } = require('../../common/cy/layout');
const { getLayoutConfig } = require('../../common/cy/layout');
//const downloadTypes = require('../../common/config').downloadTypes;

const enrichmentConfig={
Expand All @@ -20,61 +21,81 @@ const enrichmentConfig={
useSearchBar: true
};

//temporary empty network for development purposes
const emptyNetwork = {
graph: {
edges: [],
nodes: [],
pathwayMetadata: {
title: [],
datasource: [],
comments: []
},
layout: null
}
};
const network = emptyNetwork;
const layoutConfig = getLayoutConfig();

class Enrichment extends React.Component {
constructor(props) {
super(props);
this.state = {
cy: make_cytoscape({headless: true}),
componentConfig: enrichmentConfig,
networkMetadata: {
name: '',
datasource: '',
comments: []
},
query: '',
titleContainer: []
layoutConfig: layoutConfig,
networkJSON: network.graph,
networkMetadata: network.graph.pathwayMetadata,

//temporarily set to false so loading spinner is disabled
networkLoading: false,

closeToolBar: true,
//all submitted tokens, includes valid and invalid tokens
genes: [],
unrecognized: [],
inputs: ""
};

this.handleInputs = this.handleInputs.bind(this);
this.handleUnrecognized = this.handleUnrecognized.bind(this);
this.handleGenes = this.handleGenes.bind(this);
}

handleInputs( inputs ) {
this.setState({ inputs });
}

geneInputChange(e) {
this.setState( {query: e.target.value});
handleUnrecognized( unrecognized ) {
this.setState({ unrecognized });
}

geneInputSubmission(input){
const geneArray = input.split(/\n/g);
const inputObject = {genes: _.pull(geneArray,"")};
//console.log(geneArray);
//console.log(inputObject.genes);
//console.log(ServerAPI.geneQuery(inputObject));
return inputObject.genes;
handleGenes( genes ) {
this.setState( { genes } );console.log(genes);
}

render() {
const state = this.state;
const baseView = h(BaseNetworkView.component, {
componentConfig: state.componentConfig,
//titles at top of toolbar
networkMetadata: {},
titleContainer: [
h('h4', [
h('span', 'Pathway Enrichment '),]),
h('img', {
src: '/img/humanIcon.png'
}),
h('textarea.gene-input', {
placeholder: 'Enter one gene per line',
onChange: e => this.geneInputChange(e),
onKeyPress: e => this.geneInputChange(e)
}),
h('submit-container', {onClick: () => this.geneInputSubmission(this.state.query) },[
h('button.submit', 'Submit'),
])
]
let { cy, componentConfig, layoutConfig, networkJSON, networkMetadata, networkLoading } = this.state;
let retrieveTokenInput = () => h(TokenInput,{
inputs: this.state.inputs,
handleInputs: this.handleInputs,
handleUnrecognized: this.handleUnrecognized,
unrecognized: this.state.unrecognized,
handleGenes: this.handleGenes
});

return h(BaseNetworkView.component, {
cy,
componentConfig,
layoutConfig,
networkJSON,
networkMetadata,
networkLoading,
titleContainer: () => h(retrieveTokenInput),
//will use state to set to false to render the toolbar once analysis is run and graph is displayed
closeToolBar: true
});
//console.log(this.state.query);
return h('div.main', [baseView]);
}
}
module.exports = Enrichment;

//NOTE: CURRENTLY ONLY RENDERS ON PAGE WHEN base-network-view.js function 'componentDidMount(){}'
// IS COMMENTED OUT
module.exports = Enrichment;
80 changes: 80 additions & 0 deletions src/client/features/enrichment/token-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
const React = require('react');
const h = require('react-hyperscript');
const _ = require('lodash');
const { ServerAPI } = require('../../services/');
let Textarea = require('react-textarea-autosize').default;

class TokenInput extends React.Component {

constructor(props) {
super(props);
// Note on input contents: Set the initial value here from parent
// in order to maintain contents on re-render.
this.state = {
inputBoxContents: this.props.inputs
};
}
//store 'gene-input-box' contents on state
handleChange(e) {
this.setState({inputBoxContents: e.target.value});
}

//call validation service API to retrieve validation result in the form of []
retrieveValidationAPIResult(){
let tokenList = _.pull(this.state.inputBoxContents.split(/\s/g), "");
ServerAPI.enrichmentAPI({
genes: tokenList,
targetDb: "HGNCSYMBOL"
}, "validation")
.then( result => {
const aliases = result.geneInfo.map( value => {
return value.convertedAlias;
});
this.props.handleGenes( aliases );
this.props.handleUnrecognized( result.unrecognized );
this.props.handleInputs( this.state.inputBoxContents );
})
.catch(
error => error
);
}

render() {

const unrecognized = this.props.unrecognized;

return h('div.enrichmentInput', [
h('h4', [
h('span', 'Pathway Enrichment ')
]),
h('img', {
src: '/img/humanIcon.png'
}),
h('div.gene-input-container', [
h(Textarea, {
className: 'gene-input-box',
placeholder: 'Enter one gene per line',
value: this.state.inputBoxContents,
onChange: (e) => this.handleChange(e)
})
]),
h('submit-container', {
onClick: () => { this.retrieveValidationAPIResult();} },
[h('button.submit', 'Submit')]
),
h('div.unrecognized-token-container',[
h(Textarea, {
className:'unrecognized-tokens-feedback',
value: "Unrecognized Tokens: \n" + unrecognized.join("\n"),
readOnly: true,
//if unrecognizedTokens is its default value (ie no tokens have been added), feedback box not displayed
style: {display: _.isEmpty( unrecognized ) ? 'none' : 'block' }
})
])
]);
}
}

module.exports = TokenInput;


66 changes: 56 additions & 10 deletions src/styles/features/view/menuBar.css
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,16 @@
margin: 0;
margin-top: 5px;
}
/* css for human icon */
& img {
margin-top: 2px;
height: var(--icon-size);
width: auto;
}
/* css for human icon */
& img {
margin-top: 2px;
height: var(--icon-size);
width: auto;
}
}

.enrichmentInput {
display: flex;
}

.sidebar-tool-button-container {
Expand Down Expand Up @@ -148,18 +152,60 @@ _::-webkit-full-page-media, _:future, :root .view-toolbar{
padding: 0 0 1px 0 !important;
border-width: 0px !important;
}

.gene-input{
.gene-input-container{
height: 1.85em;
width: 200px;
}

.gene-input-box{
min-height: 1.85em;
max-height: 80%;
width: 200px;
background-color: white;
padding: 0em 0.5em;
box-sizing: border-box;
border: 1px solid var(--light-base-colour-dark);
border-right: none;
vertical-align: middle;
border-radius: 0 !important;
font-weight: normal;
position: fixed;
vertical-align: middle;
z-index: 1;
overflow-y:scroll;
line-height: 1.8;
resize: none;
}

.gene-input-box:empty:not(:focus):before {
content: attr(placeholder);
}

.unrecognized-token-container{
@extend %flex-center;

min-width: 200px;
position: absolute;
top: 100%;
left: -1px;
}

.unrecognized-tokens-feedback{
min-height: 1.85em;
max-height: 628px;
width: 200px;
background-color: white;
padding: 0em 0.5em;
border: 1px solid var(--light-base-colour-dark);
border-radius: 0 !important;
font-weight: normal;
vertical-align: middle;
z-index: 1;
overflow-y:scroll;
line-height: 1.8;
resize: none;
}

.unrecognized-tokens-feedback:empty{
display:none;
}

/* submit button for gene input */
Expand Down