UNPKG

ideogram

Version:

Chromosome visualization for the web

406 lines (339 loc) 12.3 kB
/* eslint-disable no-new */ /* eslint-disable spaced-comment */ /* eslint-disable no-use-before-define */ /* eslint-disable no-unused-vars */ /* eslint-disable max-len */ describe('Ideogram filter support', function() { var config = {}; d3 = Ideogram.d3; beforeEach(function() { delete window.chrBands; d3.selectAll('div').remove(); config = { organism: 'human', chrWidth: 10, chrHeight: 150, chrMargin: 10, showChromosomeLabels: true, orientation: 'vertical', dataDir: '/dist/data/bands/native/' }; }); function takeScreenshot() { if (window.callPhantom) { var date = new Date(); var filename = 'screenshots/' + date.getTime(); console.log('Taking screenshot ' + filename); callPhantom({screenshot: filename}); } } afterEach(function() { if (this.currentTest.state === 'failed') { takeScreenshot(); } }); it('should have filterable annotations', done => { // Tests use case from ../examples/vanilla/annotations-histogram.html var priorBody = document.querySelector('body').innerHTML; var firstRun = true; var numAnnotsInFirstBar; // Ensure the first histogram bar represents // 110 annotations before filtering, and // 2 annotations after filtering function callback() { numAnnotsInFirstBar = ideogram.bars[0].annots[0].count; if (firstRun) { assert.equal(numAnnotsInFirstBar, 110); firstRun = false; document.querySelector('#filter_expression-level_extremely-high').click(); return; } assert.equal(numAnnotsInFirstBar, 2); document.querySelector('body').innerHTML = priorBody; done(); } var htmlScaffolding = '<div id="container"></div>' + '<ul id="expression-level">' + 'Expression level' + '<li>' + '<label for="filter_expression-level_extremely-high">' + '<input type="checkbox" id="filter_expression-level_extremely-high">Extremely high</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '<li>' + '<label for="filter_expression-level_very-high">' + '<input type="checkbox" id="filter_expression-level_very-high">Very high</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '<li>' + '<label for="filter_expression-level_high">' + '<input type="checkbox" id="filter_expression-level_high">High</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '<li>' + '<label for="filter_expression-level_moderately-high">' + '<input type="checkbox" id="filter_expression-level_moderately-high">Moderately high</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '<li>' + '<label for="filter_expression-level_moderate">' + '<input type="checkbox" id="filter_expression-level_moderate">Moderate</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '<li>' + '<label for="filter_expression-level_low">' + '<input type="checkbox" id="filter_expression-level_low">Low</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '<li>' + '<label for="filter_expression-level_very-low">' + '<input type="checkbox" id="filter_expression-level_very-low">Very low</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '</ul>' + '<ul id="gene-type">' + 'Gene type' + '<li>' + '<label for="filter_gene-type_mrna">' + '<input type="checkbox" id="filter_gene-type_mrna">mRNA</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '<li>' + '<label for="filter_gene-type_misc-rna">' + '<input type="checkbox" id="filter_gene-type_misc-rna">misc_RNA</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '<li>' + '<label for="filter_gene-type_mirna">' + '<input type="checkbox" id="filter_gene-type_mirna">miRNA</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '<li>' + '<label for="filter_gene-type_trna">' + '<input type="checkbox" id="filter_gene-type_trna">tRNA</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '<li>' + '<label for="filter_gene-type_lncrna">' + '<input type="checkbox" id="filter_gene-type_lncrna">lncRNA</input>' + '<span class="count"></span>' + '</label>' + '</li>' + '</ul>'; document.querySelector('body').innerHTML = htmlScaffolding; var filterMap = { 'expression-level': { 'extremely-high': 7, 'very-high': 6, 'high': 5, 'moderately-high': 4, 'moderate': 3, 'low': 2, 'very-low': 1 }, 'gene-type': { 'mrna': 1, 'misc-rna': 2, 'mirna': 3, 'trna': 4, 'lncrna': 5 }, 'tissue-type': { 'cerebral-cortex': 1, 'heart': 2, 'liver': 3, 'skin': 4, 'skeletal-muscle': 5 } }; d3.selectAll('input').on('click', function() { var tmp, checkedFilter, checkedFilters, i, facet, counts, count, filterID, key, selections = {}; checkedFilters = d3.selectAll('input:checked').nodes(); for (i = 0; i < checkedFilters.length; i++) { tmp = checkedFilters[i].id.split('_'); facet = tmp[1]; checkedFilter = tmp[2]; filterID = filterMap[facet][checkedFilter]; if (facet in selections === false) { selections[facet] = {}; } selections[facet][filterID] = 1; } counts = ideogram.filterAnnots(selections); for (facet in counts) { for (i = 0; i < counts[facet].length; i++) { count = counts[facet][i]; key = count.key - 1; value = '(' + count.value + ')'; // document.querySelectorAll('#' + facet + ' .count')[key].innerHTML = value; } } }); var config = { container: '#container', orientation: 'vertical', organism: 'human', assembly: 'GRCh37', chrHeight: 275, annotationsPath: '/dist/data/annotations/SRR562646.json', dataDir: '/dist/data/bands/native/', annotationsLayout: 'histogram', barWidth: 3, filterable: true, onDrawAnnots: callback }; ideogram = new Ideogram(config); }); it('should have filterable tracks in track filters example', done => { // Tests use case from ../examples/vanilla/annotations-track-filters.html var firstRun = true; function callback() { if (firstRun) { firstRun = false; } else { return; } var numAnnots = document.getElementsByClassName('annot').length; assert.equal(numAnnots, 707); // Filters tracks to show only 4th and 5th track (of 9) ideogram.updateDisplayedTracks([4, 5]); numAnnots = document.getElementsByClassName('annot').length; assert.equal(numAnnots, 635); done(); } var config = { organism: 'human', annotationsPath: '../dist/data/annotations/9_tracks_virtual_snvs.json', dataDir: '/dist/data/bands/native/', annotationsNumTracks: 3, annotationsDisplayedTracks: [1, 5, 9], onDrawAnnots: callback }; ideogram = new Ideogram(config); }); it('should filter heatmap tracks and show track labels', done => { // Tests use case from ../examples/vanilla/annotations-track-filters.html var firstRun = true; function callback() { var track1, track2, track3; if (firstRun) { firstRun = false; } else { return; } d3.select('#chr2-9606-canvas-0').dispatch('mouseover'); var trackLabel = d3.select('#_ideogramTrackLabel').html(); assert.equal(trackLabel, 'Sample A<br>Sample E<br>Sample I'); track1 = document.querySelector('#chr2-9606-canvas-0').getBoundingClientRect(); track2 = document.querySelector('#chr2-9606-canvas-1').getBoundingClientRect(); track3 = document.querySelector('#chr2-9606-canvas-2').getBoundingClientRect(); assert.equal(track1.x, 95); assert.equal(track2.x, 104); assert.equal(track3.x, 113); // Filters tracks to show only 4th and 5th track (of 9) ideogram.updateDisplayedTracks([4, 5]); track1 = document.querySelector('#chr2-9606-canvas-0').getBoundingClientRect(); track2 = document.querySelector('#chr2-9606-canvas-1').getBoundingClientRect(); assert.equal(track1.x, 104); assert.equal(track2.x, 113); done(); } var config = { organism: 'human', annotationsPath: '../dist/data/annotations/9_tracks_virtual_snvs.json', dataDir: '/dist/data/bands/native/', annotationsNumTracks: 3, annotationsDisplayedTracks: [1, 5, 9], onDrawAnnots: callback, annotationsLayout: 'heatmap' }; ideogram = new Ideogram(config); }); it('should have expected width with explicit `geometry: "parallel"`', done => { // Tests use case from ../examples/vanilla/annotations-track-filters.html // Similar to "should filter heatmap tracks and show track labels", except // one (now explicit) configuration option. function callback() { track1 = document.querySelector('#chr2-9606-canvas-0').getBoundingClientRect(); track2 = document.querySelector('#chr2-9606-canvas-1').getBoundingClientRect(); track3 = document.querySelector('#chr2-9606-canvas-2').getBoundingClientRect(); assert.equal(track1.x, 95); assert.equal(track2.x, 104); assert.equal(track3.x, 113); done(); } var config = { organism: 'human', annotationsPath: '../dist/data/annotations/9_tracks_virtual_snvs.json', dataDir: '/dist/data/bands/native/', annotationsNumTracks: 3, annotationsDisplayedTracks: [1, 5, 9], onDrawAnnots: callback, annotationsLayout: 'heatmap', geometry: 'parallel' }; ideogram = new Ideogram(config); }); it('should sort yeast annotations, and preserve clearing filters', done => { // Tests use case from ../examples/vanilla/annotations-basic.html let numTimesDrawn = 0; function getNumAnnots(annotsContainer) { return annotsContainer .map((annots) => annots.annots.length) .reduce((totalAnnots, numAnnots) => totalAnnots + numAnnots); } function callback() { numTimesDrawn += 1; var numAnnotsByChr = this.annots.length; // yeast_issue_239.json has known duplicate chromosomes. // This accounts for them. Yeast should have 17 chromosomes (I-XVI, MT) // but the annotations used in // https://github.com/eweitz/ideogram/issues/239 had a redundant // chromosome XIV in its raw annotations JSON. Because of the // duplicate chromosome, we expect 18 in this particular dataset. assert.equal(numAnnotsByChr, 18); const filteredAnnots = ideogram.filteredAnnots; const numFilteredAnnotsChrVI = filteredAnnots[5].annots.length; const numFilteredAnnots = getNumAnnots(filteredAnnots); if (numTimesDrawn === 1) { assert.equal(numFilteredAnnots, 21); assert.equal(numFilteredAnnotsChrVI, 3); var selections = {'expression-level': {4: 1}}; ideogram.filterAnnots(selections); } else if (numTimesDrawn === 2) { assert.equal(numFilteredAnnotsChrVI, 0); assert.equal(numFilteredAnnots, 0); var selections = {}; ideogram.filterAnnots(selections); } else if (numTimesDrawn === 3) { // Prevent regression in an issue 239 bug; this had shown MT annots assert.equal(numFilteredAnnotsChrVI, 3); assert.equal(numFilteredAnnots, 21); done(); } } var config = { organism: 'Saccharomyces cerevisiae', annotationsPath: '../dist/data/annotations/yeast_issue_239.json', annotationsLayout: 'histogram', annotationsNumTracks: 3, showNonNuclearChromosomes: true, onDrawAnnots: callback, filterable: true }; var ideogram = new Ideogram(config); }); });