Skip to content

Commit 06bb87f

Browse files
committed
Start something that would Fix #32
1 parent f0ebe23 commit 06bb87f

File tree

4 files changed

+89
-33
lines changed

4 files changed

+89
-33
lines changed

assets/js/gens.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { OverviewCanvas } from './overview.js'
55
import { VariantTrack, AnnotationTrack, TranscriptTrack, CytogeneticIdeogram } from './track.js'
66
export {
77
setupDrawEventManager, drawTrack, previousChromosome, nextChromosome,
8-
panTracks, zoomIn, zoomOut, parseRegionDesignation, queryRegionOrGene
8+
panTracks, zoomIn, zoomInY, zoomOut, zoomOutY, parseRegionDesignation, queryRegionOrGene
99
} from './navigation.js'
1010

11-
export function initCanvases({ sampleName, caseId, genomeBuild, hgFileDir, uiColors, scoutBaseURL, selectedVariant, annotationFile }) {
11+
export function initCanvases ({ sampleName, caseId, genomeBuild, hgFileDir, uiColors, scoutBaseURL, selectedVariant, annotationFile }) {
1212
// initialize and return the different canvases
1313
// WEBGL values
1414
const near = 0.1
@@ -44,7 +44,7 @@ export function initCanvases({ sampleName, caseId, genomeBuild, hgFileDir, uiCol
4444
}
4545

4646
// Make hard link and copy link to clipboard
47-
export function copyPermalink(genomeBuild, region) {
47+
export function copyPermalink (genomeBuild, region) {
4848
// create element and add url to it
4949
const tempElement = document.createElement('input')
5050
const loc = window.location
@@ -57,14 +57,14 @@ export function copyPermalink(genomeBuild, region) {
5757
}
5858

5959
// Reloads page to printable size
60-
export function loadPrintPage(region) {
60+
export function loadPrintPage (region) {
6161
let location = window.location.href.replace(/region=.*&/, `region=${region}&`)
6262
location = location.includes('?') ? `${location}&print_page=true` : `${location}?print_page=true`
6363
window.location.replace(location)
6464
}
6565

6666
// Show print prompt and reloads page after print
67-
export function printPage() {
67+
export function printPage () {
6868
document.querySelector('.no-print').toggleAttribute('hidden')
6969
window.addEventListener('afterprint', () => {
7070
window.location.replace(window.location.href.replace('&print_page=true', ''))

assets/js/interactive.js

+35-11
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ export class InteractiveCanvas extends BaseScatterTrack {
3838

3939
// Log2 ratio values
4040
this.log2 = {
41-
yStart: 4.0, // Start value for y axis
42-
yEnd: -4.0, // End value for y axis
43-
step: 1.0, // Step value for drawing ticks along y-axis
41+
yStart: 2.0, // Start value for y axis
42+
yEnd: -2.0, // End value for y axis
43+
step: 0.5, // Step value for drawing ticks along y-axis
4444
color: '#000000' // Viz color
4545
}
4646

@@ -180,24 +180,49 @@ export class InteractiveCanvas extends BaseScatterTrack {
180180
this.markingRegion = false
181181
this.drag = false
182182
})
183+
// when user asks for Y zoom
184+
this.staticCanvas.addEventListener('zoomY', event => {
185+
this.clearStaticContent()
186+
if (event.detail.direction === 'out') {
187+
this.log2.yStart += 1
188+
this.log2.yEnd -= 1
189+
if (this.log2.yStart > 2) {
190+
this.log2.step = 1
191+
}
192+
}
193+
if (event.detail.direction === 'in' && this.log2.yStart > 1) {
194+
this.log2.yStart -= 1
195+
this.log2.yEnd += 1
196+
if (this.log2.yStart <= 2) {
197+
this.log2.step = 0.5
198+
}
199+
}
200+
// then draw new with new coords
201+
this.drawStaticContent()
202+
drawTrack({ ...readInputField(), force: true, displayLoading: false, drawTitle: false })
203+
})
183204
}
184205

185-
// Draw static content for interactive canvas
186-
async drawStaticContent () {
206+
// clear static content
207+
async clearStaticContent () {
187208
const linePadding = 2
188209
const staticContext = this.staticCanvas.getContext('2d')
189-
190210
// Fill background colour
191211
staticContext.fillStyle = '#F7F9F9'
192212
staticContext.fillRect(0, 0, this.staticCanvas.width, this.staticCanvas.height)
193-
194213
// Make content area visible
195214
// content window
196215
staticContext.clearRect(this.x + linePadding, this.y + linePadding,
197216
this.plotWidth, this.staticCanvas.height)
198217
// area for ticks above content area
199218
staticContext.clearRect(0, 0, this.staticCanvas.width, this.y + linePadding)
219+
// Transfer image to visible canvas
220+
staticContext.drawImage(this.drawCanvas, 0, 0)
221+
}
200222

223+
// Draw static content for interactive canvas
224+
async drawStaticContent () {
225+
const staticContext = this.staticCanvas.getContext('2d')
201226
// Draw rotated y-axis legends
202227
drawRotatedText(staticContext, 'B Allele Freq', 18, this.x - this.legendMargin,
203228
this.y + this.plotHeight / 2, -Math.PI / 2, this.titleColor)
@@ -313,12 +338,11 @@ export class InteractiveCanvas extends BaseScatterTrack {
313338
// Draw chromosome title on the content canvas as a blitting
314339
// work around
315340
this.titleYPos = result.y_pos - this.titleMargin
316-
if ( drawTitle ) {
341+
if (drawTitle) {
317342
this.titleBbox !== null && this.blitChromName(
318-
{textPosition: this.titleBbox, clearOnly: true
319-
})
343+
{ textPosition: this.titleBbox, clearOnly: true })
320344
this.titleBbox = this.drawTitle(`Chromosome ${result.chrom}`)
321-
this.blitChromName({textPosition: this.titleBbox})
345+
this.blitChromName({ textPosition: this.titleBbox })
322346
}
323347

324348
return result

assets/js/navigation.js

+42-16
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import { get } from './fetch.js'
22
import { CHROMOSOMES } from './track.js'
33
import { chromSizes } from './helper.js'
44

5-
function redrawEvent({ region, exclude = [], ...kwargs }) {
5+
function redrawEvent ({ region, exclude = [], ...kwargs }) {
66
return new CustomEvent(
77
'draw', { detail: { region: region, exclude: exclude, ...kwargs } }
88
)
99
}
1010

11-
function drawEventManager({ target, throttleTime }) {
11+
function drawEventManager ({ target, throttleTime }) {
1212
const tracks = [
1313
...target.querySelectorAll('.track-container'),
1414
target.querySelector('#cytogenetic-ideogram')
@@ -30,7 +30,7 @@ function drawEventManager({ target, throttleTime }) {
3030
}
3131
}
3232

33-
export function setupDrawEventManager({ target, throttleTime = 20 }) {
33+
export function setupDrawEventManager ({ target, throttleTime = 20 }) {
3434
const manager = drawEventManager({ target, throttleTime })
3535
target.addEventListener('draw', (event) => {
3636
manager(event)
@@ -42,7 +42,7 @@ export function readInputField() {
4242
return parseRegionDesignation(field.value)
4343
}
4444

45-
function updateInputField({ chrom, start, end }) {
45+
function updateInputField ({ chrom, start, end }) {
4646
const field = document.getElementById('region-field')
4747
field.value = `${chrom}:${start}-${end}`
4848
field.placeholder = field.value
@@ -54,7 +54,7 @@ function updateInputField({ chrom, start, end }) {
5454
// eg 1:12-220 --> 1, 12 220
5555
// 1: --> 1, null, null
5656
// 1 --> 1, null, null
57-
export function parseRegionDesignation(regionString) {
57+
export function parseRegionDesignation (regionString) {
5858
if (regionString.includes(':')) {
5959
const [chromosome, position] = regionString.split(':')
6060
// verify chromosome
@@ -68,7 +68,7 @@ export function parseRegionDesignation(regionString) {
6868
}
6969
}
7070

71-
export async function limitRegionToChromosome({ chrom, start, end, genomeBuild = '38' }) {
71+
export async function limitRegionToChromosome ({ chrom, start, end, genomeBuild = '38' }) {
7272
// assert that start/stop are within start and end of chromosome
7373
const sizes = await chromSizes(genomeBuild)
7474
const chromSize = sizes[chrom]
@@ -93,7 +93,7 @@ export async function limitRegionToChromosome({ chrom, start, end, genomeBuild =
9393
return { chrom: chrom, start: Math.round(updStart), end: Math.round(updEnd) }
9494
}
9595

96-
export async function drawTrack({
96+
export async function drawTrack ({
9797
chrom, start, end, genomeBuild = '38',
9898
exclude = [], force = false, ...kwargs
9999
}) {
@@ -113,7 +113,7 @@ export async function drawTrack({
113113
// If query is a regionString draw the relevant region
114114
// If input is a chromosome display entire chromosome
115115
// Else query api for genes with that name and draw that region
116-
export function queryRegionOrGene(query, genomeBuild = 38) {
116+
export function queryRegionOrGene (query, genomeBuild = 38) {
117117
if (query.includes(':')) {
118118
drawTrack(parseRegionDesignation(query))
119119
} else if (CHROMOSOMES.includes(query)) {
@@ -133,21 +133,21 @@ export function queryRegionOrGene(query, genomeBuild = 38) {
133133
}
134134

135135
// goto the next chromosome
136-
export function nextChromosome() {
136+
export function nextChromosome () {
137137
const position = readInputField()
138138
const chrom = CHROMOSOMES[CHROMOSOMES.indexOf(position.chrom) + 1]
139139
drawTrack({ chrom: chrom, start: 1, end: null })
140140
}
141141

142142
// goto the previous chromosome
143-
export function previousChromosome() {
143+
export function previousChromosome () {
144144
const position = readInputField()
145145
const chrom = CHROMOSOMES[CHROMOSOMES.indexOf(position.chrom) - 1]
146146
drawTrack({ chrom: chrom, start: 1, end: null })
147147
}
148148

149149
// Pan whole canvas and tracks to the left
150-
export function panTracks(direction = 'left', speed = 0.1) {
150+
export function panTracks (direction = 'left', speed = 0.1) {
151151
const pos = readInputField()
152152
const distance = Math.abs(Math.floor(speed * (pos.end - pos.start)))
153153
if (direction === 'left') {
@@ -166,7 +166,7 @@ export function panTracks(direction = 'left', speed = 0.1) {
166166
}
167167

168168
// Handle zoom in button click
169-
export function zoomIn() {
169+
export function zoomIn () {
170170
const pos = readInputField()
171171
const factor = Math.floor((pos.end - pos.start) * 0.2)
172172
pos.start += factor
@@ -175,19 +175,37 @@ export function zoomIn() {
175175
}
176176

177177
// Handle zoom out button click
178-
export function zoomOut() {
178+
export function zoomOut () {
179179
const pos = readInputField()
180180
const factor = Math.floor((pos.end - pos.start) / 3)
181181
pos.start = (pos.start - factor) < 1 ? 1 : pos.start - factor
182182
pos.end += factor
183183
drawTrack({ chrom: pos.chrom, start: pos.start, end: pos.end, exclude: ['cytogenetic-ideogram'], drawTitle: false })
184184
}
185185

186+
// Handle zoom in Y button click
187+
export function zoomInY () {
188+
console.log('dispatching zoom in Y')
189+
const zoomYEvent = new CustomEvent(
190+
'zoomY', { detail: { direction: 'in' } }
191+
)
192+
document.getElementById('interactive-static').dispatchEvent(zoomYEvent)
193+
}
194+
195+
// Handle zoom out Y button click
196+
export function zoomOutY () {
197+
console.log('dispatching zoom out Y')
198+
const zoomYEvent = new CustomEvent(
199+
'zoomY', { detail: { direction: 'out' } }
200+
)
201+
document.getElementById('interactive-static').dispatchEvent(zoomYEvent)
202+
}
203+
186204
// Dispatch dispatch an event to draw a given region
187205
// Redraw events can be limited to certain tracks or include all tracks
188206
class KeyLogger {
189207
// Records keypress combinations
190-
constructor(bufferSize = 10) {
208+
constructor (bufferSize = 10) {
191209
// Setup variables
192210
this.bufferSize = bufferSize
193211
this.lastKeyTime = Date.now()
@@ -213,14 +231,14 @@ class KeyLogger {
213231
})
214232
}
215233

216-
recentKeys(timeWindow) {
234+
recentKeys (timeWindow) {
217235
// get keys pressed within a window of time.
218236
const currentTime = Date.now()
219237
return this.keyBuffer.filter(keyEvent =>
220238
timeWindow > currentTime - keyEvent.time)
221239
}
222240

223-
lastKeypressTime() {
241+
lastKeypressTime () {
224242
return this.keyBuffer[this.keyBuffer.length - 1] - Date.now()
225243
}
226244
}
@@ -272,11 +290,19 @@ document.addEventListener('keyevent', event => {
272290
case '+':
273291
zoomIn()
274292
break
293+
case '?':
294+
case 'W':
295+
zoomInY()
296+
break
275297
case 'ArrowDown':
276298
case 's':
277299
case '-':
278300
zoomOut()
279301
break
302+
case 'S':
303+
case '_':
304+
zoomOutY()
305+
break
280306
default:
281307
}
282308
}

gens/blueprints/gens/templates/gens.html

+7-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@
8282
<button onclick='gens.zoomIn();' class='button--zoom-in no-print'>
8383
<span class='icon search-plus' title='Zoom in'></span>
8484
</button>
85+
<button onclick='gens.zoomInY();' class='button--zoom-in-y no-print'>
86+
<span class='icon search-plus' title='Zoom in Y'><br>Y</span>
87+
</button>
88+
<button onclick='gens.zoomOutY();' class='button--zoom-out-y no-print'>
89+
<span class='icon search-minus' title='Zoom out Y'><br>Y</span>
90+
</button>
8591
<button onclick='gens.zoomOut();' class='button--zoom-out no-print'>
8692
<span class='icon search-minus' title='Zoom out'></span>
8793
</button>
@@ -176,7 +182,7 @@
176182
targetElementIds: ['interactive-content'],
177183
})
178184

179-
Promise.all([ic.drawStaticContent(), oc.drawOverviewContent()]).then( () => {
185+
Promise.all([ic.clearStaticContent(), ic.drawStaticContent(), oc.drawOverviewContent()]).then( () => {
180186
// setup event managers and draw the tracks
181187
gens.drawTrack({chrom: '{{ chrom }}', start: start, end: {{ end }} })
182188
document.dispatchEvent(new CustomEvent('data-loaded'))

0 commit comments

Comments
 (0)