Skip to content

Commit 94c6e72

Browse files
committed
Region of Interest changes
* Bug fix -- new ROIs ignored hide/show state * Add alpha to color specification if missing * Decrease default alpha to 1/16 from 2/16
1 parent 15db658 commit 94c6e72

File tree

5 files changed

+66
-51
lines changed

5 files changed

+66
-51
lines changed

dev/roi/roi.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
<body>
1515

16-
16+
<button id="log-state">Log Session</button>
1717
<button id="bookmark">Bookmark</button>
1818

1919

@@ -46,7 +46,7 @@
4646
},
4747
{
4848
name: "ROI set 2",
49-
color: "rgba(3,52,249,0.25)",
49+
color: "darkviolet",
5050
features: [
5151
{
5252
chr: "chr1",
@@ -117,6 +117,9 @@
117117
document.getElementById("bookmark").addEventListener("click",
118118
() => window.history.pushState({}, "IGV", browser.sessionURL()))
119119

120+
document.getElementById("log-state").addEventListener("click", () => console.log(browser.toJSON()))
121+
122+
120123

121124
</script>
122125

js/browser.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,10 @@ class Browser {
527527
this.qtlSelections = QTLSelections.fromJSON(session.qtlSelections)
528528
}
529529

530+
// ROIs
531+
if(session.showROIOverlays !== undefined) {
532+
this.roiManager.showOverlays = session.showROIOverlays
533+
}
530534
this.roiManager.clearROIs()
531535
if (session.roi) {
532536
this.roiManager.loadROI(session.roi)
@@ -1857,7 +1861,13 @@ class Browser {
18571861
}
18581862
json["locus"] = locus.length === 1 ? locus[0] : locus
18591863

1860-
json["roi"] = this.roiManager.toJSON()
1864+
const roiSets = this.roiManager.toJSON()
1865+
if(roiSets) {
1866+
json["roi"] = roiSets
1867+
if(!this.roiManager.showOverlays){
1868+
json["showROIOverlays"] = false // true is the default
1869+
}
1870+
}
18611871

18621872
if (!this.qtlSelections.isEmpty()) {
18631873
json["qtlSelections"] = this.qtlSelections.toJSON()

js/roi/ROIManager.js

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class ROIManager {
1515
this.roiTable = new ROITable(browser, browser.columnContainer)
1616
this.top = 0
1717
this.roiSets = []
18+
this.showOverlays = true
1819
this.boundLocusChangeHandler = locusChangeHandler.bind(this)
1920
browser.on('locuschange', this.boundLocusChangeHandler)
2021

@@ -66,16 +67,35 @@ class ROIManager {
6667
this.roiTable.renderTable(records)
6768

6869
if (this.roiSets.length > 0) {
69-
const isVisible = this.roiSets[0].isVisible
70-
this.roiTable.setROIVisibility(isVisible)
70+
this.setOverlayVisibility(this.showOverlays)
7171
}
72+
}
73+
74+
setOverlayVisibility(isVisible) {
7275

76+
const elements = this.browser.columnContainer.querySelectorAll('.igv-roi-region')
77+
for (let i = 0; i < elements.length; i++) {
78+
const el = elements[i]
79+
if (isVisible) {
80+
// Restore element background color to its original value
81+
el.style.backgroundColor = el.dataset.color
82+
} else {
83+
// Hide overlay by setting its transparency to zero. A bit of an unusual method to hide an element.
84+
el.style.backgroundColor = `rgba(0,0,0,0)`
85+
}
86+
}
87+
this.roiTable.toggleROIButton.textContent = false === isVisible ? 'Show Overlays' : 'Hide Overlays'
7388
}
7489

7590
async loadROI(config, genome) {
7691

7792
const configs = Array.isArray(config) ? config : [config]
7893

94+
// Backward compatibility hack
95+
if (configs.length > 0 && configs[0].isVisible === false) {
96+
this.showOverlays = false
97+
}
98+
7999
for (let config of configs) {
80100
if (!config.name && config.url) {
81101
config.name = await getFilename(config.url)
@@ -164,13 +184,8 @@ class ROIManager {
164184
}
165185

166186
toggleROIs() {
167-
168-
const isVisible = !(this.roiSets[0].isVisible)
169-
this.roiTable.setROIVisibility(isVisible)
170-
171-
for (const roiSet of this.roiSets) {
172-
roiSet.isVisible = isVisible
173-
}
187+
this.showOverlays = !this.showOverlays
188+
this.setOverlayVisibility(this.showOverlays)
174189
}
175190

176191
async renderAllROISets() {
@@ -232,10 +247,17 @@ class ROIManager {
232247
regionElement.style.top = `${pixelTop}px`
233248
regionElement.style.left = `${pixelX}px`
234249
regionElement.style.width = `${pixelWidth}px`
235-
regionElement.style.backgroundColor = roiSet.color
236250
regionElement.dataset.color = roiSet.color
237251
regionElement.dataset.region = regionKey
238252

253+
if (this.showOverlays) {
254+
// Restore element background color to its original value
255+
regionElement.style.backgroundColor = roiSet.color
256+
} else {
257+
// Hide overlay by setting its transparency to zero. A bit of an unusual method to hide an element.
258+
regionElement.style.backgroundColor = `rgba(0,0,0,0)`
259+
}
260+
239261
const header = DOMUtils.div()
240262
regionElement.appendChild(header)
241263

@@ -274,8 +296,8 @@ class ROIManager {
274296
return this.roiSets.find(roiSet => true === roiSet.isUserDefined)
275297
}
276298

277-
deleteUserDefinedROISet(){
278-
this.roiSets = this.roiSets.filter(roiSet => roiSet.isUserDefined !== true);
299+
deleteUserDefinedROISet() {
300+
this.roiSets = this.roiSets.filter(roiSet => roiSet.isUserDefined !== true)
279301
}
280302

281303
initializeUserDefinedROISet() {

js/roi/ROISet.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import FeatureSource from '../feature/featureSource.js'
2-
import {appleCrayonRGBA} from '../util/colorPalletes.js'
2+
import {appleCrayonRGBA, rgbaStringTokens} from '../util/colorPalletes.js'
33
import {computeWGFeatures} from "../feature/featureUtils.js"
4+
import * as DOMUtils from "../ui/utils/dom-utils.js"
5+
import {IGVColor} from "../../node_modules/igv-utils/src/index.js"
46

57
const appleCrayonColorName = 'nickel'
68

7-
const ROI_DEFAULT_ALPHA = 2 / 16
9+
const ROI_DEFAULT_ALPHA = 1 / 16
810

911
const ROI_DEFAULT_COLOR = appleCrayonRGBA(appleCrayonColorName, ROI_DEFAULT_ALPHA)
1012
const ROI_DEFAULT_HEADER_COLOR = 'rgb(190,190,190)'
@@ -35,23 +37,24 @@ class ROISet {
3537
throw Error('ROI configuration must define either features or file format')
3638
}
3739

40+
if(config.color && !config.color.startsWith("rgba")) {
41+
config.color = IGVColor.addAlpha(config.color, ROI_DEFAULT_ALPHA)
42+
}
3843

3944
if (true === this.isUserDefined) {
4045
this.color = config.color || ROI_USER_DEFINED_COLOR
4146
this.headerColor = ROI_USER_HEADER_DEFINED_COLOR
4247

4348
} else {
44-
4549
this.color = config.color || ROI_DEFAULT_COLOR
4650
this.headerColor = ROI_DEFAULT_HEADER_COLOR
4751

4852
// Use body color with alpha pinned to 1
49-
// const [ r, g, b, discard ] = rgbaStringTokens(this.color)
50-
// this.headerColor = `rgba(${ r },${ g },${ b },${ 1.0 })`
51-
53+
const [ r, g, b, discard ] = rgbaStringTokens(this.color)
54+
this.headerColor = `rgba(${ r },${ g },${ b },${ 1.0 })`
5255
}
5356

54-
this.isVisible = undefined === config.isVisible ? true : config.isVisible
57+
delete config.isVisible // Deprecated
5558

5659
}
5760

js/roi/ROITable.js

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -129,34 +129,25 @@ class ROITable extends RegionTableBase {
129129
this._footerDOM.appendChild(toggleROIButton)
130130

131131
toggleROIButton.id = 'igv-roi-hide-show-button'
132-
toggleROIButton.textContent = 'Hide all ROIs'
132+
toggleROIButton.textContent = 'Hide Overlays'
133133
this.toggleROIButton = toggleROIButton
134134

135135
function toggleROIButtonHandler(event) {
136136
event.preventDefault()
137137
event.stopPropagation()
138-
this.browser.roiManager.toggleROIs()
138+
this.roiManager.toggleROIs()
139139
}
140140

141141
this.boundToggleDisplayButtonHandler = toggleROIButtonHandler.bind(this)
142142
this.toggleROIButton.addEventListener('click', this.boundToggleDisplayButtonHandler)
143-
144143
}
145144

146-
setROIVisibility(isVisible) {
147-
148-
const elements = this.browser.columnContainer.querySelectorAll('.igv-roi-region')
149-
150-
for (let i = 0; i < elements.length; i++) {
151-
const el = elements[ i ]
152-
false === isVisible ? updateElementAlpha(el, 0.0) : el.style.backgroundColor = el.dataset.color
153-
154-
}
155-
156-
this.toggleROIButton.textContent = false === isVisible ? 'Show all ROIs' : 'Hide all ROIs'
157-
145+
// This is a rather roundabot way to get the manager
146+
get roiManager() {
147+
return this.browser.roiManager
158148
}
159149

150+
160151
setTableRowSelectionState(isTableRowSelected) {
161152
super.setTableRowSelectionState(isTableRowSelected)
162153
const selected = this.tableDOM.querySelectorAll('.igv-roi-table-row-selected')
@@ -236,19 +227,5 @@ function enableButton(button, doEnable) {
236227

237228
}
238229

239-
function updateElementAlpha(element, alpha) {
240-
241-
const rgba = window.getComputedStyle(element).backgroundColor;
242-
243-
const rgbaArray = rgba.match(/[\d.]+/g);
244-
245-
if (rgbaArray.length === 3) {
246-
rgbaArray.push(1)
247-
}
248-
249-
rgbaArray[3] = alpha;
250-
251-
element.style.backgroundColor = `rgba(${rgbaArray.join(', ')})`
252-
}
253230

254231
export default ROITable

0 commit comments

Comments
 (0)