sequenceserver 2.0.0.rc8 → 2.0.0
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.
Potentially problematic release.
This version of sequenceserver might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bin/sequenceserver +22 -30
- data/lib/sequenceserver/api_errors.rb +5 -1
- data/lib/sequenceserver/blast/constants.rb +1 -1
- data/lib/sequenceserver/blast/hit.rb +5 -16
- data/lib/sequenceserver/blast/job.rb +9 -18
- data/lib/sequenceserver/blast/report.rb +5 -3
- data/lib/sequenceserver/config.rb +4 -1
- data/lib/sequenceserver/database.rb +69 -9
- data/lib/sequenceserver/job.rb +1 -1
- data/lib/sequenceserver/makeblastdb.rb +40 -45
- data/lib/sequenceserver/routes.rb +4 -0
- data/lib/sequenceserver/version.rb +1 -1
- data/lib/sequenceserver.rb +15 -11
- data/public/config.js +143 -142
- data/public/css/fonts.css +23 -22
- data/public/css/grapher.css +598 -594
- data/public/css/sequenceserver.css +86 -24
- data/public/css/sequenceserver.min.css +2 -2
- data/public/js/alignment_exporter.js +14 -14
- data/public/js/databases_tree.js +215 -0
- data/public/js/download_fasta.js +1 -1
- data/public/js/hit.js +6 -2
- data/public/js/hits_overview.js +1 -1
- data/public/js/length_distribution.js +5 -5
- data/public/js/query.js +4 -7
- data/public/js/report.js +12 -24
- data/public/js/search.js +21 -2
- data/public/js/sidebar.js +4 -4
- data/public/js/svgExporter.js +12 -12
- data/public/js/visualisation_helpers.js +4 -5
- data/public/sequenceserver-report.min.js +11 -11
- data/public/sequenceserver-search.min.js +15 -11
- data/public/vendor/github/vakata/jstree@3.3.8/LICENSE-MIT +22 -0
- data/public/vendor/github/vakata/jstree@3.3.8/README.md +663 -0
- data/public/vendor/github/vakata/jstree@3.3.8/bower.json +33 -0
- data/public/vendor/github/vakata/jstree@3.3.8/component.json +28 -0
- data/public/vendor/github/vakata/jstree@3.3.8/composer.json +46 -0
- data/public/vendor/github/vakata/jstree@3.3.8/demo/README.md +2 -0
- data/public/vendor/github/vakata/jstree@3.3.8/demo/basic/index.html +146 -0
- data/public/vendor/github/vakata/jstree@3.3.8/demo/basic/root.json +1 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/jstree.js +8612 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/jstree.min.js +6 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default/32px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default/40px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default/style.css +1102 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default/style.min.css +1 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default/throbber.gif +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default-dark/32px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default-dark/40px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default-dark/style.css +1146 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default-dark/style.min.css +1 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default-dark/throbber.gif +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/gruntfile.js +242 -0
- data/public/vendor/github/vakata/jstree@3.3.8/jstree.jquery.json +28 -0
- data/public/vendor/github/vakata/jstree@3.3.8/package.json +58 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/intro.js +14 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.changed.js +69 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.checkbox.js +976 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.conditionalselect.js +38 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.contextmenu.js +661 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.dnd.js +669 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.js +4931 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.massload.js +137 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.search.js +421 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.sort.js +74 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.state.js +138 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.types.js +372 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.unique.js +164 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.wholerow.js +122 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/misc.js +656 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/outro.js +1 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/sample.js +93 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/base.less +93 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default/32px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default/40px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default/style.css +1102 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default/style.less +22 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default/throbber.gif +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default-dark/32px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default-dark/40px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default-dark/style.css +1146 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default-dark/style.less +50 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default-dark/throbber.gif +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/main.less +77 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/mixins.less +104 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/responsive.less +67 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/vakata-jstree.js +38 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/unit/index.html +16 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/unit/libs/qunit.css +244 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/unit/libs/qunit.js +2212 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/unit/test.js +11 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/desktop/index.html +44 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/mobile/index.html +42 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/screenshots/desktop/desktop.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/screenshots/desktop/home.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/screenshots/mobile/home.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/screenshots/mobile/mobile.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8.js +3 -0
- data/public/vendor/system-csp-production.js +3 -3
- data/public/vendor/system-csp-production.js.map +1 -1
- data/public/vendor/system-csp-production.src.js +146 -140
- data/public/vendor/system-polyfills.js.map +1 -1
- data/public/vendor/system-polyfills.src.js +1 -0
- data/public/vendor/system.js +3 -3
- data/public/vendor/system.js.map +1 -1
- data/public/vendor/system.src.js +4771 -2383
- data/views/_options.erb +21 -0
- data/views/layout.erb +17 -18
- metadata +102 -43
- data/bin/chromedriver +0 -0
- data/bin/geckodriver +0 -0
- data/public/shims/form-core.js +0 -3
- data/public/shims/form-validation.js +0 -3
- data/public/shims/plugins/jquery.ui.position.js +0 -13
- data/public/shims/styles/shim.css +0 -1
@@ -7,28 +7,28 @@ export default class AlignmentExporter {
|
|
7
7
|
var idx = 0;
|
8
8
|
var wrapped = '';
|
9
9
|
while(true) {
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
wrapped += str.substring(idx, idx + width);
|
11
|
+
idx += width;
|
12
|
+
if(idx < str.length) {
|
13
|
+
wrapped += '\n';
|
14
|
+
} else {
|
15
|
+
break;
|
16
|
+
}
|
17
17
|
}
|
18
18
|
return wrapped;
|
19
19
|
}
|
20
20
|
|
21
21
|
generate_fasta(hsps) {
|
22
22
|
|
23
|
-
var fasta =
|
23
|
+
var fasta = '';
|
24
24
|
|
25
25
|
_.each(hsps, _.bind(function (hsp) {
|
26
|
-
fasta +=
|
27
|
-
fasta += hsp.qseq+
|
28
|
-
fasta +=
|
29
|
-
fasta += hsp.midline+
|
30
|
-
fasta +=
|
31
|
-
fasta += hsp.sseq+
|
26
|
+
fasta += '>'+hsp.query_id+':'+hsp.qstart+'-'+hsp.qend+'\n';
|
27
|
+
fasta += hsp.qseq+'\n';
|
28
|
+
fasta += '>'+hsp.query_id+':'+hsp.qstart+'-'+hsp.qend+'_alignment_'+hsp.hit_id+':'+hsp.sstart+'-'+hsp.send+'\n';
|
29
|
+
fasta += hsp.midline+'\n';
|
30
|
+
fasta += '>'+hsp.hit_id+':'+hsp.sstart+'-'+hsp.send+'\n';
|
31
|
+
fasta += hsp.sseq+'\n';
|
32
32
|
}, this));
|
33
33
|
return fasta;
|
34
34
|
}
|
@@ -0,0 +1,215 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import _ from 'underscore';
|
3
|
+
import Jstree from 'vakata/jstree';
|
4
|
+
|
5
|
+
export default React.createClass({
|
6
|
+
getInitialState: function () {
|
7
|
+
return { type: '' };
|
8
|
+
},
|
9
|
+
|
10
|
+
databases: function (category) {
|
11
|
+
var databases = this.props.databases;
|
12
|
+
if (category) {
|
13
|
+
databases = _.select(databases, database => database.type === category);
|
14
|
+
}
|
15
|
+
|
16
|
+
return _.sortBy(databases, 'title');
|
17
|
+
},
|
18
|
+
|
19
|
+
nselected: function () {
|
20
|
+
return $('input[name="databases[]"]:checked').length;
|
21
|
+
},
|
22
|
+
|
23
|
+
categories: function () {
|
24
|
+
return _.uniq(_.map(this.props.databases,
|
25
|
+
_.iteratee('type'))).sort();
|
26
|
+
},
|
27
|
+
|
28
|
+
handleClick: function (database) {
|
29
|
+
var type = this.nselected() ? database.type : '';
|
30
|
+
if (type != this.state.type) this.setState({type: type});
|
31
|
+
},
|
32
|
+
|
33
|
+
handleLoadTree: function (category) {
|
34
|
+
var tree_id = '#' + category + '_database_tree';
|
35
|
+
// hack that is needed to sync the selected tree db with the hidden main db
|
36
|
+
window.jstree_node_change_timeout = null;
|
37
|
+
|
38
|
+
// when a tree database gets selected
|
39
|
+
$(tree_id).on('select_node.jstree deselect_node.jstree', function (e, data) {
|
40
|
+
if (window.jstree_node_change_timeout) {
|
41
|
+
clearTimeout(window.jstree_node_change_timeout);
|
42
|
+
window.jstree_node_change_timeout = null;
|
43
|
+
}
|
44
|
+
|
45
|
+
window.jstree_node_change_timeout = setTimeout(function(){
|
46
|
+
// uncheck all input
|
47
|
+
$('div#database_list input[type="checkbox"]:checked').click();
|
48
|
+
setTimeout(function(){
|
49
|
+
// get all selected tree dbs. Also includes folders. Therefore, the id must have a length of 32
|
50
|
+
// this id is used to find the corresponding element from the hidden main form
|
51
|
+
var selected = $(tree_id).jstree('get_selected').filter(selected => selected.length == 32);
|
52
|
+
$.each(selected, function( index, value ) {
|
53
|
+
// select hidden element to trigger original sequenceserver behavior, like blast algorithm, ...
|
54
|
+
$('input[value="'+ value + '"]').click();
|
55
|
+
});
|
56
|
+
}, 100);
|
57
|
+
}, 100);
|
58
|
+
});
|
59
|
+
|
60
|
+
$(tree_id).jstree({
|
61
|
+
'core' : {
|
62
|
+
'data': this.props.tree[category]
|
63
|
+
},
|
64
|
+
'plugins' : [ 'checkbox', 'search', 'sort' ],
|
65
|
+
'checkbox' : {
|
66
|
+
'keep_selected_style' : false
|
67
|
+
}
|
68
|
+
});
|
69
|
+
},
|
70
|
+
|
71
|
+
handleTreeSearch: function(category, tree_id, search_id) {
|
72
|
+
var search_for = $('#' + search_id).val();
|
73
|
+
$('#' + tree_id).jstree(true).search(search_for);
|
74
|
+
},
|
75
|
+
|
76
|
+
handleToggle: function (toggleState, type) {
|
77
|
+
switch (toggleState) {
|
78
|
+
case '[Select all]':
|
79
|
+
$(`.${type} .database input:not(:checked)`).click();
|
80
|
+
break;
|
81
|
+
case '[Deselect all]':
|
82
|
+
$(`.${type} .database input:checked`).click();
|
83
|
+
break;
|
84
|
+
}
|
85
|
+
},
|
86
|
+
|
87
|
+
render: function () {
|
88
|
+
return (
|
89
|
+
<div className='form-group databases-container'>
|
90
|
+
{ _.map(this.categories(), this.renderDatabases) }
|
91
|
+
</div>
|
92
|
+
);
|
93
|
+
},
|
94
|
+
|
95
|
+
renderDatabases: function (category) {
|
96
|
+
// Panel name and column width.
|
97
|
+
var panelTitle = category[0].toUpperCase() +
|
98
|
+
category.substring(1).toLowerCase() + ' databases';
|
99
|
+
var columnClass = this.categories().length === 1 ? 'col-md-12' :
|
100
|
+
'col-md-6';
|
101
|
+
|
102
|
+
// Toggle button.
|
103
|
+
var toggleState = '[Select all]';
|
104
|
+
var toggleClass = 'btn-link';
|
105
|
+
var toggleShown = this.databases(category).length > 1 ;
|
106
|
+
var toggleDisabled = this.state.type && this.state.type !== category;
|
107
|
+
if (toggleShown && toggleDisabled) toggleClass += ' disabled';
|
108
|
+
if (!toggleShown) toggleClass += ' hidden';
|
109
|
+
if (this.nselected() === this.databases(category).length) {
|
110
|
+
toggleState = '[Deselect all]';
|
111
|
+
}
|
112
|
+
|
113
|
+
// JSX.
|
114
|
+
return (
|
115
|
+
<div className={columnClass} key={'DB_'+category}>
|
116
|
+
<div className='panel panel-default' id='database_list'>
|
117
|
+
<div className='panel-heading'>
|
118
|
+
<h4 style={{display: 'inline'}}>{panelTitle}</h4>
|
119
|
+
{
|
120
|
+
this.renderDatabaseSearch(category)
|
121
|
+
}
|
122
|
+
<button type='button' className={toggleClass} disabled={toggleDisabled} style={{display: 'none'}}
|
123
|
+
onClick={ function () { this.handleToggle(toggleState, category); }.bind(this) }>
|
124
|
+
{toggleState}
|
125
|
+
</button>
|
126
|
+
</div>
|
127
|
+
<ul className={'list-group databases ' + category} style={{display: 'none'}}>
|
128
|
+
{
|
129
|
+
_.map(this.databases(category), _.bind(function (database,index) {
|
130
|
+
return (
|
131
|
+
<li className='list-group-item' key={'DB_'+category+index}>
|
132
|
+
{ this.renderDatabase(database) }
|
133
|
+
</li>
|
134
|
+
);
|
135
|
+
}, this))
|
136
|
+
}
|
137
|
+
</ul>
|
138
|
+
</div>
|
139
|
+
{
|
140
|
+
this.renderDatabaseTree(category)
|
141
|
+
}
|
142
|
+
</div>
|
143
|
+
);
|
144
|
+
},
|
145
|
+
|
146
|
+
renderDatabaseSearch: function (category) {
|
147
|
+
var tree_id = category + '_database_tree';
|
148
|
+
var search_id = tree_id + '_search';
|
149
|
+
|
150
|
+
return (
|
151
|
+
<input type='text' id={search_id} class='input'
|
152
|
+
onKeyUp=
|
153
|
+
{
|
154
|
+
_.bind(function () {
|
155
|
+
this.handleTreeSearch(category, tree_id, search_id);
|
156
|
+
}, this)
|
157
|
+
}
|
158
|
+
></input>
|
159
|
+
);
|
160
|
+
},
|
161
|
+
|
162
|
+
renderDatabaseTree: function (category) {
|
163
|
+
var tree_id = category + '_database_tree';
|
164
|
+
var data = this.props.tree[category];
|
165
|
+
|
166
|
+
return (
|
167
|
+
<div
|
168
|
+
id={tree_id}
|
169
|
+
className={'jstree_div'}
|
170
|
+
onClick=
|
171
|
+
{
|
172
|
+
_.bind(function () {
|
173
|
+
this.handleLoadTree(category);
|
174
|
+
}, this)
|
175
|
+
}
|
176
|
+
>
|
177
|
+
</div>
|
178
|
+
);
|
179
|
+
},
|
180
|
+
|
181
|
+
renderDatabase: function (database) {
|
182
|
+
var disabled = this.state.type && this.state.type !== database.type;
|
183
|
+
|
184
|
+
return (
|
185
|
+
<label
|
186
|
+
className={disabled && 'disabled database' || 'database'}>
|
187
|
+
<input
|
188
|
+
type='checkbox' name='databases[]' value={database.id}
|
189
|
+
data-type={database.type} disabled={disabled}
|
190
|
+
onChange=
|
191
|
+
{
|
192
|
+
_.bind(function () {
|
193
|
+
this.handleClick(database);
|
194
|
+
}, this)
|
195
|
+
}/>
|
196
|
+
{' ' + (database.title || database.name)}
|
197
|
+
</label>
|
198
|
+
);
|
199
|
+
},
|
200
|
+
|
201
|
+
componentDidUpdate: function () {
|
202
|
+
if (this.databases() && this.databases().length === 1) {
|
203
|
+
$('.databases').find('input').prop('checked',true);
|
204
|
+
this.handleClick(this.databases()[0]);
|
205
|
+
}
|
206
|
+
|
207
|
+
if (this.props.preSelectedDbs) {
|
208
|
+
var selectors = this.props.preSelectedDbs.map(db => `input[value=${db.id}]`);
|
209
|
+
$(...selectors).prop('checked',true);
|
210
|
+
this.handleClick(this.props.preSelectedDbs[0]);
|
211
|
+
this.props.preSelectedDbs = null;
|
212
|
+
}
|
213
|
+
this.props.onDatabaseTypeChanged(this.state.type);
|
214
|
+
}
|
215
|
+
});
|
data/public/js/download_fasta.js
CHANGED
data/public/js/hit.js
CHANGED
@@ -30,6 +30,10 @@ export default React.createClass({
|
|
30
30
|
return this.props.hit.length;
|
31
31
|
},
|
32
32
|
|
33
|
+
numHSPs: function () {
|
34
|
+
return this.props.hit.hsps.length;
|
35
|
+
},
|
36
|
+
|
33
37
|
// Internal helpers. //
|
34
38
|
|
35
39
|
/**
|
@@ -119,14 +123,14 @@ export default React.createClass({
|
|
119
123
|
{ this.hitLinks() }
|
120
124
|
<HSPOverview key={'kablammo' + this.props.query.id} query={this.props.query}
|
121
125
|
hit={this.props.hit} algorithm={this.props.algorithm}
|
122
|
-
showHSPCrumbs={this.
|
126
|
+
showHSPCrumbs={this.numHSPs() > 1 && this.numHSPs() < 27}
|
123
127
|
collapsed={this.props.veryBig} />
|
124
128
|
</div>;
|
125
129
|
},
|
126
130
|
|
127
131
|
hitLinks: function () {
|
128
132
|
var btns = [];
|
129
|
-
if (!this.props.imported_xml) {
|
133
|
+
if (!(this.props.imported_xml || this.props.non_parse_seqids)) {
|
130
134
|
btns = btns.concat([
|
131
135
|
this.viewSequenceButton(),
|
132
136
|
this.downloadFASTAButton()
|
data/public/js/hits_overview.js
CHANGED
@@ -9,7 +9,7 @@ import * as Helpers from './visualisation_helpers';
|
|
9
9
|
|
10
10
|
class Graph {
|
11
11
|
static name() {
|
12
|
-
return 'Length distribution of
|
12
|
+
return 'Length distribution of matching sequences';
|
13
13
|
}
|
14
14
|
|
15
15
|
static className() {
|
@@ -69,8 +69,7 @@ class Graph {
|
|
69
69
|
.range([0, this._width]);
|
70
70
|
this._bins = d3.layout.histogram()
|
71
71
|
.range(this._scale_x.domain())
|
72
|
-
.bins(this._scale_x.ticks(50))
|
73
|
-
(this._data);
|
72
|
+
.bins(this._scale_x.ticks(50))(this._data);
|
74
73
|
this._scale_y = d3.scale.linear()
|
75
74
|
.domain([0, d3.max(this._bins, function(d) { return d.length; })])
|
76
75
|
.range([this._height, 0]).nice();
|
@@ -129,14 +128,15 @@ class Graph {
|
|
129
128
|
bin.map(function (d,i) {
|
130
129
|
var y1 = bin.length - (i+1);
|
131
130
|
var len_index = _.findIndex(self.query.hits, {length: d});
|
131
|
+
var evalue = self.query.hits[len_index].hsps[0].evalue;
|
132
132
|
var item = {
|
133
133
|
value: d,
|
134
134
|
id: self.query.hits[len_index].id,
|
135
|
-
evalue:
|
135
|
+
evalue: evalue,
|
136
136
|
url: '#Query_'+self.query.number+'_hit_'+self.query.hits[len_index].number,
|
137
137
|
y0: y0,
|
138
138
|
y1: y0 += (y1 - y0),
|
139
|
-
color: Helpers.get_colors_for_evalue(
|
139
|
+
color: Helpers.get_colors_for_evalue(evalue,self.query.hits)
|
140
140
|
};
|
141
141
|
inner_data.push(item);
|
142
142
|
});
|
data/public/js/query.js
CHANGED
@@ -111,7 +111,7 @@ var HitsTable = React.createClass({
|
|
111
111
|
<div className="table-hit-overview">
|
112
112
|
<h4 className="caption" data-toggle="collapse" data-target={'#Query_'+this.props.query.number+'HT_'+this.props.query.number}>
|
113
113
|
<i className="fa fa-minus-square-o"></i>
|
114
|
-
<span>
|
114
|
+
<span>Sequences producing significant alignments</span>
|
115
115
|
</h4>
|
116
116
|
<div className="collapsed in"id={'Query_'+ this.props.query.number + 'HT_'+ this.props.query.number}>
|
117
117
|
<table
|
@@ -123,10 +123,7 @@ var HitsTable = React.createClass({
|
|
123
123
|
{!this.props.imported_xml && <th width="15%" className="text-right">Query coverage (%)</th>}
|
124
124
|
<th width="10%" className="text-right">Total score</th>
|
125
125
|
<th width="10%" className="text-right">E value</th>
|
126
|
-
<th width="10%" className="text-right"
|
127
|
-
data-placement="left" title="Total identity of all hsps / total length of all hsps">
|
128
|
-
Identity (%)
|
129
|
-
</th>
|
126
|
+
<th width="10%" className="text-right">Identity (%)</th>
|
130
127
|
</thead>
|
131
128
|
<tbody>
|
132
129
|
{
|
@@ -147,9 +144,9 @@ var HitsTable = React.createClass({
|
|
147
144
|
</td>
|
148
145
|
}
|
149
146
|
{!this.props.imported_xml && <td className="text-right">{hit.qcovs}</td>}
|
150
|
-
<td className="text-right">{hit.
|
147
|
+
<td className="text-right">{hit.total_score}</td>
|
151
148
|
<td className="text-right">{this.inExponential(hit.hsps[0].evalue)}</td>
|
152
|
-
<td className="text-right">{hit.identity}</td>
|
149
|
+
<td className="text-right">{this.inPercentage(hit.hsps[0].identity, hit.hsps[0].length)}</td>
|
153
150
|
</tr>
|
154
151
|
);
|
155
152
|
}, this))
|
data/public/js/report.js
CHANGED
@@ -203,6 +203,7 @@ var Report = React.createClass({
|
|
203
203
|
results.push(<Query key={'Query_'+query.number} query={query}
|
204
204
|
program={this.state.program} querydb={this.state.querydb}
|
205
205
|
showQueryCrumbs={this.state.queries.length > 1}
|
206
|
+
non_parse_seqids={this.state.non_parse_seqids}
|
206
207
|
imported_xml={this.state.imported_xml}
|
207
208
|
veryBig={this.state.veryBig} />);
|
208
209
|
}
|
@@ -216,6 +217,7 @@ var Report = React.createClass({
|
|
216
217
|
results.push(<Hit key={'Query_'+query.number+'_Hit_'+hit.number} query={query}
|
217
218
|
hit={hit} algorithm={this.state.program} querydb={this.state.querydb}
|
218
219
|
selectHit={this.selectHit} imported_xml={this.state.imported_xml}
|
220
|
+
non_parse_seqids={this.state.non_parse_seqids}
|
219
221
|
showQueryCrumbs={this.state.queries.length > 1}
|
220
222
|
showHitCrumbs={query.hits.length > 1}
|
221
223
|
veryBig={this.state.veryBig}
|
@@ -301,14 +303,12 @@ var Report = React.createClass({
|
|
301
303
|
resultsJSX: function () {
|
302
304
|
return (
|
303
305
|
<div className="row">
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
}
|
311
|
-
<div className={this.shouldShowSidebar() ? 'col-md-9' : 'col-md-12'}>
|
306
|
+
<div className="col-md-3 hidden-sm hidden-xs">
|
307
|
+
<Sidebar data={this.state}
|
308
|
+
atLeastOneHit={this.atLeastOneHit()}
|
309
|
+
shouldShowIndex={this.shouldShowIndex()} />
|
310
|
+
</div>
|
311
|
+
<div className="col-md-9">
|
312
312
|
{ this.overviewJSX() }
|
313
313
|
{ this.circosJSX() }
|
314
314
|
{ this.state.results }
|
@@ -387,17 +387,6 @@ var Report = React.createClass({
|
|
387
387
|
});
|
388
388
|
},
|
389
389
|
|
390
|
-
/**
|
391
|
-
* Returns true if sidebar should be shown.
|
392
|
-
*
|
393
|
-
* Sidebar is not shown if there is only one query and there are no hits
|
394
|
-
* corresponding to the query.
|
395
|
-
*/
|
396
|
-
shouldShowSidebar: function () {
|
397
|
-
return !(this.state.queries.length == 1 &&
|
398
|
-
this.state.queries[0].hits.length == 0);
|
399
|
-
},
|
400
|
-
|
401
390
|
/**
|
402
391
|
* Returns true if index should be shown in the sidebar. Index is shown
|
403
392
|
* only for 2 and 8 queries.
|
@@ -446,7 +435,7 @@ var Report = React.createClass({
|
|
446
435
|
*/
|
447
436
|
affixSidebar: function () {
|
448
437
|
var $sidebar = $('.sidebar');
|
449
|
-
var sidebarOffset = $sidebar.offset()
|
438
|
+
var sidebarOffset = $sidebar.offset();
|
450
439
|
if (sidebarOffset) {
|
451
440
|
$sidebar.affix({
|
452
441
|
offset: {
|
@@ -492,17 +481,16 @@ var Report = React.createClass({
|
|
492
481
|
$hit.next('.hsp').removeClass('glow');
|
493
482
|
}
|
494
483
|
|
484
|
+
var $a = $('.download-fasta-of-selected');
|
485
|
+
var $b = $('.download-alignment-of-selected');
|
486
|
+
|
495
487
|
if (num_checked >= 1)
|
496
488
|
{
|
497
|
-
var $a = $('.download-fasta-of-selected');
|
498
|
-
var $b = $('.download-alignment-of-selected');
|
499
489
|
$a.find('.text-bold').html(num_checked);
|
500
490
|
$b.find('.text-bold').html(num_checked);
|
501
491
|
}
|
502
492
|
|
503
493
|
if (num_checked == 0) {
|
504
|
-
var $a = $('.download-fasta-of-selected');
|
505
|
-
var $b = $('.download-alignment-of-selected');
|
506
494
|
$a.addClass('disabled').find('.text-bold').html('');
|
507
495
|
$b.addClass('disabled').find('.text-bold').html('');
|
508
496
|
}
|
data/public/js/search.js
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
import './jquery_world';
|
2
2
|
import React from 'react';
|
3
3
|
import _ from 'underscore';
|
4
|
+
import DatabasesTree from './databases_tree';
|
4
5
|
|
5
6
|
/**
|
6
7
|
* Load necessary polyfills.
|
7
8
|
*/
|
9
|
+
$.webshims.setOptions('basePath', '/vendor/npm/webshim@1.15.8/js-webshim/minified/shims/');
|
8
10
|
$.webshims.polyfill('forms');
|
9
11
|
|
10
12
|
/**
|
@@ -206,7 +208,7 @@ var DnD = React.createClass({
|
|
206
208
|
var Form = React.createClass({
|
207
209
|
|
208
210
|
getInitialState: function () {
|
209
|
-
return { databases: {},
|
211
|
+
return { databases: [], preDefinedOpts: {}, tree: {} };
|
210
212
|
},
|
211
213
|
|
212
214
|
componentDidMount: function () {
|
@@ -225,6 +227,7 @@ var Form = React.createClass({
|
|
225
227
|
* advanced options.
|
226
228
|
*/
|
227
229
|
this.setState({
|
230
|
+
tree: data['tree'],
|
228
231
|
databases: data['database'],
|
229
232
|
preSelectedDbs: data['preSelectedDbs'],
|
230
233
|
preDefinedOpts: data['options']
|
@@ -236,6 +239,10 @@ var Form = React.createClass({
|
|
236
239
|
if (data['query']) {
|
237
240
|
this.refs.query.value(data['query']);
|
238
241
|
}
|
242
|
+
|
243
|
+
setTimeout(function(){
|
244
|
+
$('.jstree_div').click();
|
245
|
+
}, 1000);
|
239
246
|
}.bind(this));
|
240
247
|
|
241
248
|
/* Enable submitting form on Cmd+Enter */
|
@@ -248,6 +255,10 @@ var Form = React.createClass({
|
|
248
255
|
});
|
249
256
|
},
|
250
257
|
|
258
|
+
useTreeWidget: function () {
|
259
|
+
return !_.isEmpty(this.state.tree);
|
260
|
+
},
|
261
|
+
|
251
262
|
determineBlastMethod: function () {
|
252
263
|
var database_type = this.databaseType;
|
253
264
|
var sequence_type = this.sequenceType;
|
@@ -335,9 +346,16 @@ var Form = React.createClass({
|
|
335
346
|
<ProteinNotification/>
|
336
347
|
<MixedNotification/>
|
337
348
|
</div>
|
349
|
+
{this.useTreeWidget() ?
|
350
|
+
<DatabasesTree ref="databases"
|
351
|
+
databases={this.state.databases} tree={this.state.tree}
|
352
|
+
preSelectedDbs={this.state.preSelectedDbs}
|
353
|
+
onDatabaseTypeChanged={this.handleDatabaseTypeChanaged} />
|
354
|
+
:
|
338
355
|
<Databases ref="databases" databases={this.state.databases}
|
339
356
|
preSelectedDbs={this.state.preSelectedDbs}
|
340
357
|
onDatabaseTypeChanged={this.handleDatabaseTypeChanaged} />
|
358
|
+
}
|
341
359
|
<div className="form-group">
|
342
360
|
<Options ref="opts"/>
|
343
361
|
<div className="col-md-2">
|
@@ -687,6 +705,7 @@ var Databases = React.createClass({
|
|
687
705
|
$(`.${type} .database input:checked`).click();
|
688
706
|
break;
|
689
707
|
}
|
708
|
+
this.forceUpdate();
|
690
709
|
},
|
691
710
|
|
692
711
|
render: function () {
|
@@ -770,7 +789,7 @@ var Databases = React.createClass({
|
|
770
789
|
|
771
790
|
if (this.props.preSelectedDbs) {
|
772
791
|
var selectors = this.props.preSelectedDbs.map(db => `input[value=${db.id}]`);
|
773
|
-
$(
|
792
|
+
$(selectors.join(',')).prop('checked',true);
|
774
793
|
this.handleClick(this.props.preSelectedDbs[0]);
|
775
794
|
this.props.preSelectedDbs = null;
|
776
795
|
}
|
data/public/js/sidebar.js
CHANGED
@@ -166,15 +166,15 @@ export default React.createClass({
|
|
166
166
|
</div>
|
167
167
|
<ul className="nav">
|
168
168
|
{
|
169
|
-
!this.props.data.imported_xml && <li>
|
170
|
-
<a href="#" className=
|
169
|
+
!(this.props.data.imported_xml || this.props.data.non_parse_seqids) && <li>
|
170
|
+
<a href="#" className={`btn-link download-fasta-of-all ${!this.props.atLeastOneHit && 'disabled'}`}
|
171
171
|
onClick={this.downloadFastaOfAll}>
|
172
172
|
FASTA of all hits
|
173
173
|
</a>
|
174
174
|
</li>
|
175
175
|
}
|
176
176
|
{
|
177
|
-
!this.props.data.imported_xml && <li>
|
177
|
+
!(this.props.data.imported_xml || this.props.data.non_parse_seqids) && <li>
|
178
178
|
<a href="#" className="btn-link download-fasta-of-selected disabled"
|
179
179
|
onClick={this.downloadFastaOfSelected}>
|
180
180
|
FASTA of <span className="text-bold"></span> selected hit(s)
|
@@ -182,7 +182,7 @@ export default React.createClass({
|
|
182
182
|
</li>
|
183
183
|
}
|
184
184
|
<li>
|
185
|
-
<a href="#" className=
|
185
|
+
<a href="#" className={`btn-link download-alignment-of-all ${!this.props.atLeastOneHit && 'disabled'}`}
|
186
186
|
onClick={this.downloadAlignmentOfAll}>
|
187
187
|
Alignment of all hits
|
188
188
|
</a>
|
data/public/js/svgExporter.js
CHANGED
@@ -16,7 +16,7 @@ var export_as_svg = function (svg, filename) {
|
|
16
16
|
var blob = new Blob([serialize_svg(svg)], { type: 'text/xml' });
|
17
17
|
filename = Exporter.sanitize_filename(filename) + '.svg';
|
18
18
|
Exporter.download_blob(blob, filename);
|
19
|
-
}
|
19
|
+
};
|
20
20
|
|
21
21
|
/**
|
22
22
|
* Exports the given <svg> DOM node as a .png file.
|
@@ -45,19 +45,19 @@ var export_as_png = function (svg, filename) {
|
|
45
45
|
};
|
46
46
|
|
47
47
|
img.src = 'data:image/svg+xml;base64,' + window.btoa(serialize_svg(svg));
|
48
|
-
}
|
48
|
+
};
|
49
49
|
|
50
50
|
var serialize_svg = function(svg) {
|
51
51
|
// Clone svg first so that none of our changes to affect the actual SVG.
|
52
52
|
svg = svg.cloneNode(true);
|
53
53
|
|
54
54
|
d3.select(svg).attr('version', '1.1')
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
55
|
+
.insert('defs', ':first-child')
|
56
|
+
.append('style')
|
57
|
+
.attr('class', 'exported-css')
|
58
|
+
.attr('type', 'text/css')
|
59
|
+
.node()
|
60
|
+
.textContent = get_styles();
|
61
61
|
|
62
62
|
svg.removeAttribute('xmlns');
|
63
63
|
svg.removeAttribute('xlink');
|
@@ -67,8 +67,8 @@ var serialize_svg = function(svg) {
|
|
67
67
|
var source = (new XMLSerializer()).serializeToString(svg);
|
68
68
|
var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC ' +
|
69
69
|
'"-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
|
70
|
-
|
71
|
-
}
|
70
|
+
return doctype + source;
|
71
|
+
};
|
72
72
|
|
73
73
|
var get_styles = function () {
|
74
74
|
var styles = '';
|
@@ -113,14 +113,14 @@ var get_styles = function () {
|
|
113
113
|
}
|
114
114
|
|
115
115
|
return styles;
|
116
|
-
}
|
116
|
+
};
|
117
117
|
|
118
118
|
var handle_click = function (export_callback) {
|
119
119
|
return function () {
|
120
120
|
var $svg = $(this).parents('.grapher').find('svg');
|
121
121
|
export_callback($svg[0], $svg.attr('data-name'));
|
122
122
|
return false;
|
123
|
-
}
|
123
|
+
};
|
124
124
|
};
|
125
125
|
|
126
126
|
var $body = $('body');
|
@@ -39,16 +39,15 @@ export function tick_formatter(scale, seq_type) {
|
|
39
39
|
var digits = 0;
|
40
40
|
var format;
|
41
41
|
var _ticks;
|
42
|
-
|
42
|
+
|
43
|
+
do {
|
43
44
|
format = d3.format('.' + digits + 'f');
|
44
45
|
_ticks = scale.ticks().map(function (d) {
|
45
46
|
return format(prefix.scale(d));
|
46
47
|
});
|
47
|
-
if (_ticks.length === _.uniq(_ticks).length) {
|
48
|
-
break;
|
49
|
-
}
|
50
48
|
digits++;
|
51
|
-
|
49
|
+
|
50
|
+
} while (_ticks.length !== _.uniq(_ticks).length);
|
52
51
|
|
53
52
|
return function (d) {
|
54
53
|
if (!prefix.symbol || d === scale.domain()[0]) {
|