@gmod/jbrowse
Version:
JBrowse - client-side genome browser
120 lines (98 loc) • 3.28 kB
JavaScript
define( [
'JBrowse/Util'
],
function( Util ) {
// A class that keeps a frequency table. the categories in the
// frequency table can be other frequency tables.
// Note that the frequency table acts like a number (its total) when
// used as a number or a string. E.g. 0+table is like table.total()
var NestedFrequencyTable = Util.fastDeclare({
constructor: function( initialData ) {
this._categories = {};
if( initialData )
dojo.mixin( this._categories, initialData );
},
// get the sum of all the category counts
total: function() {
// calculate total if necessary
var t = 0;
for( var k in this._categories ) {
var v = this._categories[k];
t += v.total ? v.total() : v;
}
return t;
},
// decrement the count for the given category
decrement: function( slotName, amount ) {
if( ! amount )
amount = 1;
if( !slotName )
slotName = 'default';
else
slotName = slotName.toString();
if( this._categories[slotName] )
return this._categories[slotName] = Math.max( 0 , this._categories[slotName] - amount );
else
return 0;
},
// increment the count for the given category
increment: function( slotName, amount ) {
if( ! amount )
amount = 1;
if( !slotName )
slotName = 'default';
else
slotName = slotName.toString();
return ( this._categories[slotName] = (this._categories[slotName] || 0) + amount );
},
// get the value of the given category. may be a number or a
// frequency table.
get: function( slotName ) {
return this._categories[slotName] || 0;
},
// get a given category as a frequency table
getNested: function( path ) {
if( typeof path == 'string' )
path = path.split('/');
if( ! path.length )
return this;
var slotName = path[0].toString();
var slot = this._categories[slotName];
if( ! slot || ! slot._categories )
slot = this._categories[slotName] = new NestedFrequencyTable( slot ? { "default": slot+0 } : {} );
if( path.length > 1 ) {
return slot.getNested( path.slice(1) );
} else
return slot;
},
// returns array of category names that are present
categories: function() {
return Util.dojof.keys( this._categories );
},
toString: function() {
return this.total().toPrecision(6).toString().replace(/\.?0+$/,'');
},
valueOf: function() {
return this.total();
},
// iterate through the categories and counts, call like:
//
// tbl.forEach( function( count, categoryName ) {
// // do something
// }, this );
//
forEach: function( func, ctx ) {
var c = this._categories;
if( ctx ) {
for( var slotName in c ) {
func.call( ctx, c[slotName], slotName );
}
} else {
for( var slotName in c ) {
func( c[slotName], slotName );
}
}
}
});
return NestedFrequencyTable;
});