Skip to content

Commit

Permalink
Merge pull request #213 from eweitz/telocentric-q-arms
Browse files Browse the repository at this point in the history
Render telocentric q-arms
  • Loading branch information
eweitz authored Jun 29, 2020
2 parents 5086eed + 3da0e2e commit dcfb9c5
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 18 deletions.
2 changes: 1 addition & 1 deletion examples/vanilla/eukaryotes.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ <h1>Eukaryotes | Ideogram</h1>
<a href="orthologs">Next</a> |
<a href="https://github.com/eweitz/ideogram/blob/gh-pages/eukaryotes.html" target="_blank">Source</a>
<p>
Ideogram.js can display the genome of any hundreds of organisms, using data from
Ideogram.js can display the genome of any one of hundreds of organisms, using data from
<a href="https://www.ncbi.nlm.nih.gov/assembly">NCBI Assembly</a>.
</p>
<div>
Expand Down
8 changes: 5 additions & 3 deletions examples/vanilla/orthologs.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
}

#search-button {
height: 21px;
height: 23px;
width: 23px;
font-size: 24px;
background: #58F;
Expand All @@ -36,7 +36,7 @@
left: 325px;
border-radius: 3px;
text-align: center;
padding-top: 3px;
padding-top: 1px;
cursor: pointer;
}

Expand Down Expand Up @@ -75,7 +75,9 @@ <h1>Orthologs | Ideogram</h1>
<div style="float: left; width: 350px;">
<label for="search" id="search-container">Search:
<input id="search" autocomplete="off" placeholder="Gene or location"/>
<span id="search-button">&#x2315;</span>
<span id="search-button">
<svg width="12" height="13"><g stroke-width="2" stroke="#FFF" fill="none"><path d="M11.29 11.71l-4-4"/><circle cx="5" cy="5" r="4"/></g></svg>
</span>
</label>
<div style="font-size: 12px; position: relative; top: -7px;">
Examples:
Expand Down
10 changes: 6 additions & 4 deletions examples/vanilla/related-genes.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@
}

#search-button {
height: 21px;
height: 23px;
width: 23px;
font-size: 24px;
background: #58F;
color: #FFF;
display: inline-block;
position: relative;
top: 3px;
top: 2px;
left: -25px;
border-radius: 3px;
text-align: center;
padding-top: 3px;
padding-top: 1px;
cursor: pointer;
}

Expand Down Expand Up @@ -111,7 +111,9 @@ <h1>Related genes | Ideogram</h1>
<div style="float: left; width: 350px;">
<label for="search-genes" id="search-container">
<input id="search-genes" autocomplete="off" placeholder="Search gene (e.g. RAD51)"/>
<span id="search-button">&#x2315;</span>
<span id="search-button">
<svg width="12" height="13"><g stroke-width="2" stroke="#FFF" fill="none"><path d="M11.29 11.71l-4-4"/><circle cx="5" cy="5" r="4"/></g></svg>
</span>
</label>
</div>
<br/><br/><br/>
Expand Down
24 changes: 21 additions & 3 deletions src/js/views/chromosome-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,30 @@ function deleteExtraneousBands(chr, hasBands) {
}

function getCentromerePosition(hasBands, bands) {
if (

const hasTelocentricPArm = (
// As with almost all mouse chromosome, chimpanzee chr22
hasBands && bands[0].name[0] === 'p' && bands[1].name[0] === 'q' &&
bands[0].bp.stop - bands[0].bp.start < 2E6
) {
);

let hasTelocentricQArm = false;
if (hasBands) {
// As with Macaca mulatta chromosome Y
const lastBand = bands.slice(-1)[0];
const penultimateBand = bands.slice(-2)[0];

hasTelocentricQArm = (
hasBands && penultimateBand.name[0] === 'p' && lastBand.name[0] === 'q' &&
lastBand.bp.stop - lastBand.bp.start < 2E6
);
}

if (hasTelocentricPArm) {
// As with almost all mouse chromosome, chimpanzee chr22
return 'telocentric';
return 'telocentric-p';
} else if (hasTelocentricQArm) {
return 'telocentric-q';
} else {
return '';
}
Expand Down
88 changes: 84 additions & 4 deletions src/js/views/chromosome.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ export class Chromosome {
* Factory method
*/
static getInstance(adapter, config, ideo) {
if (adapter.getModel().centromerePosition === 'telocentric') {
return new TelocentricChromosome(adapter, config, ideo);
const centromerePosition = adapter.getModel().centromerePosition;
if (centromerePosition === 'telocentric-p') {
return new TelocentricPChromosome(adapter, config, ideo);
} else if (centromerePosition === 'telocentric-q') {
return new TelocentricQChromosome(adapter, config, ideo);
} else {
return new MetacentricChromosome(adapter, config, ideo);
}
Expand Down Expand Up @@ -327,11 +330,12 @@ export class MetacentricChromosome extends Chromosome {
}
}

export class TelocentricChromosome extends Chromosome {
export class TelocentricPChromosome extends Chromosome {

constructor(model, config, ideo) {
// alert('p')
super(model, config, ideo);
this._class = 'TelocentricChromosome';
this._class = 'TelocentricPChromosome';
this._pArmOffset = 3;
}

Expand All @@ -340,6 +344,12 @@ export class TelocentricChromosome extends Chromosome {
}

_getPArmShape() {
// Properties description:
// x1 - left terminal start position
// x2 - centromere position
// x3 - right terminal end position
// w - chromosome width
// b - bump size
var d = this._getShapeData();
d.o = this._pArmOffset;

Expand All @@ -360,6 +370,12 @@ export class TelocentricChromosome extends Chromosome {
}

_getQArmShape() {
// Properties description:
// x1 - left terminal start position
// x2 - centromere position
// x3 - right terminal end position
// w - chromosome width
// b - bump size
var d = this._getShapeData(),
x = d.x3 - d.b,
o = this._pArmOffset + 3;
Expand All @@ -374,3 +390,67 @@ export class TelocentricChromosome extends Chromosome {
};
}
}

export class TelocentricQChromosome extends Chromosome {

constructor(model, config, ideo) {
// alert('q')
super(model, config, ideo);
this._class = 'TelocentricQChromosome';
this._qArmOffset = 3;
}

_getPArmShape() {
// Properties description:
// x1 - left terminal start position
// x2 - centromere position
// x3 - right terminal end position
// w - chromosome width
// b - bump size

var d = this._getShapeData(),
x = d.x3 - d.b,
o = this._qArmOffset;

return {
class: '',
path:
// 'M1,0, ' +
'M' + (d.x2 + o) + ',0 ' +
'L' + (x + o) + ',0 ' +
'L' + (x + o) + ',' + d.w + ' ' +
'L' + d.b + ',' + d.w + ' ' +
'Q-' + d.b + ',' + (d.w / 2) + ',' + d.b + ',0'
};
}

_addQArmShape(clipPath) {
return clipPath.concat(this._getQArmShape());
}

_getQArmShape() {
// Properties description:
// x1 - left terminal start position
// x2 - centromere position
// x3 - right terminal end position
// w - chromosome width
// b - bump size
var d = this._getShapeData();
d.o = this._qArmOffset;

return [{
class: 'acen',
path: 'M' + (d.x2 + 2) + ',1 ' +
'L' + (d.x2 + d.o + 3.25) + ',1 ' +
'L' + (d.x2 + d.o + 3.25) + ',' + (d.w - 1) + ' ' +
'L' + (d.x2 + 2) + ',' + (d.w - 1)
}, {
class: 'gpos66',
path: 'M' + (d.x2 + d.o + 5) + ',0 ' +
'L' + (d.x2 + d.o + 3) + ',0 ' +
'L' + (d.x2 + d.o + 3) + ',' + d.w + ' ' +
'L' + (d.x2 + d.o + 5) + ',' + d.w,
strokeWidth: 0.5
}];
}
}
4 changes: 2 additions & 2 deletions src/js/views/draw-chromosomes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {d3} from '../lib';
import {initSettings} from '../init/settings-ui';
// import {initSettings} from '../init/settings-ui';
import {ModelAdapter} from '../model-adapter';
import {Chromosome} from './chromosome';

Expand Down Expand Up @@ -163,7 +163,7 @@ function setOverflowScroll() {

ideoSvg.style('min-width', (ideoWidth - 5) + 'px');

initSettings(ideo);
// initSettings(ideo);
}

export {
Expand Down
2 changes: 2 additions & 0 deletions test/offline/collinear.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ describe('Ideogram', function() {

d3 = Ideogram.d3;

this.timeout(10000);

beforeEach(function() {

delete window.chrBands;
Expand Down
32 changes: 31 additions & 1 deletion test/offline/core.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ describe('Ideogram', function() {

function callback() {
var svg = document.getElementsByTagName('svg').length;
assert.equal(svg, 2); // one for ideogram, one for settings gear
// assert.equal(svg, 2); // one for ideogram, one for settings gear
assert.equal(svg, 1); // one for ideogram
done();
}
config.onLoad = callback;
Expand Down Expand Up @@ -735,4 +736,33 @@ describe('Ideogram', function() {

ideogram = new Ideogram(config);
});

it('should properly render q-telocentric chromosomes', done => {
// Tests use case from ../examples/vanilla/eukaryotes?org=macaca-mulatta

function callback() {
var chrYParts =
document.querySelectorAll('#chrY-9544 .chromosome-border path');

var pArm = chrYParts[0].getBoundingClientRect();
assert.isBelow(Math.abs(23.6 - pArm.height), 1);

var centromere = chrYParts[1].getBoundingClientRect();
assert.isBelow(Math.abs(4.25 - centromere.height), 1);

var qArm = chrYParts[2].getBoundingClientRect();
assert.isBelow(Math.abs(2 - qArm.height), 1);

done();
}

var config = {
organism: 'macaca-mulatta', // Rhesus macaque
dataDir: '/dist/data/bands/native/',
onLoad: callback
};

var ideogram = new Ideogram(config);
});

});

0 comments on commit dcfb9c5

Please sign in to comment.