gramene-search 1.2.39 → 1.2.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gramene-search",
3
- "version": "1.2.39",
3
+ "version": "1.2.41",
4
4
  "description": "search wrapper for gramene",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -3,11 +3,11 @@ const grameneViews = {
3
3
  getReducer: () => {
4
4
  const initialState = {
5
5
  options: [
6
- // {
7
- // id: 'help',
8
- // name: 'Help / Demo',
9
- // show: 'off'
10
- // },
6
+ {
7
+ id: 'help',
8
+ name: 'Help / Demo',
9
+ show: 'off'
10
+ },
11
11
  {
12
12
  id: 'taxonomy',
13
13
  name: 'Taxonomic distribution',
@@ -17,12 +17,12 @@ const grameneViews = {
17
17
  id: 'list',
18
18
  name: 'Gene list',
19
19
  show: 'on'
20
- }
20
+ // },
21
21
  // {
22
22
  // id: 'pathways',
23
23
  // name: 'Pathways',
24
24
  // show: 'disabled'
25
- // },
25
+ }
26
26
  // {
27
27
  // id: 'domains',
28
28
  // name: 'Domains',
@@ -178,10 +178,7 @@ const ResultsCmp = props => {
178
178
  v.idx = idx;
179
179
  return v.show === 'on'
180
180
  });
181
- // if (props.grameneFilters.rightIdx === 1 || activeViews.length === 0) {
182
- // return <HelpDemo/>
183
- // }
184
- return props.grameneFilters.rightIdx > 1 ? (
181
+ return props.grameneFilters.rightIdx > 0 ? (
185
182
  <div style={{padding:'10px'}}>
186
183
  {activeViews.map(v => {
187
184
  let p = Object.assign({}, props);
@@ -209,6 +206,16 @@ const Results = connect(
209
206
  const ViewsCmp = props => (
210
207
  <div className={'gramene-view-container'}>
211
208
  <b>Views</b>
209
+ {/*{props.grameneViews.options.map((view,idx) => (*/}
210
+ {/* <div key={idx}>*/}
211
+ {/* <input type="checkbox" className='toggle-switch' id={`toggle${idx}`} onChange={(e) => {*/}
212
+ {/* if (view.show !== 'disabled') {*/}
213
+ {/* props.doToggleGrameneView(idx)*/}
214
+ {/* }*/}
215
+ {/* }} disabled={view.show === 'disabled'} checked={view.show === 'on'}/>*/}
216
+ {/* <label for={`toggle${idx}`}>{view.show}</label>{view.name}*/}
217
+ {/* </div>*/}
218
+ {/*))}*/}
212
219
  <ul className={'gramene-view'}>
213
220
  {props.grameneViews.options.map((view,idx) => (
214
221
  <li key={idx} className={`gramene-view-${view.show}`}
@@ -228,7 +235,6 @@ const ViewsCmp = props => (
228
235
  {/* <li className='gramene-view-disabled'>Disabled</li>*/}
229
236
  {/* </ul>*/}
230
237
  {/*</div>*/}
231
- &nbsp;
232
238
  </div>
233
239
  );
234
240
 
@@ -7,8 +7,9 @@ import Homology from './details/Homology'
7
7
  import Location from './details/Location'
8
8
  import Pathways from "./details/Pathways"
9
9
  import Xrefs from "./details/Xrefs"
10
+ import Publications from "./details/Publications"
10
11
  import {GrFormPrevious, GrFormNextLink, GrFormNext, GrHpe} from 'react-icons/gr'
11
- import { Badge } from 'react-bootstrap'
12
+ import { Badge, OverlayTrigger, Tooltip } from 'react-bootstrap'
12
13
 
13
14
  let external = <small title="This link opens a page from an external site"> <i className="fa fa-external-link"/></small>;
14
15
 
@@ -17,7 +18,8 @@ let inventory = {
17
18
  expression: Expression,
18
19
  homology: Homology,
19
20
  pathways: Pathways,
20
- xrefs: Xrefs
21
+ xrefs: Xrefs,
22
+ pubs: Publications
21
23
  };
22
24
 
23
25
  function renderTairSummary(searchResult) {
@@ -102,31 +104,37 @@ class Gene extends React.Component {
102
104
  {
103
105
  id: 'location',
104
106
  label: 'Location',
107
+ popup: 'Genome Browser',
105
108
  available: false
106
109
  },
107
110
  {
108
111
  id: 'expression',
109
112
  label: 'Expression',
113
+ popup: 'Gene Expression Atlas',
110
114
  available: false
111
115
  },
112
116
  {
113
117
  id: 'homology',
114
118
  label: 'Homology',
119
+ popup: 'Gene Family Tree',
115
120
  available: false
116
121
  },
117
122
  {
118
123
  id: 'pathways',
119
124
  label: 'Pathways',
125
+ popup: 'Plant Reactome Pathways',
126
+ available: false
127
+ },
128
+ {
129
+ id: 'pubs',
130
+ label: 'Papers',
131
+ popup: 'Curated Publications',
120
132
  available: false
121
133
  },
122
- // {
123
- // id: 'pubs',
124
- // label: 'Publications',
125
- // available: false
126
- // },
127
134
  {
128
135
  id: 'xrefs',
129
136
  label: 'Xrefs',
137
+ popup: 'Database Cross-references',
130
138
  available: false
131
139
  }
132
140
  ],
@@ -202,10 +210,18 @@ class Gene extends React.Component {
202
210
  </div>
203
211
  <div className="gene-detail-tabs">
204
212
  {this.state.details.map((d,idx) => (
213
+ <OverlayTrigger
214
+ key={idx}
215
+ placement={'bottom'}
216
+ overlay={
217
+ <Tooltip id={`tooltip`}>{d.popup}</Tooltip>
218
+ }
219
+ >
205
220
  <div key={idx}
206
221
  className={`col-md-1 text-center gene-detail-tab-${this.getDetailStatus(d)}`}
207
222
  onClick={()=>this.setExpanded(d)}
208
223
  >{d.label}</div>
224
+ </OverlayTrigger>
209
225
  ))}
210
226
  </div>
211
227
  {this.state.expandedDetail && this.ensureGene(searchResult.id) && <div className="visible-detail">{React.createElement(inventory[this.state.expandedDetail], this.props)}</div>}
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
  import {connect} from "redux-bundler-react";
3
- import {Alert, Container, Row, Card, CardDeck} from 'react-bootstrap'
3
+ import {Alert, Container, Row, Card, CardGroup} from 'react-bootstrap'
4
4
  import './genes.css'
5
5
 
6
6
  const examples = [
@@ -85,7 +85,7 @@ const HelpDemo = ({configuration,doReplaceGrameneFilters}) => (
85
85
  <h3>Search Features</h3>
86
86
  </Row>
87
87
  <Row>
88
- <CardDeck style={{width:'80%'}}>
88
+ <CardGroup style={{width:'80%'}}>
89
89
  <Card style={{'backgroundColor':'#f3f6f5', 'borderColor':'#DDE5E3'}}>
90
90
  <Card.Body>
91
91
  <Card.Title>Suggestions</Card.Title>
@@ -107,7 +107,7 @@ const HelpDemo = ({configuration,doReplaceGrameneFilters}) => (
107
107
  <div className='gene-search-pic-genetree'/>
108
108
  </Card.Body>
109
109
  </Card>
110
- </CardDeck>
110
+ </CardGroup>
111
111
  </Row>
112
112
  <Row>
113
113
  <h4>For Example</h4>
@@ -35,7 +35,11 @@ class TaxDist extends React.Component {
35
35
  }
36
36
  return (
37
37
  <div className="results-vis big-vis">
38
- <button type="button" className="btn btn-primary btn-sm" onClick={this.toggleEmpties.bind(this)}>{this.state.collapseEmpties ? 'Expand' : 'Collapse'} empty branches</button>
38
+ {this.props.grameneTaxDist && <button type="button"
39
+ className="btn btn-primary btn-sm"
40
+ onClick={this.toggleEmpties.bind(this)}>
41
+ {this.state.collapseEmpties ? 'Expand' : 'Collapse'} empty branches
42
+ </button>}
39
43
  {this.props.grameneTaxDist && <Vis taxonomy={this.props.grameneTaxDist}
40
44
  selectedTaxa={selectedTaxa}
41
45
  onSelection={this.handleSelection.bind(this)}
@@ -0,0 +1,145 @@
1
+ import React from 'react'
2
+ import ReactGA from 'react-ga'
3
+ // import {connect} from "redux-bundler-react";
4
+ import _ from 'lodash'
5
+ import dbxrefs from 'gramene-dbxrefs';
6
+ import {Detail, Title, Description, Content} from "./generic";
7
+
8
+ const HOW_MANY_TO_SHOW_BY_DEFAULT = 10;
9
+
10
+ class Xref extends React.Component {
11
+ constructor(props) {
12
+ super(props);
13
+ this.state = {showAll: false};
14
+ }
15
+
16
+ toggleShowAll() {
17
+ this.setState({showAll: !this.state.showAll});
18
+ }
19
+
20
+ possiblyTruncateList(vals) {
21
+ var ellipsis, ellipsisChar, ellipsisTitle;
22
+
23
+ if (vals.length > HOW_MANY_TO_SHOW_BY_DEFAULT) {
24
+ if (this.state.showAll) {
25
+ ellipsisChar = '^ show first ' + HOW_MANY_TO_SHOW_BY_DEFAULT;
26
+ ellipsisTitle = 'Show less';
27
+ }
28
+ else {
29
+ ellipsisChar = '… show all (' + (vals.length - HOW_MANY_TO_SHOW_BY_DEFAULT) + ' more)';
30
+ ellipsisTitle = 'Show more';
31
+ vals = vals.slice(0, HOW_MANY_TO_SHOW_BY_DEFAULT);
32
+ }
33
+
34
+ ellipsis = (
35
+ <li key="showMore" className="showAll">
36
+ <a title={ellipsisTitle} onClick={this.toggleShowAll.bind(this)}>{ellipsisChar}</a>
37
+ </li>
38
+ );
39
+
40
+ vals.push(ellipsis);
41
+ }
42
+
43
+ return vals;
44
+ }
45
+
46
+ render() {
47
+ var db = this.props.xref.label;
48
+ var urlfcn = this.props.xref.url;
49
+
50
+ var members = this.props.members.sort();
51
+
52
+ var vals = members.map(function (item, idx) {
53
+ var url = urlfcn(item),
54
+ liClass = idx < HOW_MANY_TO_SHOW_BY_DEFAULT ? "default" : "extra";
55
+ let external = <small title="This link opens a page from an external site"> <i className="fa fa-external-link"/></small>;
56
+ return (
57
+ <li key={idx} className={liClass}>
58
+ <ReactGA.OutboundLink
59
+ eventLabel={db}
60
+ to={url}
61
+ target="_blank"
62
+ >
63
+ {item}{external}
64
+ </ReactGA.OutboundLink>
65
+ </li>
66
+ )
67
+ })
68
+
69
+ vals = this.possiblyTruncateList(vals);
70
+
71
+ return (
72
+ <tr>
73
+ {/*<td className="xref-name-col">{db}</td>*/}
74
+ <td className="xref-value-col">
75
+ <ol className="xref-id-list">{vals}</ol>
76
+ </td>
77
+ <td className="xref-name-col">{this.props.source}</td>
78
+ <td className="xref-value-col">{this.props.text}</td>
79
+ </tr>
80
+ );
81
+ }
82
+ }
83
+
84
+ function formatPubsForGene(gene) {
85
+ if(!gene || !_.isArray(gene.xrefs)) {
86
+ throw new Error("No xrefs for " + _.get(gene._id));
87
+ }
88
+ return gene.xrefs
89
+ .filter(xr => xr.db === "PUBMED") //dbxrefs.isKnown(xr.db))
90
+ .sort((a,b) => {
91
+ if (a.source) {
92
+ if (b.source) {
93
+ if (a.source < b.source) {
94
+ return -1;
95
+ }
96
+ if (a.source > b.source) {
97
+ return 1;
98
+ }
99
+ }
100
+ else {
101
+ return -1;
102
+ }
103
+ }
104
+ else if (b.source) {
105
+ return 1;
106
+ }
107
+ if (a.db < b.db) {
108
+ return -1;
109
+ }
110
+ if (a.db > b.db) {
111
+ return 1;
112
+ }
113
+ return 0;
114
+ })
115
+ .map((xr,idx) => {
116
+ var xref = dbxrefs.fetch(xr.db);
117
+ return (
118
+ <Xref key={idx} xref={xref} members={xr.ids} source={xr.source} text={xr.text} />
119
+ )
120
+ })
121
+ }
122
+
123
+ const Publications = ({searchResult, geneDocs}) => (
124
+ <Detail>
125
+ <Title key="title">Curated publications</Title>
126
+ <Description key="description">This gene has been described in the literature:</Description>
127
+ <Content key="content">
128
+ <table className="xrefs table">
129
+ <thead>
130
+ <tr>
131
+ <th className="xref-10-col">PubMed link</th>
132
+ <th className="xref-10-col">Curation source</th>
133
+ <th className="xref-80-col">Title/Description</th>
134
+ </tr>
135
+ </thead>
136
+ <tbody>
137
+ {formatPubsForGene(geneDocs[searchResult.id])}
138
+ </tbody>
139
+ </table>
140
+ </Content>
141
+ </Detail>
142
+ );
143
+
144
+ export default Publications;
145
+
@@ -74,8 +74,6 @@ class Xref extends React.Component {
74
74
  <td className="xref-value-col">
75
75
  <ol className="xref-id-list">{vals}</ol>
76
76
  </td>
77
- <td className="xref-name-col">{this.props.source}</td>
78
- <td className="xref-value-col">{this.props.text}</td>
79
77
  </tr>
80
78
  );
81
79
  }
@@ -86,32 +84,8 @@ function formatXrefsForGene(gene) {
86
84
  throw new Error("No xrefs for " + _.get(gene._id));
87
85
  }
88
86
  return gene.xrefs
89
- .filter(xr => dbxrefs.isKnown(xr.db))
90
- .sort((a,b) => {
91
- if (a.source) {
92
- if (b.source) {
93
- if (a.source < b.source) {
94
- return -1;
95
- }
96
- if (a.source > b.source) {
97
- return 1;
98
- }
99
- }
100
- else {
101
- return -1;
102
- }
103
- }
104
- else if (b.source) {
105
- return 1;
106
- }
107
- if (a.db < b.db) {
108
- return -1;
109
- }
110
- if (a.db > b.db) {
111
- return 1;
112
- }
113
- return 0;
114
- })
87
+ .filter(xr => dbxrefs.isKnown(xr.db) && xr.db !== "PUBMED")
88
+ .sort()
115
89
  .map((xr,idx) => {
116
90
  var xref = dbxrefs.fetch(xr.db);
117
91
  return (
@@ -128,10 +102,8 @@ const Xrefs = ({searchResult, geneDocs}) => (
128
102
  <table className="xrefs table">
129
103
  <thead>
130
104
  <tr>
131
- <th className="xref-10-col">Database</th>
132
- <th className="xref-10-col">IDs and links</th>
133
- <th className="xref-10-col">Source</th>
134
- <th className="xref-70-col">Text</th>
105
+ <th className="xref-name-col">Database</th>
106
+ <th className="xref-value-col">IDs and links</th>
135
107
  </tr>
136
108
  </thead>
137
109
  <tbody>
@@ -24,6 +24,9 @@
24
24
  .xref-value-col {
25
25
  width: 80%;
26
26
  }
27
+ .xref-80-col {
28
+ width: 80%;
29
+ }
27
30
  .xref-70-col {
28
31
  width: 70%;
29
32
  }
@@ -9,6 +9,7 @@
9
9
  .gramene-filter-container {
10
10
  background-color: #cfb5e6;
11
11
  padding-left: 4px;
12
+ padding-bottom: 4px;
12
13
  }
13
14
  .gramene-filter {
14
15
  padding-left: 4px;
@@ -56,11 +57,14 @@
56
57
 
57
58
  .gramene-view-container {
58
59
  background-color: lightblue;
59
- padding-left: 10px;
60
+ padding-left: 4px;
61
+ padding-right: 4px;
62
+ padding-bottom: 4px;
60
63
  }
61
64
  .gramene-view {
62
- padding-left: 5px;
63
- margin: 4px;
65
+ padding-left: 0px;
66
+ padding-right: 10px;
67
+ margin-bottom: 0;
64
68
  background-color: white;
65
69
  }
66
70
  .gramene-view li {
@@ -68,19 +72,22 @@
68
72
  cursor: pointer;
69
73
  padding-left: 5px;
70
74
  border-left-style: inset;
71
- border-left-width: 4px;
75
+ border-left-width: 8px;
72
76
  margin-bottom: 2px;
73
77
  }
74
78
 
75
79
  .gramene-view-on {
76
80
  border-left-color: #40a0ff;
81
+ font-weight: bold;
77
82
  }
78
83
  .gramene-view-off {
79
84
  border-left-color: #ff6d68;
85
+ color: grey;
80
86
  }
81
87
  .gramene-view-disabled {
82
88
  color: darkgray;
83
89
  border-left-color: #efefef;
90
+ cursor: default!important;
84
91
  }
85
92
  #gramene-suggestion button {
86
93
  border-radius: .6rem;
@@ -90,4 +97,5 @@
90
97
  color: #fff;
91
98
  background-color: #6c757d;
92
99
  border-color: #6c757d;
93
- }
100
+ }
101
+
package/src/demo.js CHANGED
@@ -159,7 +159,7 @@ const SearchViews = props => (
159
159
  <div className="gramene-sidebar">
160
160
  <Status/>
161
161
  <Filters/>
162
- {/*<Views/>*/}
162
+ <Views/>
163
163
  </div>
164
164
  </div>
165
165
  <div className="col-md-10 no-padding">