', {class: 'igv-navbar-right-container'})
+ $navBar.append($navbarRightContainer)
+ this.navbarRightContainer = $navbarRightContainer.get(0)
+
+ const $toggle_button_container = $('
')
+ $navbarRightContainer.append($toggle_button_container)
+ const toggleButtonContainer = $toggle_button_container.get(0)
+ this.toggle_button_container = toggleButtonContainer // TODO -- for circular view , refactor this
+
+ this.overlayTrackButton = new OverlayTrackButton(toggleButtonContainer, browser)
+ this.overlayTrackButton.setVisibility(false)
+
+ const showMultiSelect = config.showMultiSelectButton !== false
+ this.multiTrackSelectButton = new MultiTrackSelectButton(toggleButtonContainer, browser, this, showMultiSelect)
+
+ this.cursorGuideButton = new CursorGuideButton(toggleButtonContainer, browser)
+
+ this.centerLineButton = new CenterLineButton(toggleButtonContainer, browser)
+
+ this.trackLabelControl = new TrackLabelControl(toggleButtonContainer, browser)
+
+ // ROI Control
+ this.roiTableControl = new ROITableControl(toggleButtonContainer, browser)
+
+ this.sampleInfoControl = new SampleInfoControl(toggleButtonContainer, browser)
+
+ this.sampleNameControl = new SampleNameControl(toggleButtonContainer, browser)
+
+ if (true === config.showSVGButton) {
+ this.saveImageControl = new SaveImageControl(toggleButtonContainer, browser)
+ }
+
+ if (config.customButtons) {
+ for (let b of config.customButtons) {
+ new CustomButton(toggleButtonContainer, browser, b)
+ }
+ }
+
+ this.zoomWidget = new ZoomWidget(config, browser, $navbarRightContainer.get(0))
+
+ if (false === config.showNavigation) {
+ this.$navigation.hide()
+ }
-const responsiveThreshold = 8
-let textButtonContainerWidth = undefined
-function navbarDidResize(browser, width) {
- const currentClass = NavbarButton.currentNavbarButtonClass(browser)
- if ('igv-navbar-text-button' === currentClass) {
- textButtonContainerWidth = browser.$navigation.get(0).querySelector('.igv-navbar-right-container').getBoundingClientRect().width
}
- const responsiveClasses = getResponsiveClasses(browser, width)
+ navbarDidResize() {
- $(browser.zoomWidget.zoomContainer).removeClass()
- $(browser.zoomWidget.zoomContainer).addClass(responsiveClasses.zoomContainer)
- browser.fireEvent('navbar-resize', [ responsiveClasses.navbarButton ])
-}
+ const navbarWidth = this.$navigation.width()
+ const currentClass = this.currentNavbarButtonClass()
+ if ('igv-navbar-text-button' === currentClass) {
+ this.textButtonContainerWidth = this.navbarRightContainer.getBoundingClientRect().width
+ }
+ const browser = this.browser
+ const isWGV =
+ (browser.isMultiLocusWholeGenomeView()) ||
+ (browser.referenceFrameList && GenomeUtils.isWholeGenomeView(browser.referenceFrameList[0].chr))
+
+ isWGV ? this.windowSizePanel.hide() : this.windowSizePanel.show()
-function getResponsiveClasses(browser, navbarWidth) {
+ const {
+ x: leftContainerX,
+ width: leftContainerWidth
+ } = this.navbarLeftContainer.getBoundingClientRect()
+ const leftContainerExtent = leftContainerX + leftContainerWidth
+ const {x: rightContainerX} = this.navbarRightContainer.getBoundingClientRect()
- const isWGV =
- (browser.isMultiLocusWholeGenomeView()) ||
- (browser.referenceFrameList && GenomeUtils.isWholeGenomeView(browser.referenceFrameList[0].chr))
+ const delta = rightContainerX - leftContainerExtent
+
+ let navbarButtonClass
+ const threshold = 8
+ if ('igv-navbar-text-button' === currentClass && delta < threshold) {
+ navbarButtonClass = 'igv-navbar-icon-button'
+ } else if (this.textButtonContainerWidth && 'igv-navbar-icon-button' === currentClass) {
+ const length = navbarWidth - leftContainerExtent
+ if (length - this.textButtonContainerWidth > threshold) {
+ navbarButtonClass = 'igv-navbar-text-button'
+ }
+ }
+ // Update all the buttons (buttons are listeners)
+ if(navbarButtonClass && currentClass !== navbarButtonClass) {
+ this.currentClass = navbarButtonClass
+ this.browser.fireEvent('navbar-resize', [navbarButtonClass])
+ }
+
+ let zoomContainerClass
+ if (isWGV) {
+ zoomContainerClass = 'igv-zoom-widget-hidden'
+ } else {
+ zoomContainerClass = navbarWidth > 860 ? 'igv-zoom-widget' : 'igv-zoom-widget-900'
+ }
+ $(this.zoomWidget.zoomContainer).removeClass()
+ $(this.zoomWidget.zoomContainer).addClass(zoomContainerClass)
+ }
+
+
+ setCenterLineButtonVisibility(isWholeGenomeView) {
+ if (isWholeGenomeView) {
+ this.centerLineButton.setVisibility(!isWholeGenomeView)
+ } else {
+ this.centerLineButton.setVisibility(this.config.showCenterGuideButton)
+ }
+ }
- isWGV ? browser.windowSizePanel.hide() : browser.windowSizePanel.show()
+ setCursorGuideVisibility(doShowCursorGuide) {
+ if (doShowCursorGuide) {
+ this.cursorGuide.show()
+ } else {
+ this.cursorGuide.hide()
+ }
+ }
- const { x: leftContainerX, width: leftContainerWidth } = browser.$navigation.get(0).querySelector('.igv-navbar-left-container').getBoundingClientRect()
- const leftContainerExtent = leftContainerX + leftContainerWidth
- const { x:rightContainerX} = browser.$navigation.get(0).querySelector('.igv-navbar-right-container').getBoundingClientRect()
+ updateGenome(genome) {
- const delta = rightContainerX - leftContainerExtent
+ let genomeLabel = (genome.id && genome.id.length < 20 ? genome.id : `${genome.id.substring(0, 8)}...${genome.id.substring(genome.id.length - 8)}`)
+ this.$current_genome.text(genomeLabel)
+ this.$current_genome.attr('title', genome.description)
- const currentClass = NavbarButton.currentNavbarButtonClass(browser)
+ // chromosome select widget -- Show this IFF its not explicitly hidden AND the genome has pre-loaded chromosomes
+ const showChromosomeWidget =
+ this.config.showChromosomeWidget !== false &&
+ genome.showChromosomeWidget !== false &&
+ genome.chromosomeNames &&
+ genome.chromosomeNames.length > 1
- // console.log(`Current class ${ currentClass } Delta: ${ StringUtils.numberFormatter(Math.floor(delta))}`)
+ if (showChromosomeWidget) {
+ this.chromosomeSelectWidget.update(genome)
+ this.chromosomeSelectWidget.show()
+ } else {
+ this.chromosomeSelectWidget.hide()
+ }
+ }
- if ('igv-navbar-text-button' === currentClass && delta < responsiveThreshold) {
- navbarResponsiveClasses.navbarButton = 'igv-navbar-icon-button'
- } else if (textButtonContainerWidth && 'igv-navbar-icon-button' === currentClass) {
- const length = navbarWidth - leftContainerExtent
- if (length - textButtonContainerWidth > responsiveThreshold) {
- navbarResponsiveClasses.navbarButton = 'igv-navbar-text-button'
+ updateLocus(loc, chrName) {
+ if(this.$searchInput) {
+ this.$searchInput.val(loc)
}
+ if (this.chromosomeSelectWidget) {
+ this.chromosomeSelectWidget.select.value = chrName
+ }
+ }
+ currentNavbarButtonClass() {
+ return this.currentClass
+ //const el = this.$navigation.get(0).querySelector('.igv-navbar-text-button')
+ //return el ? 'igv-navbar-text-button' : 'igv-navbar-icon-button'
}
+ setEnableTrackSelection(b) {
+ this.multiTrackSelectButton.setMultiTrackSelection(b)
+ }
+ getEnableTrackSelection() {
+ return this.multiTrackSelectButton.enableMultiTrackSelection
+ }
- if (isWGV) {
- navbarResponsiveClasses.zoomContainer = 'igv-zoom-widget-hidden'
- } else {
- navbarResponsiveClasses.zoomContainer = navbarWidth > 860 ? 'igv-zoom-widget' : 'igv-zoom-widget-900'
+ hide() {
+ this.$navigation.hide()
+ }
+
+ show() {
+ this.$navigation.show()
}
- return navbarResponsiveClasses
}
-export { navbarDidResize, navbarResponsiveClasses }
+
+function logo() {
+
+ return $(
+ '
'
+ )
+}
+
+
+export default ResponsiveNavbar
diff --git a/js/roi/roiTableControl.js b/js/roi/roiTableControl.js
index 07170660c..877281e72 100644
--- a/js/roi/roiTableControl.js
+++ b/js/roi/roiTableControl.js
@@ -32,7 +32,7 @@ class ROITableControl extends NavbarButton {
constructor(parent, browser) {
- super(browser, parent, [ 'ROI', 'Regions of Interest Table' ], buttonLabel, roiImage, roiImageHover, false)
+ super(parent, browser, ['ROI', 'Regions of Interest Table'], buttonLabel, roiImage, roiImageHover, false)
this.button.addEventListener('mouseenter', () => {
if (false === browser.doShowROITable) {
diff --git a/js/sample/sampleInfoControl.js b/js/sample/sampleInfoControl.js
index 0163f4e71..d737e8c3a 100644
--- a/js/sample/sampleInfoControl.js
+++ b/js/sample/sampleInfoControl.js
@@ -32,7 +32,7 @@ class SampleInfoControl extends NavbarButton {
constructor(parent, browser) {
- super(browser, parent, 'Sample Info', buttonLabel, sampleInfoImage, sampleInfoImageHover, false)
+ super(parent, browser, 'Sample Info', buttonLabel, sampleInfoImage, sampleInfoImageHover, false)
this.showSampleInfo = false
diff --git a/js/sample/sampleNameControl.js b/js/sample/sampleNameControl.js
index 9e5a8fbdb..5b006b4db 100644
--- a/js/sample/sampleNameControl.js
+++ b/js/sample/sampleNameControl.js
@@ -32,7 +32,7 @@ class SampleNameControl extends NavbarButton {
constructor(parent, browser) {
- super(browser, parent, 'Sample Names', sampleNameButtonLabel, sampleNameImage, sampleNameImageHover, browser.config.showSampleNames)
+ super(parent, browser, 'Sample Names', sampleNameButtonLabel, sampleNameImage, sampleNameImageHover, browser.config.showSampleNames)
this.button.addEventListener('mouseenter', () => {
if (false === browser.showSampleNames) {
diff --git a/js/search.js b/js/search.js
index 4391768d6..9b844580f 100644
--- a/js/search.js
+++ b/js/search.js
@@ -13,6 +13,7 @@ async function searchFeatures(browser, name) {
const searchConfig = browser.searchConfig || DEFAULT_SEARCH_CONFIG
let feature
+ name = name.toUpperCase()
const searchableTracks = browser.tracks.filter(t => t.searchable)
for (let track of searchableTracks) {
const feature = await track.search(name)
diff --git a/js/trackView.js b/js/trackView.js
index 494c81c7c..3862ac55e 100644
--- a/js/trackView.js
+++ b/js/trackView.js
@@ -33,7 +33,7 @@ import {createIcon} from "./ui/utils/icons.js"
import SampleInfoViewport from "./sample/sampleInfoViewport.js"
import SampleNameViewport from './sample/sampleNameViewport.js'
import MenuPopup from "./ui/menuPopup.js"
-import { autoScaleGroupColorHash, multiTrackSelectExclusionTypes } from "./ui/menuUtils.js"
+import {autoScaleGroupColorHash, multiTrackSelectExclusionTypes} from "./ui/menuUtils.js"
import {colorPalettes, hexToRGB} from "./util/colorPalletes.js"
import {isOverlayTrackCriteriaMet} from "./ui/overlayTrackButton.js"
@@ -117,6 +117,8 @@ class TrackView {
createAxis(browser, track) {
const axis = DOMUtils.div()
+ this.axis = axis
+
browser.columnContainer.querySelector('.igv-axis-column').appendChild(axis)
axis.dataset.tracktype = track.type
@@ -134,12 +136,12 @@ class TrackView {
if (false === multiTrackSelectExclusionTypes.has(this.track.type)) {
- const trackSelectionContainer = DOMUtils.div()
- axis.appendChild(trackSelectionContainer)
+ this.trackSelectionContainer = DOMUtils.div()
+ axis.appendChild(this.trackSelectionContainer)
const html = `
`
const input = document.createRange().createContextualFragment(html).firstChild
- trackSelectionContainer.appendChild(input)
+ this.trackSelectionContainer.appendChild(input)
input.checked = this.track.selected || false
input.addEventListener('change', event => {
@@ -147,10 +149,10 @@ class TrackView {
event.stopPropagation()
this.track.selected = event.target.checked
this.setDragHandleSelectionState(event.target.checked)
- this.browser.overlayTrackButton.setVisibility( isOverlayTrackCriteriaMet(this.browser) )
+ this.browser.overlayTrackButton.setVisibility(isOverlayTrackCriteriaMet(this.browser))
})
- this.setTrackSelectionState(axis, false)
+ this.enableTrackSelection(false)
}
@@ -966,13 +968,19 @@ class TrackView {
return Math.max(...this.viewports.map(viewport => viewport.getContentHeight()))
}
- setTrackSelectionState(axis, doEnableMultiSelection) {
+ enableTrackSelection(doEnableMultiSelection) {
+
+ const container = this.trackSelectionContainer
- const container = axis.querySelector('div')
+ if (!container || multiTrackSelectExclusionTypes.has(this.track.type)) {
+ return
+ }
if (false !== doEnableMultiSelection) {
container.style.display = 'grid'
} else {
+ // If disabling selection set track selection state to false
+ this.track.selected = false
const trackSelectInput = container.querySelector('[name=track-select]')
trackSelectInput.checked = this.track.selected
@@ -998,13 +1006,11 @@ class TrackView {
dragHandle.classList.remove('igv-track-drag-handle-selected-color')
dragHandle.classList.add('igv-track-drag-handle-color')
}
-
}
}
-
function renderSVGAxis(context, track, axisCanvas, deltaX, deltaY) {
if (typeof track.paintAxis === 'function') {
diff --git a/js/ucsc/ucscHub.js b/js/ucsc/ucscHub.js
index c015f0fcd..c2f72a7ef 100644
--- a/js/ucsc/ucscHub.js
+++ b/js/ucsc/ucscHub.js
@@ -332,7 +332,7 @@ isPcr dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/186/305/GCF_000186305.1
config.searchIndex = t.getProperty("searchIndex")
}
if (t.hasProperty("searchTrix")) {
- config.searchTrix = this.baseURL + t.getProperty("searchTrix")
+ config.trixURL = this.baseURL + t.getProperty("searchTrix")
}
if (t.hasProperty("group")) {
diff --git a/js/ui/centerLineButton.js b/js/ui/centerLineButton.js
index 925c9bd90..c0bd0acd6 100644
--- a/js/ui/centerLineButton.js
+++ b/js/ui/centerLineButton.js
@@ -31,9 +31,9 @@ import { buttonLabel } from "./navbarIcons/buttonLabel.js"
class CenterLineButton extends NavbarButton {
- constructor(browser, parent) {
+ constructor(parent, browser) {
- super(browser, parent, 'Center Line', buttonLabel, centerlineImage, centerlineImageHover, browser.config.showCenterGuide)
+ super(parent, browser, 'Center Line', buttonLabel, centerlineImage, centerlineImageHover, browser.config.showCenterGuide)
this.button.addEventListener('mouseenter', () => {
if (false === browser.doShowCenterLine) {
diff --git a/js/ui/cursorGuideButton.js b/js/ui/cursorGuideButton.js
index 623a5a0c6..cd4824290 100644
--- a/js/ui/cursorGuideButton.js
+++ b/js/ui/cursorGuideButton.js
@@ -31,9 +31,9 @@ import { buttonLabel } from "./navbarIcons/buttonLabel.js"
class CursorGuideButton extends NavbarButton {
- constructor(browser, parent) {
+ constructor(parent, browser) {
- super(browser, parent, 'Crosshairs', buttonLabel, cursorImage, cursorImageHover, browser.doShowCursorGuide)
+ super(parent, browser, 'Crosshairs', buttonLabel, cursorImage, cursorImageHover, browser.doShowCursorGuide)
this.button.addEventListener('mouseenter', () => {
if (false === browser.doShowCursorGuide) {
diff --git a/js/ui/multiTrackSelectButton.js b/js/ui/multiTrackSelectButton.js
index 365dd5ed2..285136378 100644
--- a/js/ui/multiTrackSelectButton.js
+++ b/js/ui/multiTrackSelectButton.js
@@ -1,15 +1,16 @@
import NavbarButton from "./navbarButton.js"
-import {multiTrackSelectExclusionTypes} from './menuUtils.js'
import {multiSelectImage, multiSelectImageHover} from "./navbarIcons/multiSelect.js"
import {buttonLabel} from "./navbarIcons/buttonLabel.js"
-
+import {multiTrackSelectExclusionTypes} from './menuUtils.js'
class MultiTrackSelectButton extends NavbarButton {
- constructor(browser, parent, enableMultiTrackSelection) {
+ constructor(parent, browser, navbar, enableMultiTrackSelection, visibility = true) {
- super(browser, parent, 'Select Tracks', buttonLabel, multiSelectImage, multiSelectImageHover, enableMultiTrackSelection = false)
- this.enableMultiTrackSelection = enableMultiTrackSelection
+ super(parent, browser, 'Select Tracks', buttonLabel, multiSelectImage, multiSelectImageHover, false)
+
+ this.navbar = navbar
+ this.enableMultiTrackSelection = false // Initial state
this.button.addEventListener('mouseenter', event => {
if (false === enableMultiTrackSelection) {
this.setState(true)
@@ -23,6 +24,7 @@ class MultiTrackSelectButton extends NavbarButton {
})
const mouseClickHandler = () => {
+ // Toggle the selection state
this.setMultiTrackSelection(!this.enableMultiTrackSelection)
}
@@ -30,29 +32,26 @@ class MultiTrackSelectButton extends NavbarButton {
this.button.addEventListener('click', this.boundMouseClickHandler)
- this.setVisibility(true)
+ this.setVisibility(visibility)
}
setMultiTrackSelection(enableMultiTrackSelection) {
- this.enableMultiTrackSelection = enableMultiTrackSelection
- for (const trackView of this.browser.trackViews) {
- if (false === multiTrackSelectExclusionTypes.has(trackView.track.type)) {
- trackView.setTrackSelectionState(trackView.axis, this.enableMultiTrackSelection)
- // If closing the selection boxes set track selected property to false
- if (!this.enableMultiTrackSelection) {
- trackView.track.selected = false
- }
- }
- }
+ this.enableMultiTrackSelection = enableMultiTrackSelection
this.setState(this.enableMultiTrackSelection)
- // If enableMultiTrackSelection is false hide Overlay button
+ // If enableMultiTrackSelection is false hide the Overly button
if (false === this.enableMultiTrackSelection) {
- this.browser.overlayTrackButton.setVisibility(false)
+ this.navbar.overlayTrackButton.setVisibility(false)
}
+
+ for (const trackView of this.browser.trackViews) {
+ trackView.enableTrackSelection(enableMultiTrackSelection)
+ }
+
}
+
}
export default MultiTrackSelectButton
diff --git a/js/ui/navbarButton.js b/js/ui/navbarButton.js
index ce7d254cd..29218b883 100644
--- a/js/ui/navbarButton.js
+++ b/js/ui/navbarButton.js
@@ -28,7 +28,7 @@ import * as DOMUtils from "../ui/utils/dom-utils.js"
class NavbarButton {
- constructor(browser, parent, title, buttonLabel, imageSVG, imageHoverSVG, initialButtonState) {
+ constructor(parent, browser, title, buttonLabel, imageSVG, imageHoverSVG, initialButtonState) {
this.browser = browser
@@ -85,7 +85,7 @@ class NavbarButton {
}
configureTextButton(textContent) {
-
+ console.log(`text ${this.title}`)
this.button.classList.add('igv-navbar-text-button')
const tempDiv = document.createElement('div')
@@ -100,6 +100,7 @@ class NavbarButton {
}
configureIconButton() {
+ console.log(`icon ${this.title}`)
this.button.classList.add('igv-navbar-icon-button')
}
@@ -139,11 +140,6 @@ class NavbarButton {
this.hide()
}
}
-
- static currentNavbarButtonClass(browser) {
- const el = browser.$navigation.get(0).querySelector('.igv-navbar-text-button')
- return el ? 'igv-navbar-text-button' : 'igv-navbar-icon-button'
- }
}
export default NavbarButton
diff --git a/js/ui/overlayTrackButton.js b/js/ui/overlayTrackButton.js
index 46f1722b4..31a909ef3 100644
--- a/js/ui/overlayTrackButton.js
+++ b/js/ui/overlayTrackButton.js
@@ -1,13 +1,13 @@
import NavbarButton from "./navbarButton.js"
-import { overlayTrackImage, overlayTrackImageHover } from "./navbarIcons/overlayTrack.js"
-import { buttonLabel } from "./navbarIcons/buttonLabel.js"
+import {overlayTrackImage, overlayTrackImageHover} from "./navbarIcons/overlayTrack.js"
+import {buttonLabel} from "./navbarIcons/buttonLabel.js"
import MergedTrack from "../feature/mergedTrack.js"
class OverlayTrackButton extends NavbarButton {
- constructor(browser, parent) {
+ constructor(parent, browser) {
- super(browser, parent, 'Overlay Tracks', buttonLabel, overlayTrackImage, overlayTrackImageHover, false)
+ super(parent, browser, 'Overlay Tracks', buttonLabel, overlayTrackImage, overlayTrackImageHover, false)
this.button.addEventListener('mouseenter', () => this.setState(true))
this.button.addEventListener('mouseleave', () => this.setState(false))
@@ -30,15 +30,15 @@ function trackOverlayClickHandler(e) {
if (true === isOverlayTrackCriteriaMet(this.browser)) {
- const tracks = this.browser.getSelectedTrackViews().map(({ track }) => track)
+ const tracks = this.browser.getSelectedTrackViews().map(({track}) => track)
for (const track of tracks) {
track.selected = false
}
- // Flatten any merged tracks. Must do this before there removal
+ // Flatten any merged tracks. Must do this before their removal
const flattenedTracks = []
- for(let t of tracks) {
- if("merged" === t.type) {
+ for (let t of tracks) {
+ if ("merged" === t.type) {
flattenedTracks.push(...t.tracks)
} else {
flattenedTracks.push(t)
@@ -51,17 +51,20 @@ function trackOverlayClickHandler(e) {
type: 'merged',
autoscale: false,
alpha: 0.5, //fudge * (1.0/tracks.length),
- height: Math.max(...tracks.map(({ height }) => height)),
- order: Math.min(...tracks.map(({ order }) => order)),
+ height: Math.max(...tracks.map(({height}) => height)),
+ order: Math.min(...tracks.map(({order}) => order)),
}
const mergedTrack = new MergedTrack(config, this.browser, flattenedTracks)
for (const track of tracks) {
- this.browser.removeTrack(track)
+ const idx = this.browser.trackViews.indexOf(track.trackView)
+ this.browser.trackViews.splice(idx, 1)
+ track.trackView.dispose()
}
this.browser.addTrack(config, mergedTrack)
+ mergedTrack.trackView.updateViews()
}
@@ -73,9 +76,9 @@ function isOverlayTrackCriteriaMet(browser) {
if (selected && selected.length > 1) {
- const criteriaSet = new Set([ 'wig', 'merged' ])
+ const criteriaSet = new Set(['wig', 'merged'])
- const list = selected.filter(({ track }) => criteriaSet.has(track.type))
+ const list = selected.filter(({track}) => criteriaSet.has(track.type))
return list.length > 1
@@ -85,5 +88,5 @@ function isOverlayTrackCriteriaMet(browser) {
}
-export { isOverlayTrackCriteriaMet }
+export {isOverlayTrackCriteriaMet}
export default OverlayTrackButton
diff --git a/js/ui/saveImageControl.js b/js/ui/saveImageControl.js
index 785040a82..fd31ad5ee 100644
--- a/js/ui/saveImageControl.js
+++ b/js/ui/saveImageControl.js
@@ -33,7 +33,7 @@ import { buttonLabel } from "./navbarIcons/buttonLabel.js"
class SaveImageControl extends NavbarButton {
constructor(parent, browser) {
- super(browser, parent, 'Save Image', buttonLabel, imageSaveImageSVG, imageSaveImageHoverSVG, false)
+ super(parent, browser, 'Save Image', buttonLabel, imageSaveImageSVG, imageSaveImageHoverSVG, false)
this.button.addEventListener('mouseenter', () => this.setState(true))
diff --git a/js/ui/trackLabelControl.js b/js/ui/trackLabelControl.js
index adc43cfab..e98973fd7 100644
--- a/js/ui/trackLabelControl.js
+++ b/js/ui/trackLabelControl.js
@@ -32,7 +32,7 @@ class TrackLabelControl extends NavbarButton {
constructor(parent, browser) {
- super(browser, parent, 'Track Labels', buttonLabel, trackLabelsImage, trackLabelsImageHover, browser.config.showTrackLabels)
+ super(parent, browser, 'Track Labels', buttonLabel, trackLabelsImage, trackLabelsImageHover, browser.config.showTrackLabels)
this.button.addEventListener('mouseenter', () => {
if (false === browser.doShowTrackLabels) {
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