From 73bfe9ce8357ed5f935cb632f85f3b56b02d8c9a Mon Sep 17 00:00:00 2001 From: jrobinso <933148+jrobinso@users.noreply.github.com> Date: Thu, 24 Oct 2024 12:03:21 -0700 Subject: [PATCH] .. --- js/responsiveNavbar.js | 48 +++++----- js/ui/zoomWidget.js | 197 +++++++++++++++++++---------------------- 2 files changed, 115 insertions(+), 130 deletions(-) diff --git a/js/responsiveNavbar.js b/js/responsiveNavbar.js index 43c055366..8a2f637a5 100644 --- a/js/responsiveNavbar.js +++ b/js/responsiveNavbar.js @@ -54,6 +54,7 @@ class ResponsiveNavbar { const $navbarLeftContainer = $('
', {class: 'igv-navbar-left-container'}) $navBar.append($navbarLeftContainer) + $navbarLeftContainer // IGV logo const $logo = $('
', {class: 'igv-logo'}) @@ -140,33 +141,24 @@ class ResponsiveNavbar { } } - this.zoomWidget = new ZoomWidget(browser, $navbarRightContainer.get(0)) + this.zoomWidget = new ZoomWidget(config, browser, $navbarRightContainer.get(0)) if (false === config.showNavigation) { this.$navigation.hide() } + this.navbarRightContainer = $navbarRightContainer.get(0) + this.navbarLeftContainer = $navbarLeftContainer.get(0) } navbarDidResize() { - const width = this.$navigation.width() + const navbarWidth = this.$navigation.width() const currentClass = this.currentNavbarButtonClass() if ('igv-navbar-text-button' === currentClass) { - this.textButtonContainerWidth = this.$navigation.get(0).querySelector('.igv-navbar-right-container').getBoundingClientRect().width + this.textButtonContainerWidth = this.navbarRightContainer.getBoundingClientRect().width } - const responsiveClasses = this.getResponsiveClasses(width) - - $(this.zoomWidget.zoomContainer).removeClass() - $(this.zoomWidget.zoomContainer).addClass(responsiveClasses.zoomContainer) - - this.browser.fireEvent('navbar-resize', [responsiveClasses.navbarButton]) - } - - getResponsiveClasses(navbarWidth) { - - const navbarResponsiveClasses = {} const browser = this.browser const isWGV = (browser.isMultiLocusWholeGenomeView()) || @@ -177,36 +169,40 @@ class ResponsiveNavbar { const { x: leftContainerX, width: leftContainerWidth - } = this.$navigation.get(0).querySelector('.igv-navbar-left-container').getBoundingClientRect() + } = this.navbarLeftContainer.getBoundingClientRect() const leftContainerExtent = leftContainerX + leftContainerWidth - const {x: rightContainerX} = this.$navigation.get(0).querySelector('.igv-navbar-right-container').getBoundingClientRect() + const {x: rightContainerX} = this.navbarRightContainer.getBoundingClientRect() const delta = rightContainerX - leftContainerExtent - const currentClass = this.currentNavbarButtonClass() - // console.log(`Current class ${ currentClass } Delta: ${ StringUtils.numberFormatter(Math.floor(delta))}`) + let navbarButtonClass const threshold = 8 if ('igv-navbar-text-button' === currentClass && delta < threshold) { - navbarResponsiveClasses.navbarButton = 'igv-navbar-icon-button' + navbarButtonClass = 'igv-navbar-icon-button' } else if (this.textButtonContainerWidth && 'igv-navbar-icon-button' === currentClass) { const length = navbarWidth - leftContainerExtent if (length - this.textButtonContainerWidth > threshold) { - navbarResponsiveClasses.navbarButton = 'igv-navbar-text-button' + navbarButtonClass = 'igv-navbar-text-button' } - } - + // Update all the buttons (buttons are listeners) + if(currentClass !== navbarButtonClass) { + this.browser.fireEvent('navbar-resize', [navbarButtonClass]) + } + + let zoomContainerClass if (isWGV) { - navbarResponsiveClasses.zoomContainer = 'igv-zoom-widget-hidden' + zoomContainerClass = 'igv-zoom-widget-hidden' } else { - navbarResponsiveClasses.zoomContainer = navbarWidth > 860 ? 'igv-zoom-widget' : 'igv-zoom-widget-900' + zoomContainerClass = navbarWidth > 860 ? 'igv-zoom-widget' : 'igv-zoom-widget-900' } - - return navbarResponsiveClasses + $(this.zoomWidget.zoomContainer).removeClass() + $(this.zoomWidget.zoomContainer).addClass(zoomContainerClass) } + setCenterLineButtonVisibility(isWholeGenomeView) { if (isWholeGenomeView) { this.centerLineButton.setVisibility(!isWholeGenomeView) diff --git a/js/ui/zoomWidget.js b/js/ui/zoomWidget.js index 3019530e6..54e9dc3e8 100644 --- a/js/ui/zoomWidget.js +++ b/js/ui/zoomWidget.js @@ -5,146 +5,135 @@ const sliderMin = 0 let sliderMax = 23 let sliderValueRaw = 0 -const ZoomWidget = function (browser, parent) { +class ZoomWidget { + constructor(config, browser, parent) { - this.browser = browser + this.browser = browser - this.zoomContainer = DOMUtils.div({class: 'igv-zoom-widget'}) - parent.appendChild(this.zoomContainer) + this.zoomContainer = DOMUtils.div({class: 'igv-zoom-widget'}) + parent.appendChild(this.zoomContainer) - // zoom out - this.zoomOutButton = DOMUtils.div() - this.zoomContainer.appendChild(this.zoomOutButton) - this.zoomOutButton.appendChild(createIcon('minus-circle')) - this.zoomOutButton.addEventListener('click', () => { - // browser.zoomWithScaleFactor(2.0) - browser.zoomOut() - }) + // zoom out + this.zoomOutButton = DOMUtils.div() + this.zoomContainer.appendChild(this.zoomOutButton) + this.zoomOutButton.appendChild(createIcon('minus-circle')) + this.zoomOutButton.addEventListener('click', () => { + // browser.zoomWithScaleFactor(2.0) + browser.zoomOut() + }) - // Range slider - const el = DOMUtils.div() - this.zoomContainer.appendChild(el) - this.slider = document.createElement('input') - this.slider.type = 'range' + // Range slider (optional) + if (config.showZoomSlider !== false) { + const el = DOMUtils.div() + this.zoomContainer.appendChild(el) + this.slider = document.createElement('input') + this.slider.type = 'range' - this.slider.min = `${sliderMin}` - this.slider.max = `${sliderMax}` + this.slider.min = `${sliderMin}` + this.slider.max = `${sliderMax}` - el.appendChild(this.slider) + el.appendChild(this.slider) - this.slider.addEventListener('change', e => { + this.slider.addEventListener('change', e => { - e.preventDefault() - e.stopPropagation() + e.preventDefault() + e.stopPropagation() - const referenceFrame = browser.referenceFrameList[0] - const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr) - const {end, start} = referenceFrame + const referenceFrame = browser.referenceFrameList[0] + const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr) + const {end, start} = referenceFrame - const extent = end - start + const extent = end - start - // bpLength/(end - start) - const scaleFactor = Math.pow(2, e.target.valueAsNumber) + // bpLength/(end - start) + const scaleFactor = Math.pow(2, e.target.valueAsNumber) - // (end - start) = bpLength/scaleFactor - const zoomedExtent = bpLength / scaleFactor + // (end - start) = bpLength/scaleFactor + const zoomedExtent = bpLength / scaleFactor - // console.log(`zoom-widget - slider ${ e.target.value } scaleFactor ${ scaleFactor } extent-zoomed ${ StringUtils.numberFormatter(Math.round(zoomedExtent)) }`) + // console.log(`zoom-widget - slider ${ e.target.value } scaleFactor ${ scaleFactor } extent-zoomed ${ StringUtils.numberFormatter(Math.round(zoomedExtent)) }`) - browser.zoomWithScaleFactor(zoomedExtent / extent) + browser.zoomWithScaleFactor(zoomedExtent / extent) - }) - - // zoom in - this.zoomInButton = DOMUtils.div() - this.zoomContainer.appendChild(this.zoomInButton) - this.zoomInButton.appendChild(createIcon('plus-circle')) - this.zoomInButton.addEventListener('click', () => { - // browser.zoomWithScaleFactor(0.5) - browser.zoomIn() - }) - - browser.on('locuschange', (referenceFrameList) => { - - if (this.browser.isMultiLocusMode()) { - this.disable() - } else { - this.enable() - this.update(referenceFrameList) + }) } - }) - -} - -ZoomWidget.prototype.update = function (referenceFrameList) { - - const referenceFrame = referenceFrameList[0] - const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr) - const {start, end} = referenceFrame - - sliderMax = Math.ceil(Math.log2(bpLength / this.browser.minimumBases())) - - this.slider.max = `${sliderMax}` + // zoom in + this.zoomInButton = DOMUtils.div() + this.zoomContainer.appendChild(this.zoomInButton) + this.zoomInButton.appendChild(createIcon('plus-circle')) + this.zoomInButton.addEventListener('click', () => { + // browser.zoomWithScaleFactor(0.5) + browser.zoomIn() + }) - const scaleFactor = bpLength / (end - start) - sliderValueRaw = Math.log2(scaleFactor) - this.slider.value = `${Math.round(sliderValueRaw)}` + browser.on('locuschange', (referenceFrameList) => { - const extent = end - start + if (this.browser.isMultiLocusMode()) { + this.disable() + } else { + this.enable() + this.update(referenceFrameList) + } - const derivedScalefactor = Math.pow(2, sliderValueRaw) + }) - const derivedExtent = bpLength / derivedScalefactor + } - // referenceFrame.description('zoom.update') + update(referenceFrameList) { - // console.log(`${ Date.now() } update - slider ${ this.slider.value } scaleFactor ${ Math.round(scaleFactor) } extent ${ StringUtils.numberFormatter(Math.round(extent)) }`) + if(this.slider) { + const referenceFrame = referenceFrameList[0] + const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr) + const {start, end} = referenceFrame - // console.log(`update - sliderMin ${ sliderMin } sliderValue ${ this.slider.value } sliderMax ${ sliderMax } scaleFactor ${ scaleFactor.toFixed(3) } derived-scaleFactor ${ derivedScalefactor.toFixed(3) }`) + sliderMax = Math.ceil(Math.log2(bpLength / this.browser.minimumBases())) + this.slider.max = `${sliderMax}` -} + const scaleFactor = bpLength / (end - start) + sliderValueRaw = Math.log2(scaleFactor) + this.slider.value = `${Math.round(sliderValueRaw)}` + } + } -ZoomWidget.prototype.enable = function () { - // this.zoomInButton.style.color = appleCrayonPalette[ 'steel' ]; - // this.zoomInButton.style.pointerEvents = 'auto'; - // - // this.zoomOutButton.style.color = appleCrayonPalette[ 'steel' ]; - // this.zoomOutButton.style.pointerEvents = 'auto'; + enable() { - this.slider.disabled = false -} + // this.zoomInButton.style.color = appleCrayonPalette[ 'steel' ]; + // this.zoomInButton.style.pointerEvents = 'auto'; + // + // this.zoomOutButton.style.color = appleCrayonPalette[ 'steel' ]; + // this.zoomOutButton.style.pointerEvents = 'auto'; -ZoomWidget.prototype.disable = function () { + if (this.slider) this.slider.disabled = false + } - // this.zoomInButton.style.color = appleCrayonPalette[ 'silver' ]; - // this.zoomInButton.style.pointerEvents = 'none'; - // - // this.zoomOutButton.style.color = appleCrayonPalette[ 'silver' ]; - // this.zoomOutButton.style.pointerEvents = 'none'; + disable() { - this.slider.disabled = true -} + // this.zoomInButton.style.color = appleCrayonPalette[ 'silver' ]; + // this.zoomInButton.style.pointerEvents = 'none'; + // + // this.zoomOutButton.style.color = appleCrayonPalette[ 'silver' ]; + // this.zoomOutButton.style.pointerEvents = 'none'; -ZoomWidget.prototype.hide = function () { - this.zoomContainer.style.display = 'none' -} + if (this.slider) this.slider.disabled = true + } -ZoomWidget.prototype.show = function () { - this.zoomContainer.style.display = 'block' -} + hide() { + this.zoomContainer.style.display = 'none' + } -ZoomWidget.prototype.hideSlider = function () { - this.slider.style.display = 'none' -} + show() { + this.zoomContainer.style.display = 'block' + } -ZoomWidget.prototype.showSlider = function () { - this.slider.style.display = 'block' -} + hideSlider() { + if (this.slider) this.slider.style.display = 'none' + } -function lerpAlvyRaySmith(a, b, t) { - return a - t * (a - b) + showSlider() { + if (this.slider) this.slider.style.display = 'block' + } } export default ZoomWidget