dasmoth / dalliance

Interactive web-based genome browser.
http://www.biodalliance.org/
BSD 2-Clause "Simplified" License
226 stars 68 forks source link

Browser loads wrong location in React component #239

Closed denisemauldin closed 6 years ago

denisemauldin commented 6 years ago

I have a React component that loads biodalliance. I send it a new viewRegion and a new bed string to update the information displayed by the component. However, after the first time, the browser no longer updates to the location and I have to call the setLocation API (which means that the window has to scroll/refresh twice). Why does it cache the previous location when I'm creating a new browser on load?

import React from "react"
import styles from "./dalliance.scss"

class Dalliance extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            'viewRegion': '',
        }
    }

    componentDidMount() {
        if (this.props.viewRegion) {
            this.createSources();
        }
    }

    shouldComponentUpdate(nextProps, nextState) {
        if ((this.state.viewRegion.chromosome != nextProps.viewRegion.chromosome)
            || (this.state.viewRegion.viewStart != nextProps.viewRegion.viewStart)
            || (this.state.viewRegion.viewEnd != nextProps.viewRegion.viewEnd)) {
            this.createSources();
            return true;
        }
        return false;
    }

    createSources = () => {
        var sources = [
            {
                name: 'Genome',
                twoBitURI: 'http://www.biodalliance.org/datasets/hg38.2bit',
                tier_type: 'sequence'
            },
            {
                name: 'GENCODE',
                desc: 'Gene structures from GENCODE 20',
                bwgURI: 'http://www.biodalliance.org/datasets/GRCh38/gencode.v20.annotation.bb',
                stylesheet_uri: 'http://www.biodalliance.org/stylesheets/gencode2.xml',
                collapseSuperGroups: true,
                trixURI: 'http://www.biodalliance.org/datasets/GRCh38/gencode.v20.annotation.ix'
            },

            {
                name: 'SNPs',
                tier_type: 'ensembl',
                species: 'human',
                type: 'variation',
                disabled: true,
                featureInfoPlugin: function (f, info) {
                    if (f.id) {
                        info.add('SNP', makeElement('a', f.id, { href: 'http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=' + f.id, target: '_newtab' }));
                    }
                }
            },
            {
                name: "Design",
                blob: new Blob([this.props.bed], { type: 'text/csv' }),
                tier_type: 'memstore',
                payload: 'bed',
                style: [
                    {
                        type: 'transcript',
                        style: {
                            glyph: 'BOX',
                            HEIGHT: 10,
                            FGCOLOR: 'black',
                            BGCOLOR: 'white',
                            BUMP: 'yes',
                            LABEL: 'yes',
                            ZINDEX: 20

                        }
                    },
                    {
                        type: 'translation',
                        style: {
                            glyph: 'BOX',
                            HEIGHT: 10,
                            FGCOLOR: 'black',
                            BGITEM: 'yes',
                            ZINDEX: 200,
                        }
                    }]
            },
            {
                name: 'Repeats',
                desc: 'Repeat annotation from UCSC',
                bwgURI: 'http://www.biodalliance.org/datasets/GRCh38/repeats.bb',
                stylesheet_uri: 'http://www.biodalliance.org/stylesheets/bb-repeats2.xml'
            }
        ];
        this.createBrowser(sources);
    }

    createBrowser = (sources) => {
        // this Browser setup load the proper location on the first load of the component at all
        var b = new Browser({
            chr: this.props.viewRegion.chromosome,
            viewStart: this.props.viewRegion.viewStart,
            viewEnd: this.props.viewRegion.viewEnd,
            cookieKey: 'human-grc_h38',
            coordSystem: {
                speciesName: 'Human',
                taxon: 9606,
                auth: 'GRCh',
                version: '38',
                ucscName: 'hg38'
            },
            chains: {
                hg19ToHg38: new Chainset('http://www.derkholm.net:8080/das/hg19ToHg38/', 'GRCh37', 'GRCh38',
                    {
                        speciesName: 'Human',
                        taxon: 9606,
                        auth: 'GRCh',
                        version: 37,
                        ucscName: 'hg19'
                    })
            },
            sources: sources,
        });

        // have to call this in order to get the browser to scroll to the right location on second load
        b.setLocation(
            this.props.viewRegion.chromosome,
            this.props.viewRegion.viewStart,
            this.props.viewRegion.viewEnd,

        )
        this.setState({ 'viewRegion': this.props.viewRegion })
    }

    render() {
        return (
            <div id="svgHolder" key={this.props.viewRegion}>
                Loading dalliance...
            </div>
        )
    }
}

export default Dalliance;
dasmoth commented 6 years ago

There's a "persistence" system which works by default to maintain view-regions and a few other bits of state. Tends to make sense when using Biodalliance as a stand-alone application, less so when embedding. You'll want to use either the noPersist or the noPersistView option to disable this behaviour. See here for more details.

denisemauldin commented 6 years ago

For posterity: noPersistView only disables the browser location settings (afaict). In order to not have the browser save the track locations to localStorage you have to use noPersist. So if you need to load either https or http tracks based on the window proto, you need to set noPersist so it'll update the track locations.