UNPKG

@gmod/jbrowse

Version:

JBrowse - client-side genome browser

146 lines (127 loc) 3.62 kB
define( [ 'dojo/_base/declare' ], function( declare ) { var Range = declare( null, /** * @lends JBrowse.Model.Range.prototype */ { /** * Adapted from a combination of Range and _Compound in the * Dalliance Genome Explorer, (c) Thomas Down 2006-2010. */ constructor: function() { this._ranges = arguments.length == 2 ? [ { min: arguments[0], max: arguments[1] } ] : 0 in arguments[0] ? dojo.clone( arguments[0] ) : [ arguments[0] ]; }, min: function() { return this._ranges[0].min; }, max: function() { return this._ranges[this._ranges.length - 1].max; }, contains: function(pos) { for (var s = 0; s < this._ranges.length; ++s) { var r = this._ranges[s]; if ( r.min <= pos && r.max >= pos ) { return true; } } return false; }, isContiguous: function() { return this._ranges.length > 1; }, ranges: function() { return this._ranges.map( function(r) { return new Range( r.min, r.max ); }); }, toString: function() { return this._ranges .map(function(r) { return '['+r.min+'-'+r.max+']'; }) .join(','); }, union: function(s1) { var s0 = this; var ranges = s0.ranges().concat(s1.ranges()).sort( this.rangeOrder ); var oranges = []; var current = ranges[0]; for (var i = 1; i < ranges.length; ++i) { var nxt = ranges[i]; if (nxt.min() > (current.max() + 1)) { oranges.push(current); current = nxt; } else { if (nxt.max() > current.max()) { current = new Range(current.min(), nxt.max()); } } } oranges.push(current); if (oranges.length == 1) { return oranges[0]; } else { return new Range(oranges); } }, intersection: function( s1 ) { var s0 = this; var r0 = s0.ranges(); var r1 = s1.ranges(); var l0 = r0.length, l1 = r1.length; var i0 = 0, i1 = 0; var or = []; while (i0 < l0 && i1 < l1) { var s0 = r0[i0], s1 = r1[i1]; var lapMin = Math.max(s0.min(), s1.min()); var lapMax = Math.min(s0.max(), s1.max()); if (lapMax >= lapMin) { or.push(new Range(lapMin, lapMax)); } if (s0.max() > s1.max()) { ++i1; } else { ++i0; } } if (or.length == 0) { return null; // FIXME } else if (or.length == 1) { return or[0]; } else { return new Range(or); } }, coverage: function() { var tot = 0; var rl = this.ranges(); for (var ri = 0; ri < rl.length; ++ri) { var r = rl[ri]; tot += (r.max() - r.min() + 1); } return tot; }, rangeOrder: function( a, b ) { if( arguments.length < 2 ) { b = a; a = this; } if (a.min() < b.min()) { return -1; } else if (a.min() > b.min()) { return 1; } else if (a.max() < b.max()) { return -1; } else if (b.max() > a.max()) { return 1; } else { return 0; } } }); return Range; });