sequenceserver 3.1.3 → 3.2.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.
- checksums.yaml +4 -4
- data/lib/sequenceserver/api_errors.rb +18 -0
- data/lib/sequenceserver/blast/hit.rb +1 -2
- data/lib/sequenceserver/blast/job.rb +15 -5
- data/lib/sequenceserver/blast/report.rb +5 -1
- data/lib/sequenceserver/database.rb +5 -1
- data/lib/sequenceserver/job.rb +26 -10
- data/lib/sequenceserver/makeblastdb.rb +2 -1
- data/lib/sequenceserver/routes.rb +37 -12
- data/lib/sequenceserver/version.rb +1 -1
- data/lib/sequenceserver/zip_file_generator.rb +1 -1
- data/public/404.html +8 -16
- data/public/css/app.css +794 -111
- data/public/css/app.min.css +1 -1
- data/public/css/sequenceserver.min.css +1 -8
- data/public/js/circos.js +103 -96
- data/public/{packages/circosJS@1.7.0.js → js/circosjs.js} +156 -778
- data/public/js/cloud_share_modal.js +55 -58
- data/public/js/collapse_preferences.js +13 -15
- data/public/js/databases.js +4 -3
- data/public/js/databases_tree.js +51 -30
- data/public/js/error_modal.js +35 -22
- data/public/js/exporter.js +2 -0
- data/public/js/form.js +43 -7
- data/public/js/grapher.js +94 -92
- data/public/js/hit.js +21 -19
- data/public/js/hits.js +45 -38
- data/public/js/hits_overview.js +8 -27
- data/public/js/hsp.js +140 -144
- data/public/js/jquery_world.js +24 -15
- data/public/js/kablammo.js +14 -10
- data/public/js/length_distribution.js +23 -37
- data/public/js/null_plugins/report_plugins.js +3 -5
- data/public/js/options.js +17 -19
- data/public/js/query.js +36 -35
- data/public/js/report/alignment_results.js +18 -0
- data/public/js/report/graphical_overview.js +38 -0
- data/public/js/report/report_header.js +28 -0
- data/public/js/report/run_summary.js +43 -0
- data/public/js/report.js +62 -102
- data/public/js/report_root.js +3 -3
- data/public/js/search.js +5 -2
- data/public/js/search_button.js +85 -78
- data/public/js/sequence.js +11 -22
- data/public/js/sequence_modal.js +38 -37
- data/public/js/share_url.js +5 -5
- data/public/js/sidebar.js +148 -86
- data/public/js/svgExporter.js +8 -3
- data/public/js/tests/form.spec.js +1 -1
- data/public/js/tests/visualisation_helpers.spec.js +28 -0
- data/public/js/visualisation_helpers.js +24 -27
- data/public/sequenceserver-report.min.js +1 -1
- data/public/sequenceserver-report.min.js.LICENSE.txt +1 -88
- data/public/sequenceserver-report.min.js.map +1 -1
- data/public/sequenceserver-search.min.js +1 -1
- data/public/sequenceserver-search.min.js.LICENSE.txt +0 -30
- data/public/sequenceserver-search.min.js.map +1 -1
- data/views/error.erb +1 -1
- data/views/layout.erb +123 -130
- data/views/report.erb +3 -2
- data/views/search.erb +10 -14
- metadata +13 -26
- data/public/css/fonts.css +0 -31
- data/public/css/grapher.css +0 -670
- data/public/css/sequenceserver.css +0 -509
- data/public/vendor/github/mbostock/d3@3.5.6/d3.js +0 -9506
- data/public/vendor/github/mbostock/d3@3.5.6.js +0 -1
- data/views/search_layout.erb +0 -153
data/public/js/hsp.js
CHANGED
|
@@ -1,72 +1,48 @@
|
|
|
1
|
-
import React, { createRef } from "react";
|
|
1
|
+
import React, { useState, createRef, useEffect } from "react";
|
|
2
|
+
import useDetectPrint from "react-detect-print";
|
|
2
3
|
import _ from "underscore";
|
|
3
4
|
|
|
4
5
|
import Utils from "./utils";
|
|
5
6
|
import * as Helpers from "./visualisation_helpers";
|
|
6
7
|
|
|
7
|
-
var HSPComponents = {};
|
|
8
|
-
|
|
9
8
|
/**
|
|
10
9
|
* Alignment viewer.
|
|
11
10
|
*/
|
|
12
|
-
export default class HSP extends React.Component {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"_hit_" +
|
|
24
|
-
this.props.hit.number +
|
|
25
|
-
"_" +
|
|
26
|
-
this.props.hsp.number
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
hitDOM_ID() {
|
|
31
|
-
return "Query_" + this.props.query.number + "_hit_" + this.props.hit.number;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Renders pretty formatted alignment.
|
|
35
|
-
render() {
|
|
36
|
-
return (
|
|
37
|
-
<div
|
|
38
|
-
className="hsp"
|
|
39
|
-
id={this.domID()}
|
|
40
|
-
ref={this.hspRef}
|
|
41
|
-
data-parent-hit={this.hitDOM_ID()}
|
|
42
|
-
>
|
|
43
|
-
<p className="pre-reset hsp-stats">
|
|
44
|
-
{this.props.showHSPNumbers &&
|
|
45
|
-
`${Helpers.toLetters(this.hsp.number)}. `}
|
|
46
|
-
{this.hspStats().map((s, i) => (
|
|
47
|
-
<span key={i}>{s}</span>
|
|
48
|
-
))}
|
|
49
|
-
</p>
|
|
50
|
-
{this.hspLines()}
|
|
51
|
-
</div>
|
|
52
|
-
);
|
|
11
|
+
// export default class HSP extends React.Component {
|
|
12
|
+
export default function HSP(props) {
|
|
13
|
+
const hsp = props.hsp;
|
|
14
|
+
const hspRef = createRef();
|
|
15
|
+
const printing = useDetectPrint();
|
|
16
|
+
const [chars, setChars] = useState(0)
|
|
17
|
+
const [width, setWidth] = useState(window.innerWidth);
|
|
18
|
+
|
|
19
|
+
const domID = () => {
|
|
20
|
+
const { query, hit, hsp } = props;
|
|
21
|
+
return `Query_${query.number}_hit_${hit.number}_${hsp.number}`;
|
|
53
22
|
}
|
|
54
23
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this.draw();
|
|
24
|
+
const hitDOM_ID = () => {
|
|
25
|
+
return "Query_" + props.query.number + "_hit_" + props.hit.number;
|
|
58
26
|
}
|
|
59
27
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
// Attach a debounced listener to handle window resize events
|
|
30
|
+
// Updates the width state with the current window width, throttled to run at most once every 125ms
|
|
31
|
+
const handleResize = _.debounce(() => setWidth(window.innerWidth), 125);
|
|
32
|
+
window.addEventListener("resize", handleResize);
|
|
33
|
+
|
|
34
|
+
// TODO: print handler
|
|
35
|
+
draw();
|
|
36
|
+
}, [])
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
draw(printing);
|
|
40
|
+
}, [printing, width])
|
|
41
|
+
|
|
42
|
+
const draw = (printing = false) => {
|
|
43
|
+
const charWidth = props.getCharacterWidth();
|
|
44
|
+
const containerWidth = printing ? 900 : $(hspRef.current).width();
|
|
45
|
+
setChars(Math.floor((containerWidth - 4) / charWidth))
|
|
70
46
|
}
|
|
71
47
|
|
|
72
48
|
/**
|
|
@@ -77,141 +53,155 @@ export default class HSP extends React.Component {
|
|
|
77
53
|
* We cannot return a string from this method otherwise we wouldn't be able
|
|
78
54
|
* to use JSX elements to format text (like, superscript).
|
|
79
55
|
*/
|
|
80
|
-
hspStats() {
|
|
56
|
+
const hspStats = () => {
|
|
81
57
|
// An array to hold text or span elements that make up the line.
|
|
82
58
|
let line = [];
|
|
83
59
|
|
|
84
60
|
// Bit score and total score.
|
|
85
61
|
line.push(
|
|
86
|
-
`Score: ${Utils.inTwoDecimal(
|
|
62
|
+
`Score: ${Utils.inTwoDecimal(hsp.bit_score)} (${hsp.score}), `
|
|
87
63
|
);
|
|
88
64
|
|
|
89
65
|
// E value
|
|
90
66
|
line.push("E value: ");
|
|
91
|
-
line.push(Utils.inExponential(
|
|
67
|
+
line.push(Utils.inExponential(hsp.evalue));
|
|
92
68
|
line.push(", ");
|
|
93
69
|
|
|
94
70
|
// Identity
|
|
95
71
|
line.push([
|
|
96
72
|
`Identity: ${Utils.inFraction(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
)} (${Utils.inPercentage(
|
|
73
|
+
hsp.identity,
|
|
74
|
+
hsp.length
|
|
75
|
+
)} (${Utils.inPercentage(hsp.identity, hsp.length)}), `,
|
|
100
76
|
]);
|
|
101
77
|
|
|
102
78
|
// Positives (for protein alignment).
|
|
103
79
|
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
80
|
+
props.algorithm === "blastp" ||
|
|
81
|
+
props.algorithm === "blastx" ||
|
|
82
|
+
props.algorithm === "tblastn" ||
|
|
83
|
+
props.algorithm === "tblastx"
|
|
108
84
|
) {
|
|
109
85
|
line.push(
|
|
110
86
|
`Positives: ${Utils.inFraction(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
)} (${Utils.inPercentage(
|
|
87
|
+
hsp.positives,
|
|
88
|
+
hsp.length
|
|
89
|
+
)} (${Utils.inPercentage(hsp.positives, hsp.length)}), `
|
|
114
90
|
);
|
|
115
91
|
}
|
|
116
92
|
|
|
117
93
|
// Gaps
|
|
118
94
|
line.push(
|
|
119
95
|
`Gaps: ${Utils.inFraction(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
)} (${Utils.inPercentage(
|
|
96
|
+
hsp.gaps,
|
|
97
|
+
hsp.length
|
|
98
|
+
)} (${Utils.inPercentage(hsp.gaps, hsp.length)})`
|
|
123
99
|
);
|
|
124
100
|
|
|
125
101
|
// Query coverage
|
|
126
102
|
//line.push(`Query coverage: ${this.hsp.qcovhsp}%, `)
|
|
127
103
|
|
|
128
|
-
switch (
|
|
104
|
+
switch (props.algorithm) {
|
|
129
105
|
case "tblastx":
|
|
130
106
|
line.push(
|
|
131
|
-
`, Frame: ${Utils.inFraction(
|
|
107
|
+
`, Frame: ${Utils.inFraction(hsp.qframe, hsp.sframe)}`
|
|
132
108
|
);
|
|
133
109
|
break;
|
|
134
110
|
case "blastn":
|
|
135
111
|
line.push(
|
|
136
|
-
`, Strand: ${
|
|
137
|
-
|
|
112
|
+
`, Strand: ${hsp.qframe > 0 ? "+" : "-"} / ${
|
|
113
|
+
hsp.sframe > 0 ? "+" : "-"
|
|
138
114
|
}`
|
|
139
115
|
);
|
|
140
116
|
break;
|
|
141
117
|
case "blastx":
|
|
142
|
-
line.push(`, Query Frame: ${
|
|
118
|
+
line.push(`, Query Frame: ${hsp.qframe}`);
|
|
143
119
|
break;
|
|
144
120
|
case "tblastn":
|
|
145
|
-
line.push(`, Hit Frame: ${
|
|
121
|
+
line.push(`, Hit Frame: ${hsp.sframe}`);
|
|
146
122
|
break;
|
|
147
123
|
}
|
|
148
124
|
|
|
149
125
|
return line;
|
|
150
126
|
}
|
|
151
127
|
|
|
128
|
+
|
|
129
|
+
// Width of the coordinate part of hsp lines. Essentially the length of
|
|
130
|
+
// the largest coordinate.
|
|
131
|
+
const hspLinesWidth = () => {
|
|
132
|
+
return _.max(
|
|
133
|
+
_.map(
|
|
134
|
+
[hsp.qstart, hsp.qend, hsp.sstart, hsp.send],
|
|
135
|
+
(n) => {
|
|
136
|
+
return n.toString().length;
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
152
142
|
/**
|
|
153
143
|
* Returns array of pre tags containing the three query, middle, and subject
|
|
154
144
|
* lines that together comprise one 'rendered line' of HSP.
|
|
155
145
|
*/
|
|
156
|
-
hspLines() {
|
|
146
|
+
const hspLines = () => {
|
|
157
147
|
// Space reserved for showing coordinates
|
|
158
|
-
|
|
148
|
+
const width = hspLinesWidth();
|
|
159
149
|
|
|
160
150
|
// Number of residues we can draw per line is the total number of
|
|
161
151
|
// characters we can have in a line minus space required to show left
|
|
162
152
|
// and right coordinates minus 10 characters reserved for displaying
|
|
163
153
|
// the words Query, Subject and three blank spaces per line.
|
|
164
|
-
|
|
154
|
+
const adjustedLineWidth = chars - 2 * width - 10;
|
|
165
155
|
|
|
166
156
|
// Number of lines of pairwise-alignment (i.e., each line consists of 3
|
|
167
157
|
// lines). We draw as many pre tags.
|
|
168
|
-
|
|
158
|
+
const lines = Math.ceil(hsp.length / adjustedLineWidth);
|
|
169
159
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
160
|
+
let pp = [];
|
|
161
|
+
let nqseq = getNqseq();
|
|
162
|
+
let nsseq = getNsseq();
|
|
173
163
|
for (let i = 1; i <= lines; i++) {
|
|
174
|
-
let seq_start_index =
|
|
175
|
-
let seq_stop_index = seq_start_index +
|
|
164
|
+
let seq_start_index = adjustedLineWidth * (i - 1);
|
|
165
|
+
let seq_stop_index = seq_start_index + adjustedLineWidth;
|
|
176
166
|
|
|
177
167
|
let lqstart = nqseq;
|
|
178
|
-
let lqseq =
|
|
168
|
+
let lqseq = hsp.qseq.slice(seq_start_index, seq_stop_index);
|
|
179
169
|
let lqend =
|
|
180
170
|
nqseq +
|
|
181
171
|
(lqseq.length - lqseq.split("-").length) *
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
nqseq = lqend +
|
|
172
|
+
qframe_unit() *
|
|
173
|
+
qframe_sign();
|
|
174
|
+
nqseq = lqend + qframe_unit() * qframe_sign();
|
|
185
175
|
|
|
186
|
-
let lmseq =
|
|
176
|
+
let lmseq = hsp.midline.slice(seq_start_index, seq_stop_index);
|
|
187
177
|
|
|
188
178
|
let lsstart = nsseq;
|
|
189
|
-
let lsseq =
|
|
179
|
+
let lsseq = hsp.sseq.slice(seq_start_index, seq_stop_index);
|
|
190
180
|
let lsend =
|
|
191
181
|
nsseq +
|
|
192
182
|
(lsseq.length - lsseq.split("-").length) *
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
nsseq = lsend +
|
|
183
|
+
sframe_unit() *
|
|
184
|
+
sframe_sign();
|
|
185
|
+
nsseq = lsend + sframe_unit() * sframe_sign();
|
|
196
186
|
|
|
197
187
|
pp.push(
|
|
198
|
-
<pre key={
|
|
199
|
-
<span className="
|
|
200
|
-
{`Query ${
|
|
188
|
+
<pre key={hsp.number + "," + i} className="pre-item m-0 p-0 rounded-none border-0 bg-inherit whitespace-pre-wrap break-keep mt-1 tracking-wider">
|
|
189
|
+
<span className="text-gray-500">
|
|
190
|
+
{`Query ${formatCoords(lqstart, width)} `}
|
|
201
191
|
</span>
|
|
202
192
|
<span>{lqseq}</span>
|
|
203
|
-
<span className="
|
|
193
|
+
<span className="text-gray-500">{` ${lqend}`}</span>
|
|
204
194
|
<br />
|
|
205
|
-
<span className="
|
|
206
|
-
{`${
|
|
195
|
+
<span className="text-gray-500">
|
|
196
|
+
{`${formatCoords("", width + 8)} `}
|
|
207
197
|
</span>
|
|
208
198
|
<span>{lmseq}</span>
|
|
209
199
|
<br />
|
|
210
|
-
<span className="
|
|
211
|
-
{`Subject ${
|
|
200
|
+
<span className="text-gray-500">
|
|
201
|
+
{`Subject ${formatCoords(lsstart, width)} `}
|
|
212
202
|
</span>
|
|
213
203
|
<span>{lsseq}</span>
|
|
214
|
-
<span className="
|
|
204
|
+
<span className="text-gray-500">{` ${lsend}`}</span>
|
|
215
205
|
<br />
|
|
216
206
|
</pre>
|
|
217
207
|
);
|
|
@@ -220,35 +210,23 @@ export default class HSP extends React.Component {
|
|
|
220
210
|
return pp;
|
|
221
211
|
}
|
|
222
212
|
|
|
223
|
-
// Width of the coordinate part of hsp lines. Essentially the length of
|
|
224
|
-
// the largest coordinate.
|
|
225
|
-
width() {
|
|
226
|
-
return _.max(
|
|
227
|
-
_.map(
|
|
228
|
-
[this.hsp.qstart, this.hsp.qend, this.hsp.sstart, this.hsp.send],
|
|
229
|
-
(n) => {
|
|
230
|
-
return n.toString().length;
|
|
231
|
-
}
|
|
232
|
-
)
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
213
|
|
|
236
214
|
// Alignment start coordinate for query sequence.
|
|
237
215
|
//
|
|
238
216
|
// This will be qstart or qend depending on the direction in which the
|
|
239
217
|
// (translated) query sequence aligned.
|
|
240
|
-
|
|
241
|
-
switch (
|
|
218
|
+
const getNqseq = () => {
|
|
219
|
+
switch (props.algorithm) {
|
|
242
220
|
case "blastp":
|
|
243
221
|
case "blastx":
|
|
244
222
|
case "tblastn":
|
|
245
223
|
case "tblastx":
|
|
246
|
-
return
|
|
224
|
+
return hsp.qframe >= 0 ? hsp.qstart : hsp.qend;
|
|
247
225
|
case "blastn":
|
|
248
226
|
// BLASTN is a bit weird in that, no matter which direction the query
|
|
249
227
|
// sequence aligned in, qstart is taken as alignment start coordinate
|
|
250
228
|
// for query.
|
|
251
|
-
return
|
|
229
|
+
return hsp.qstart;
|
|
252
230
|
}
|
|
253
231
|
}
|
|
254
232
|
|
|
@@ -256,18 +234,18 @@ export default class HSP extends React.Component {
|
|
|
256
234
|
//
|
|
257
235
|
// This will be sstart or send depending on the direction in which the
|
|
258
236
|
// (translated) subject sequence aligned.
|
|
259
|
-
|
|
260
|
-
switch (
|
|
237
|
+
const getNsseq = () => {
|
|
238
|
+
switch (props.algorithm) {
|
|
261
239
|
case "blastp":
|
|
262
240
|
case "blastx":
|
|
263
241
|
case "tblastn":
|
|
264
242
|
case "tblastx":
|
|
265
|
-
return
|
|
243
|
+
return hsp.sframe >= 0 ? hsp.sstart : hsp.send;
|
|
266
244
|
case "blastn":
|
|
267
245
|
// BLASTN is a bit weird in that, no matter which direction the
|
|
268
246
|
// subject sequence aligned in, sstart is taken as alignment
|
|
269
247
|
// start coordinate for subject.
|
|
270
|
-
return
|
|
248
|
+
return hsp.sstart;
|
|
271
249
|
}
|
|
272
250
|
}
|
|
273
251
|
|
|
@@ -279,8 +257,8 @@ export default class HSP extends React.Component {
|
|
|
279
257
|
//
|
|
280
258
|
// This will be 1 or 3 depending on whether the query sequence was
|
|
281
259
|
// translated or not.
|
|
282
|
-
qframe_unit() {
|
|
283
|
-
switch (
|
|
260
|
+
const qframe_unit = () => {
|
|
261
|
+
switch (props.algorithm) {
|
|
284
262
|
case "blastp":
|
|
285
263
|
case "blastn":
|
|
286
264
|
case "tblastn":
|
|
@@ -302,8 +280,8 @@ export default class HSP extends React.Component {
|
|
|
302
280
|
//
|
|
303
281
|
// This will be 1 or 3 depending on whether the subject sequence was
|
|
304
282
|
// translated or not.
|
|
305
|
-
sframe_unit() {
|
|
306
|
-
switch (
|
|
283
|
+
const sframe_unit = () => {
|
|
284
|
+
switch (props.algorithm) {
|
|
307
285
|
case "blastp":
|
|
308
286
|
case "blastx":
|
|
309
287
|
case "blastn":
|
|
@@ -326,8 +304,8 @@ export default class HSP extends React.Component {
|
|
|
326
304
|
//
|
|
327
305
|
// This will be +1 or -1, depending on the direction in which the
|
|
328
306
|
// (translated) query sequence aligned.
|
|
329
|
-
qframe_sign() {
|
|
330
|
-
return
|
|
307
|
+
const qframe_sign = () => {
|
|
308
|
+
return hsp.qframe >= 0 ? 1 : -1;
|
|
331
309
|
}
|
|
332
310
|
|
|
333
311
|
// If we should add or subtract sframe_unit from sstart to arrive at send.
|
|
@@ -338,15 +316,15 @@ export default class HSP extends React.Component {
|
|
|
338
316
|
//
|
|
339
317
|
// This will be +1 or -1, depending on the direction in which the
|
|
340
318
|
// (translated) subject sequence aligned.
|
|
341
|
-
sframe_sign() {
|
|
342
|
-
return
|
|
319
|
+
const sframe_sign = () => {
|
|
320
|
+
return hsp.sframe >= 0 ? 1 : -1;
|
|
343
321
|
}
|
|
344
322
|
|
|
345
323
|
/**
|
|
346
324
|
* Pad given coord with ' ' till its length == width. Returns undefined if
|
|
347
325
|
* width is not supplied.
|
|
348
326
|
*/
|
|
349
|
-
formatCoords(coord, width) {
|
|
327
|
+
const formatCoords = (coord, width) => {
|
|
350
328
|
if (width) {
|
|
351
329
|
let padding = width - coord.toString().length;
|
|
352
330
|
return Array(padding + 1)
|
|
@@ -355,16 +333,34 @@ export default class HSP extends React.Component {
|
|
|
355
333
|
}
|
|
356
334
|
}
|
|
357
335
|
|
|
358
|
-
spanCoords(text) {
|
|
359
|
-
return <span className="
|
|
336
|
+
const spanCoords = (text) => {
|
|
337
|
+
return <span className="text-gray-700">{text}</span>;
|
|
360
338
|
}
|
|
339
|
+
|
|
340
|
+
return (
|
|
341
|
+
<div
|
|
342
|
+
className="hsp pt-px pb-5 border-l-2 border-transparent pl-1 -ml-1"
|
|
343
|
+
id={domID()}
|
|
344
|
+
ref={hspRef}
|
|
345
|
+
data-parent-hit={hitDOM_ID()}
|
|
346
|
+
>
|
|
347
|
+
<p className="m-0 p-0 rounded-none border-0 bg-inherit whitespace-pre-wrap break-keep text-sm text-neutral-500 font-semibold tracking-wide">
|
|
348
|
+
{props.showHSPNumbers &&
|
|
349
|
+
`${Helpers.toLetters(hsp.number)}. `}
|
|
350
|
+
{hspStats().map((s, i) => (
|
|
351
|
+
<span key={i}>{s}</span>
|
|
352
|
+
))}
|
|
353
|
+
</p>
|
|
354
|
+
{hspLines()}
|
|
355
|
+
</div>
|
|
356
|
+
);
|
|
361
357
|
}
|
|
362
358
|
|
|
363
359
|
// Redraw if window resized.
|
|
364
|
-
$(window).resize(
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
);
|
|
360
|
+
// $(window).resize(
|
|
361
|
+
// _.debounce(function () {
|
|
362
|
+
// _.each(HSPComponents, (comp) => {
|
|
363
|
+
// comp.draw();
|
|
364
|
+
// });
|
|
365
|
+
// }, 100)
|
|
366
|
+
// );
|
data/public/js/jquery_world.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import $ from 'jquery';
|
|
2
2
|
import '../packages/jquery-ui@1.13.3';
|
|
3
|
-
import 'bootstrap';
|
|
4
3
|
|
|
5
4
|
global.$ = $;
|
|
6
5
|
/**
|
|
@@ -44,22 +43,32 @@ global.$ = $;
|
|
|
44
43
|
return this.prop('checked', false);
|
|
45
44
|
};
|
|
46
45
|
|
|
47
|
-
|
|
48
46
|
/**
|
|
49
|
-
*
|
|
47
|
+
* Tooltip
|
|
50
48
|
*/
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
49
|
+
$(document).tooltip({
|
|
50
|
+
position: {
|
|
51
|
+
my: 'center bottom-20',
|
|
52
|
+
at: 'center top',
|
|
53
|
+
using: function( position, feedback ) {
|
|
54
|
+
$(this).css(position);
|
|
55
|
+
$('<div>')
|
|
56
|
+
.addClass('arrow')
|
|
57
|
+
.addClass(feedback.vertical)
|
|
58
|
+
.addClass(feedback.horizontal)
|
|
59
|
+
.appendTo(this);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
items: 'rect, .tooltip-item',
|
|
63
|
+
show: false,
|
|
64
|
+
hide: false,
|
|
65
|
+
content: function() {
|
|
66
|
+
var title = $(this).attr('title');
|
|
67
|
+
if (!title) return false;
|
|
68
|
+
var parsedHTML = $.parseHTML(title);
|
|
69
|
+
return parsedHTML;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
63
72
|
|
|
64
73
|
/**
|
|
65
74
|
* Returns true / false if any modal is active.
|
data/public/js/kablammo.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import d3 from 'd3';
|
|
1
|
+
import * as d3 from 'd3';
|
|
2
2
|
import _ from 'underscore';
|
|
3
3
|
import Grapher from 'grapher';
|
|
4
4
|
import * as Helpers from './visualisation_helpers';
|
|
@@ -35,13 +35,13 @@ class Graph {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
static dataName(props) {
|
|
38
|
-
return
|
|
38
|
+
return `Kablammo_query-${props.query.number}_${props.query.id}_${props.hit.id}`;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
constructor($svgContainer, props) {
|
|
42
42
|
this._zoom_scale_by = 1.4;
|
|
43
43
|
this._padding_x = 12;
|
|
44
|
-
this._padding_y =
|
|
44
|
+
this._padding_y = 55;
|
|
45
45
|
|
|
46
46
|
this._canvas_height = $svgContainer.height();
|
|
47
47
|
this._canvas_width = $svgContainer.width();
|
|
@@ -84,7 +84,7 @@ class Graph {
|
|
|
84
84
|
this.svgContainer_d3.insert('svg', ':first-child')
|
|
85
85
|
.attr('height', this._canvas_height)
|
|
86
86
|
.attr('width', this._canvas_width);
|
|
87
|
-
this._svg.raw = this._svg.d3[0][0];
|
|
87
|
+
this._svg.raw = this._svg.d3._groups[0][0];
|
|
88
88
|
this._render_graph();
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -105,13 +105,17 @@ class Graph {
|
|
|
105
105
|
_create_axis(scale, orientation, height, text_anchor, dx, dy, seq_type) {
|
|
106
106
|
var formatter = Helpers.tick_formatter(scale, seq_type);
|
|
107
107
|
var tvalues = scale.ticks();
|
|
108
|
+
var axis;
|
|
108
109
|
tvalues.pop();
|
|
109
|
-
|
|
110
|
-
.
|
|
111
|
-
|
|
110
|
+
if (orientation === 'top') {
|
|
111
|
+
axis = d3.axisTop(scale)
|
|
112
|
+
} else {
|
|
113
|
+
axis = d3.axisBottom(scale)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
axis.ticks(this._axis_ticks)
|
|
112
117
|
.tickValues(tvalues.concat(scale.domain()))
|
|
113
118
|
.tickFormat(formatter)
|
|
114
|
-
.orient(orientation);
|
|
115
119
|
|
|
116
120
|
var container = this._svg.d3.append('g')
|
|
117
121
|
.attr('class', 'axis')
|
|
@@ -307,10 +311,10 @@ class Graph {
|
|
|
307
311
|
subject_range.reverse();
|
|
308
312
|
}
|
|
309
313
|
|
|
310
|
-
var query_scale = d3.
|
|
314
|
+
var query_scale = d3.scaleLinear()
|
|
311
315
|
.domain([1, this._query_length])
|
|
312
316
|
.range(query_range);
|
|
313
|
-
var subject_scale = d3.
|
|
317
|
+
var subject_scale = d3.scaleLinear()
|
|
314
318
|
.domain([1, this._subject_length])
|
|
315
319
|
.range(subject_range);
|
|
316
320
|
query_scale.original_domain = query_scale.domain();
|