sequenceserver 1.1.0.beta8 → 1.1.0.beta10
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/lib/sequenceserver/blast/hsp.rb +2 -174
- data/lib/sequenceserver/blast/report.rb +4 -3
- data/lib/sequenceserver/job.rb +2 -1
- data/lib/sequenceserver/version.rb +1 -1
- data/public/css/grapher.css +50 -35
- data/public/css/sequenceserver.css +25 -16
- data/public/css/sequenceserver.min.css +3 -3
- data/public/js/circos.js +1 -1
- data/public/js/grapher.js +8 -3
- data/public/js/hits_overview.js +4 -6
- data/public/js/hsp.js +283 -0
- data/public/js/kablammo.js +3 -3
- data/public/js/report.js +668 -850
- data/public/js/search.js +208 -180
- data/public/js/utils.js +77 -0
- data/public/sequenceserver-report.min.js +14 -14
- data/public/sequenceserver-search.min.js +2 -2
- metadata +4 -2
    
        data/public/js/search.js
    CHANGED
    
    | @@ -7,6 +7,23 @@ import React from 'react'; | |
| 7 7 | 
             
             */
         | 
| 8 8 | 
             
            $.webshims.polyfill('forms');
         | 
| 9 9 |  | 
| 10 | 
            +
            var Page = React.createClass({
         | 
| 11 | 
            +
                render: function () {
         | 
| 12 | 
            +
                    return (
         | 
| 13 | 
            +
                        <div>
         | 
| 14 | 
            +
                            <DnD ref="dnd"/>
         | 
| 15 | 
            +
                            <Form ref="form"/>
         | 
| 16 | 
            +
                        </div>
         | 
| 17 | 
            +
                    );
         | 
| 18 | 
            +
                },
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                componentDidMount: function () {
         | 
| 21 | 
            +
                    this.refs.dnd.setState({
         | 
| 22 | 
            +
                        query: this.refs.form.refs.query
         | 
| 23 | 
            +
                    })
         | 
| 24 | 
            +
                }
         | 
| 25 | 
            +
            });
         | 
| 26 | 
            +
             | 
| 10 27 | 
             
            /** Drag n drop widget.
         | 
| 11 28 | 
             
             */
         | 
| 12 29 | 
             
            var DnD = React.createClass({
         | 
| @@ -171,6 +188,135 @@ var DnD = React.createClass({ | |
| 171 188 | 
             
                }
         | 
| 172 189 | 
             
            });
         | 
| 173 190 |  | 
| 191 | 
            +
            /**
         | 
| 192 | 
            +
             * Search form.
         | 
| 193 | 
            +
             *
         | 
| 194 | 
            +
             * Top level component that initialises and holds all other components, and
         | 
| 195 | 
            +
             * facilitates communication between them.
         | 
| 196 | 
            +
             */
         | 
| 197 | 
            +
            var Form = React.createClass({
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                getInitialState: function () {
         | 
| 200 | 
            +
                    return {
         | 
| 201 | 
            +
                        databases: {},
         | 
| 202 | 
            +
                        preDefinedOpts: {
         | 
| 203 | 
            +
                            'blastn':  ['-task blastn', '-evalue 1e-5'],
         | 
| 204 | 
            +
                            'blastp':  ['-evalue 1e-5'],
         | 
| 205 | 
            +
                            'blastx':  ['-evalue 1e-5'],
         | 
| 206 | 
            +
                            'tblastx': ['-evalue 1e-5'],
         | 
| 207 | 
            +
                            'tblastn': ['-evalue 1e-5']
         | 
| 208 | 
            +
                        }
         | 
| 209 | 
            +
                    };
         | 
| 210 | 
            +
                },
         | 
| 211 | 
            +
             | 
| 212 | 
            +
                componentDidMount: function () {
         | 
| 213 | 
            +
                    $.getJSON("searchdata.json", _.bind(function(data) {
         | 
| 214 | 
            +
                        this.setState({
         | 
| 215 | 
            +
                            databases: data["database"], preDefinedOpts: $.extend({},
         | 
| 216 | 
            +
                            this.state.preDefinedOpts, data["options"])
         | 
| 217 | 
            +
                        });
         | 
| 218 | 
            +
                    }, this));
         | 
| 219 | 
            +
             | 
| 220 | 
            +
                   $(document).bind("keydown", _.bind(function (e) {
         | 
| 221 | 
            +
                       if (e.ctrlKey && e.keyCode === 13 &&
         | 
| 222 | 
            +
                           !$('#method').is(':disabled')) {
         | 
| 223 | 
            +
                           $(this.getDOMNode()).trigger('submit');
         | 
| 224 | 
            +
                       }
         | 
| 225 | 
            +
                   }, this));
         | 
| 226 | 
            +
                },
         | 
| 227 | 
            +
             | 
| 228 | 
            +
                determineBlastMethod: function () {
         | 
| 229 | 
            +
                    var database_type = this.databaseType;
         | 
| 230 | 
            +
                    var sequence_type = this.sequenceType;
         | 
| 231 | 
            +
             | 
| 232 | 
            +
                    if (this.refs.query.isEmpty()) {
         | 
| 233 | 
            +
                        return [];
         | 
| 234 | 
            +
                    }
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                    //database type is always known
         | 
| 237 | 
            +
                    switch (database_type) {
         | 
| 238 | 
            +
                        case 'protein':
         | 
| 239 | 
            +
                            switch (sequence_type) {
         | 
| 240 | 
            +
                                case undefined:
         | 
| 241 | 
            +
                                    return ['blastp', 'blastx'];
         | 
| 242 | 
            +
                                case 'protein':
         | 
| 243 | 
            +
                                    return ['blastp'];
         | 
| 244 | 
            +
                                case 'nucleotide':
         | 
| 245 | 
            +
                                    return ['blastx'];
         | 
| 246 | 
            +
                            }
         | 
| 247 | 
            +
                            break;
         | 
| 248 | 
            +
                        case 'nucleotide':
         | 
| 249 | 
            +
                            switch (sequence_type) {
         | 
| 250 | 
            +
                                case undefined:
         | 
| 251 | 
            +
                                    return ['tblastn', 'blastn', 'tblastx'];
         | 
| 252 | 
            +
                                case 'protein':
         | 
| 253 | 
            +
                                    return ['tblastn'];
         | 
| 254 | 
            +
                                case 'nucleotide':
         | 
| 255 | 
            +
                                    return ['blastn', 'tblastx'];
         | 
| 256 | 
            +
                            }
         | 
| 257 | 
            +
                            break;
         | 
| 258 | 
            +
                    }
         | 
| 259 | 
            +
             | 
| 260 | 
            +
                    return [];
         | 
| 261 | 
            +
                },
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                handleSequenceTypeChanged: function (type) {
         | 
| 264 | 
            +
                    this.sequenceType = type;
         | 
| 265 | 
            +
                    this.refs.button.setState({
         | 
| 266 | 
            +
                        hasQuery: !this.refs.query.isEmpty(),
         | 
| 267 | 
            +
                        hasDatabases: !!this.databaseType,
         | 
| 268 | 
            +
                        methods: this.determineBlastMethod()
         | 
| 269 | 
            +
                    });
         | 
| 270 | 
            +
                },
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                handleDatabaseTypeChanaged: function (type) {
         | 
| 273 | 
            +
                    this.databaseType = type;
         | 
| 274 | 
            +
                    this.refs.button.setState({
         | 
| 275 | 
            +
                        hasQuery: !this.refs.query.isEmpty(),
         | 
| 276 | 
            +
                        hasDatabases: !!this.databaseType,
         | 
| 277 | 
            +
                        methods: this.determineBlastMethod()
         | 
| 278 | 
            +
                    });
         | 
| 279 | 
            +
                },
         | 
| 280 | 
            +
             | 
| 281 | 
            +
                handleAlgoChanged: function (algo) {
         | 
| 282 | 
            +
                  if (this.state.preDefinedOpts.hasOwnProperty(algo)) {
         | 
| 283 | 
            +
                    this.refs.opts.setState({
         | 
| 284 | 
            +
                      preOpts: this.state.preDefinedOpts[algo].join(" ")
         | 
| 285 | 
            +
                    });
         | 
| 286 | 
            +
                  }
         | 
| 287 | 
            +
                  else {
         | 
| 288 | 
            +
                    this.refs.opts.setState({preOpts: ""});
         | 
| 289 | 
            +
                  }
         | 
| 290 | 
            +
                },
         | 
| 291 | 
            +
             | 
| 292 | 
            +
                render: function () {
         | 
| 293 | 
            +
                    return (
         | 
| 294 | 
            +
                        <div
         | 
| 295 | 
            +
                            className="container">
         | 
| 296 | 
            +
                            <form
         | 
| 297 | 
            +
                                id="blast" method="post" className="form-horizontal">
         | 
| 298 | 
            +
                                <div
         | 
| 299 | 
            +
                                    className="form-group query-container">
         | 
| 300 | 
            +
                                    <Query ref="query" onSequenceTypeChanged={this.handleSequenceTypeChanged}/>
         | 
| 301 | 
            +
                                </div>
         | 
| 302 | 
            +
                                <div
         | 
| 303 | 
            +
                                    className="notifications" id="notifications">
         | 
| 304 | 
            +
                                    <NucleotideNotification/>
         | 
| 305 | 
            +
                                    <ProteinNotification/>
         | 
| 306 | 
            +
                                    <MixedNotification/>
         | 
| 307 | 
            +
                                </div>
         | 
| 308 | 
            +
                                <Databases ref="databases" onDatabaseTypeChanged={this.handleDatabaseTypeChanaged} databases={this.state.databases}/>
         | 
| 309 | 
            +
                                <div
         | 
| 310 | 
            +
                                    className="form-group">
         | 
| 311 | 
            +
                                    <Options ref="opts"/>
         | 
| 312 | 
            +
                                    <SearchButton ref="button" onAlgoChanged={this.handleAlgoChanged}/>
         | 
| 313 | 
            +
                                </div>
         | 
| 314 | 
            +
                            </form>
         | 
| 315 | 
            +
                        </div>
         | 
| 316 | 
            +
                    );
         | 
| 317 | 
            +
                }
         | 
| 318 | 
            +
            });
         | 
| 319 | 
            +
             | 
| 174 320 | 
             
            /**
         | 
| 175 321 | 
             
             * Query widget.
         | 
| 176 322 | 
             
             */
         | 
| @@ -487,42 +633,70 @@ var Databases = React.createClass({ | |
| 487 633 | 
             
                },
         | 
| 488 634 |  | 
| 489 635 | 
             
                handleClick: function (database) {
         | 
| 490 | 
            -
                    var type = this.nselected() ? database.type : ''
         | 
| 636 | 
            +
                    var type = this.nselected() ? database.type : '';
         | 
| 491 637 | 
             
                    this.setState({type: type});
         | 
| 492 638 | 
             
                },
         | 
| 493 639 |  | 
| 640 | 
            +
                handleToggle: function (toggleState, type) {
         | 
| 641 | 
            +
                    switch (toggleState) {
         | 
| 642 | 
            +
                        case '[Select all]':
         | 
| 643 | 
            +
                            $(`.${type} .database input:not(:checked)`).click();
         | 
| 644 | 
            +
                            break;
         | 
| 645 | 
            +
                        case '[Deselect all]':
         | 
| 646 | 
            +
                            $(`.${type} .database input:checked`).click();
         | 
| 647 | 
            +
                            break;
         | 
| 648 | 
            +
                    }
         | 
| 649 | 
            +
                },
         | 
| 650 | 
            +
             | 
| 494 651 | 
             
                render: function () {
         | 
| 495 652 | 
             
                    return (
         | 
| 496 | 
            -
                        <div
         | 
| 497 | 
            -
             | 
| 498 | 
            -
             | 
| 499 | 
            -
             | 
| 500 | 
            -
             | 
| 501 | 
            -
             | 
| 502 | 
            -
             | 
| 503 | 
            -
             | 
| 504 | 
            -
             | 
| 505 | 
            -
             | 
| 506 | 
            -
             | 
| 507 | 
            -
             | 
| 508 | 
            -
             | 
| 509 | 
            -
             | 
| 510 | 
            -
             | 
| 511 | 
            -
             | 
| 512 | 
            -
             | 
| 513 | 
            -
             | 
| 514 | 
            -
             | 
| 515 | 
            -
             | 
| 516 | 
            -
             | 
| 517 | 
            -
             | 
| 518 | 
            -
             | 
| 519 | 
            -
             | 
| 520 | 
            -
             | 
| 521 | 
            -
             | 
| 522 | 
            -
             | 
| 523 | 
            -
             | 
| 524 | 
            -
                                 | 
| 525 | 
            -
             | 
| 653 | 
            +
                        <div className="form-group databases-container">
         | 
| 654 | 
            +
                            { _.map(this.categories(), this.renderDatabases) }
         | 
| 655 | 
            +
                        </div>
         | 
| 656 | 
            +
                    );
         | 
| 657 | 
            +
                },
         | 
| 658 | 
            +
             | 
| 659 | 
            +
                renderDatabases: function (category) {
         | 
| 660 | 
            +
                    // Panel name and column width.
         | 
| 661 | 
            +
                    var panelTitle = category[0].toUpperCase() +
         | 
| 662 | 
            +
                        category.substring(1).toLowerCase() + " databases";
         | 
| 663 | 
            +
                    var columnClass = this.categories().length === 1 ?  'col-md-12' :
         | 
| 664 | 
            +
                        'col-md-6';
         | 
| 665 | 
            +
             | 
| 666 | 
            +
                    // Toggle button.
         | 
| 667 | 
            +
                    var toggleState = '[Select all]';
         | 
| 668 | 
            +
                    var toggleClass = 'btn btn-link';
         | 
| 669 | 
            +
                    var toggleShown = this.databases(category).length > 1 ;
         | 
| 670 | 
            +
                    var toggleDisabled = this.state.type && this.state.type !== category;
         | 
| 671 | 
            +
                    if (toggleShown && toggleDisabled) toggleClass += ' disabled';
         | 
| 672 | 
            +
                    if (!toggleShown) toggleClass += ' hidden';
         | 
| 673 | 
            +
                    if (this.nselected() === this.databases(category).length) {
         | 
| 674 | 
            +
                        toggleState = '[Deselect all]';
         | 
| 675 | 
            +
                    }
         | 
| 676 | 
            +
             | 
| 677 | 
            +
                    // JSX.
         | 
| 678 | 
            +
                    return (
         | 
| 679 | 
            +
                        <div className={columnClass}>
         | 
| 680 | 
            +
                            <div className="panel panel-default">
         | 
| 681 | 
            +
                                <div className="panel-heading">
         | 
| 682 | 
            +
                                    <h4 style={{display: "inline"}}>{panelTitle}</h4>   
         | 
| 683 | 
            +
                                    <button type="button" className={toggleClass} disabled={toggleDisabled}
         | 
| 684 | 
            +
                                        onClick={ function () { this.handleToggle(toggleState, category) }.bind(this) }>
         | 
| 685 | 
            +
                                        {toggleState}
         | 
| 686 | 
            +
                                    </button>
         | 
| 687 | 
            +
                                </div>
         | 
| 688 | 
            +
                                <ul className={"list-group databases " + category}>
         | 
| 689 | 
            +
                                    {
         | 
| 690 | 
            +
                                        _.map(this.databases(category), _.bind(function (database) {
         | 
| 691 | 
            +
                                            return (
         | 
| 692 | 
            +
                                                <li className="list-group-item">
         | 
| 693 | 
            +
                                                    { this.renderDatabase(database) }
         | 
| 694 | 
            +
                                                </li>
         | 
| 695 | 
            +
                                            );
         | 
| 696 | 
            +
                                        }, this))
         | 
| 697 | 
            +
                                    }
         | 
| 698 | 
            +
                                </ul>
         | 
| 699 | 
            +
                            </div>
         | 
| 526 700 | 
             
                        </div>
         | 
| 527 701 | 
             
                    );
         | 
| 528 702 | 
             
                },
         | 
| @@ -547,9 +721,9 @@ var Databases = React.createClass({ | |
| 547 721 | 
             
                    );
         | 
| 548 722 | 
             
                },
         | 
| 549 723 |  | 
| 550 | 
            -
                shouldComponentUpdate: function (props, state) {
         | 
| 551 | 
            -
                    return !(state.type && state.type === this.state.type);
         | 
| 552 | 
            -
                },
         | 
| 724 | 
            +
                //shouldComponentUpdate: function (props, state) {
         | 
| 725 | 
            +
                    //return !(state.type && state.type === this.state.type);
         | 
| 726 | 
            +
                //},
         | 
| 553 727 |  | 
| 554 728 | 
             
                componentDidUpdate: function () {
         | 
| 555 729 | 
             
                    if (this.databases() && this.databases().length === 1) {
         | 
| @@ -788,150 +962,4 @@ var SearchButton = React.createClass({ | |
| 788 962 | 
             
                }
         | 
| 789 963 | 
             
            });
         | 
| 790 964 |  | 
| 791 | 
            -
            /**
         | 
| 792 | 
            -
             * Search form.
         | 
| 793 | 
            -
             *
         | 
| 794 | 
            -
             * Top level component that initialises and holds all other components, and
         | 
| 795 | 
            -
             * facilitates communication between them.
         | 
| 796 | 
            -
             */
         | 
| 797 | 
            -
            var Form = React.createClass({
         | 
| 798 | 
            -
             | 
| 799 | 
            -
                getInitialState: function () {
         | 
| 800 | 
            -
                    return {
         | 
| 801 | 
            -
                        databases: {},
         | 
| 802 | 
            -
                        preDefinedOpts: {
         | 
| 803 | 
            -
                            'blastn':  ['-task blastn', '-evalue 1e-5'],
         | 
| 804 | 
            -
                            'blastp':  ['-evalue 1e-5'],
         | 
| 805 | 
            -
                            'blastx':  ['-evalue 1e-5'],
         | 
| 806 | 
            -
                            'tblastx': ['-evalue 1e-5'],
         | 
| 807 | 
            -
                            'tblastn': ['-evalue 1e-5']
         | 
| 808 | 
            -
                        }
         | 
| 809 | 
            -
                    };
         | 
| 810 | 
            -
                },
         | 
| 811 | 
            -
             | 
| 812 | 
            -
                componentDidMount: function () {
         | 
| 813 | 
            -
                    $.getJSON("searchdata.json", _.bind(function(data) {
         | 
| 814 | 
            -
                        this.setState({
         | 
| 815 | 
            -
                            databases: data["database"], preDefinedOpts: $.extend({},
         | 
| 816 | 
            -
                            this.state.preDefinedOpts, data["options"])
         | 
| 817 | 
            -
                        });
         | 
| 818 | 
            -
                    }, this));
         | 
| 819 | 
            -
             | 
| 820 | 
            -
                   $(document).bind("keydown", _.bind(function (e) {
         | 
| 821 | 
            -
                       if (e.ctrlKey && e.keyCode === 13 &&
         | 
| 822 | 
            -
                           !$('#method').is(':disabled')) {
         | 
| 823 | 
            -
                           $(this.getDOMNode()).trigger('submit');
         | 
| 824 | 
            -
                       }
         | 
| 825 | 
            -
                   }, this));
         | 
| 826 | 
            -
                },
         | 
| 827 | 
            -
             | 
| 828 | 
            -
                determineBlastMethod: function () {
         | 
| 829 | 
            -
                    var database_type = this.databaseType;
         | 
| 830 | 
            -
                    var sequence_type = this.sequenceType;
         | 
| 831 | 
            -
             | 
| 832 | 
            -
                    if (this.refs.query.isEmpty()) {
         | 
| 833 | 
            -
                        return [];
         | 
| 834 | 
            -
                    }
         | 
| 835 | 
            -
             | 
| 836 | 
            -
                    //database type is always known
         | 
| 837 | 
            -
                    switch (database_type) {
         | 
| 838 | 
            -
                        case 'protein':
         | 
| 839 | 
            -
                            switch (sequence_type) {
         | 
| 840 | 
            -
                                case undefined:
         | 
| 841 | 
            -
                                    return ['blastp', 'blastx'];
         | 
| 842 | 
            -
                                case 'protein':
         | 
| 843 | 
            -
                                    return ['blastp'];
         | 
| 844 | 
            -
                                case 'nucleotide':
         | 
| 845 | 
            -
                                    return ['blastx'];
         | 
| 846 | 
            -
                            }
         | 
| 847 | 
            -
                            break;
         | 
| 848 | 
            -
                        case 'nucleotide':
         | 
| 849 | 
            -
                            switch (sequence_type) {
         | 
| 850 | 
            -
                                case undefined:
         | 
| 851 | 
            -
                                    return ['tblastn', 'blastn', 'tblastx'];
         | 
| 852 | 
            -
                                case 'protein':
         | 
| 853 | 
            -
                                    return ['tblastn'];
         | 
| 854 | 
            -
                                case 'nucleotide':
         | 
| 855 | 
            -
                                    return ['blastn', 'tblastx'];
         | 
| 856 | 
            -
                            }
         | 
| 857 | 
            -
                            break;
         | 
| 858 | 
            -
                    }
         | 
| 859 | 
            -
             | 
| 860 | 
            -
                    return [];
         | 
| 861 | 
            -
                },
         | 
| 862 | 
            -
             | 
| 863 | 
            -
                handleSequenceTypeChanged: function (type) {
         | 
| 864 | 
            -
                    this.sequenceType = type;
         | 
| 865 | 
            -
                    this.refs.button.setState({
         | 
| 866 | 
            -
                        hasQuery: !this.refs.query.isEmpty(),
         | 
| 867 | 
            -
                        hasDatabases: !!this.databaseType,
         | 
| 868 | 
            -
                        methods: this.determineBlastMethod()
         | 
| 869 | 
            -
                    });
         | 
| 870 | 
            -
                },
         | 
| 871 | 
            -
             | 
| 872 | 
            -
                handleDatabaseTypeChanaged: function (type) {
         | 
| 873 | 
            -
                    this.databaseType = type;
         | 
| 874 | 
            -
                    this.refs.button.setState({
         | 
| 875 | 
            -
                        hasQuery: !this.refs.query.isEmpty(),
         | 
| 876 | 
            -
                        hasDatabases: !!this.databaseType,
         | 
| 877 | 
            -
                        methods: this.determineBlastMethod()
         | 
| 878 | 
            -
                    });
         | 
| 879 | 
            -
                },
         | 
| 880 | 
            -
             | 
| 881 | 
            -
                handleAlgoChanged: function (algo) {
         | 
| 882 | 
            -
                  if (this.state.preDefinedOpts.hasOwnProperty(algo)) {
         | 
| 883 | 
            -
                    this.refs.opts.setState({
         | 
| 884 | 
            -
                      preOpts: this.state.preDefinedOpts[algo].join(" ")
         | 
| 885 | 
            -
                    });
         | 
| 886 | 
            -
                  }
         | 
| 887 | 
            -
                  else {
         | 
| 888 | 
            -
                    this.refs.opts.setState({preOpts: ""});
         | 
| 889 | 
            -
                  }
         | 
| 890 | 
            -
                },
         | 
| 891 | 
            -
             | 
| 892 | 
            -
                render: function () {
         | 
| 893 | 
            -
                    return (
         | 
| 894 | 
            -
                        <div
         | 
| 895 | 
            -
                            className="container">
         | 
| 896 | 
            -
                            <form
         | 
| 897 | 
            -
                                id="blast" method="post" className="form-horizontal">
         | 
| 898 | 
            -
                                <div
         | 
| 899 | 
            -
                                    className="form-group query-container">
         | 
| 900 | 
            -
                                    <Query ref="query" onSequenceTypeChanged={this.handleSequenceTypeChanged}/>
         | 
| 901 | 
            -
                                </div>
         | 
| 902 | 
            -
                                <div
         | 
| 903 | 
            -
                                    className="notifications" id="notifications">
         | 
| 904 | 
            -
                                    <NucleotideNotification/>
         | 
| 905 | 
            -
                                    <ProteinNotification/>
         | 
| 906 | 
            -
                                    <MixedNotification/>
         | 
| 907 | 
            -
                                </div>
         | 
| 908 | 
            -
                                <Databases ref="databases" onDatabaseTypeChanged={this.handleDatabaseTypeChanaged} databases={this.state.databases}/>
         | 
| 909 | 
            -
                                <div
         | 
| 910 | 
            -
                                    className="form-group">
         | 
| 911 | 
            -
                                    <Options ref="opts"/>
         | 
| 912 | 
            -
                                    <SearchButton ref="button" onAlgoChanged={this.handleAlgoChanged}/>
         | 
| 913 | 
            -
                                </div>
         | 
| 914 | 
            -
                            </form>
         | 
| 915 | 
            -
                        </div>
         | 
| 916 | 
            -
                    );
         | 
| 917 | 
            -
                }
         | 
| 918 | 
            -
            });
         | 
| 919 | 
            -
             | 
| 920 | 
            -
            var Page = React.createClass({
         | 
| 921 | 
            -
                render: function () {
         | 
| 922 | 
            -
                    return (
         | 
| 923 | 
            -
                        <div>
         | 
| 924 | 
            -
                            <DnD ref="dnd"/>
         | 
| 925 | 
            -
                            <Form ref="form"/>
         | 
| 926 | 
            -
                        </div>
         | 
| 927 | 
            -
                    );
         | 
| 928 | 
            -
                },
         | 
| 929 | 
            -
             | 
| 930 | 
            -
                componentDidMount: function () {
         | 
| 931 | 
            -
                    this.refs.dnd.setState({
         | 
| 932 | 
            -
                        query: this.refs.form.refs.query
         | 
| 933 | 
            -
                    })
         | 
| 934 | 
            -
                }
         | 
| 935 | 
            -
            });
         | 
| 936 | 
            -
             | 
| 937 965 | 
             
            React.render(<Page/>, document.getElementById('view'));
         | 
    
        data/public/js/utils.js
    ADDED
    
    | @@ -0,0 +1,77 @@ | |
| 1 | 
            +
            import React from 'react';
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            var Utils = {
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                /**
         | 
| 6 | 
            +
                 * Render URL for sequence-viewer.
         | 
| 7 | 
            +
                 */
         | 
| 8 | 
            +
                a: function (link) {
         | 
| 9 | 
            +
                    if (link.title && link.url)
         | 
| 10 | 
            +
                    {
         | 
| 11 | 
            +
                        return (
         | 
| 12 | 
            +
                            <a href={link.url} className={link.class} target='_blank'>
         | 
| 13 | 
            +
                                {link.icon && <i className={"fa " + link.icon}></i>}
         | 
| 14 | 
            +
                                {" " + link.title + " "}
         | 
| 15 | 
            +
                            </a>
         | 
| 16 | 
            +
                        );
         | 
| 17 | 
            +
                    }
         | 
| 18 | 
            +
                },
         | 
| 19 | 
            +
             | 
| 20 | 
            +
             | 
| 21 | 
            +
                /***********************************
         | 
| 22 | 
            +
                 * Formatters for hits & hsp table *
         | 
| 23 | 
            +
                 ***********************************/
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                // Formats an array of two elements as "first (last)".
         | 
| 26 | 
            +
                format_2_tuple: function (tuple) {
         | 
| 27 | 
            +
                    return (tuple[0] + " (" + tuple[tuple.length - 1] + ")");
         | 
| 28 | 
            +
                },
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                /**
         | 
| 31 | 
            +
                 * Returns fraction as percentage
         | 
| 32 | 
            +
                 */
         | 
| 33 | 
            +
                inPercentage: function (num , den) {
         | 
| 34 | 
            +
                    return `${(num * 100.0 / den).toFixed(2)}%`;
         | 
| 35 | 
            +
                },
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                /**
         | 
| 38 | 
            +
                 * Returns fractional representation as String.
         | 
| 39 | 
            +
                 */
         | 
| 40 | 
            +
                inFraction: function (num , den) {
         | 
| 41 | 
            +
                    return num + "/" + den;
         | 
| 42 | 
            +
                },
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                /**
         | 
| 45 | 
            +
                 * Returns given Float as String formatted to two decimal places.
         | 
| 46 | 
            +
                 */
         | 
| 47 | 
            +
                inTwoDecimal: function (num) {
         | 
| 48 | 
            +
                    return num.toFixed(2)
         | 
| 49 | 
            +
                },
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                /**
         | 
| 52 | 
            +
                 * Returns zero if num is zero. Returns two decimal representation of num
         | 
| 53 | 
            +
                 * if num is between [1..10). Returns num in scientific notation otherwise.
         | 
| 54 | 
            +
                 */
         | 
| 55 | 
            +
                inExponential: function (num) {
         | 
| 56 | 
            +
                    // Nothing to do if num is 0.
         | 
| 57 | 
            +
                    if (num === 0) {
         | 
| 58 | 
            +
                        return 0
         | 
| 59 | 
            +
                    }
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                    // Round to two decimal places if in the rane [1..10).
         | 
| 62 | 
            +
                    if (num >= 1 && num < 10)
         | 
| 63 | 
            +
                    {
         | 
| 64 | 
            +
                        return this.inTwoDecimal(num)
         | 
| 65 | 
            +
                    }
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    // Return numbers in the range [0..1) and [10..Inf] in
         | 
| 68 | 
            +
                    // scientific format.
         | 
| 69 | 
            +
                    var exp = num.toExponential(2);
         | 
| 70 | 
            +
                    var parts = exp.split("e");
         | 
| 71 | 
            +
                    var base  = parts[0];
         | 
| 72 | 
            +
                    var power = parts[1];
         | 
| 73 | 
            +
                    return <span>{base} × 10<sup>{power}</sup></span>;
         | 
| 74 | 
            +
                }
         | 
| 75 | 
            +
            };
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            export default Utils;
         |