UNPKG

@gmod/jbrowse

Version:

JBrowse - client-side genome browser

156 lines (133 loc) 6.08 kB
define([ 'dojo/_base/declare', 'dojo/_base/array', 'JBrowse/View/FeatureGlyph/Box', 'JBrowse/View/FeatureGlyph/AlignmentColoring', 'JBrowse/Store/SeqFeature/_MismatchesMixin' ], function( declare, array, BoxGlyph, AlignmentColoring, MismatchesMixin ) { return declare( [BoxGlyph,MismatchesMixin], { constructor: function() { // if showMismatches is false, stub out this object's // _drawMismatches to be a no-op if( ! this.config.style.showMismatches ) this._drawMismatches = function() {}; }, _defaultConfig: function() { return this._mergeConfigs( dojo.clone( this.inherited(arguments) ), { //maxFeatureScreenDensity: 400 style: { color: AlignmentColoring.colorAlignment, color_fwd_strand_not_proper: '#ECC8C8', color_rev_strand_not_proper: '#BEBED8', color_fwd_strand: '#EC8B8B', color_rev_strand: '#8F8FD8', color_fwd_missing_mate: '#D11919', color_rev_missing_mate: '#1919D1', color_fwd_diff_chr: '#000000', color_rev_diff_chr: '#969696', color_pair_lr: 'grey', color_pair_rr: 'navy', color_pair_rl: 'teal', color_pair_ll: 'green', color_nostrand: '#999999', color_interchrom: 'orange', color_longinsert: 'red', color_shortinsert: 'pink', border_color: null, strandArrow: false, height: 7, marginBottom: 1, showMismatches: true, mismatchFont: 'bold 10px Courier New,monospace', orientationType: 'fr' // default illumina adapter sequence --> <-- } } ); }, renderFeature: function( context, fRect ) { this.inherited( arguments ); // draw some mismatches if the feature is more than 3px wide: // draw everything if zoomed in past 0.2 px/bp, otherwise // draw only skips and deletions (the mismatches that // might be large enough to see) if( fRect.w > 2 ) { if( fRect.viewInfo.scale > 0.2 ) this._drawMismatches( context, fRect, this._getMismatches( fRect.f ) ); else this._drawMismatches( context, fRect, this._getSkipsAndDeletions( fRect.f )); } }, // draw both gaps and mismatches _drawMismatches: function( context, fRect, mismatches, f) { var feature = f || fRect.f var block = fRect.viewInfo.block; var scale = block.scale; var charSize = this.getCharacterMeasurements( context ); context.textBaseline = 'middle'; // reset to alphabetic (the default) after loop array.forEach( mismatches, function( mismatch ) { var start = feature.get('start') + mismatch.start; var end = start + mismatch.length; var mRect = { h: (fRect.rect||{}).h || fRect.h, l: block.bpToX( start ), t: fRect.rect.t }; mRect.w = Math.max( block.bpToX( end ) - mRect.l, 1 ); if( mismatch.type == 'mismatch' || mismatch.type == 'deletion' ) { context.fillStyle = this.track.colorForBase( mismatch.type == 'deletion' ? 'deletion' : mismatch.base ); context.fillRect( mRect.l, mRect.t, mRect.w, mRect.h ); if( mRect.w >= charSize.w && mRect.h >= charSize.h-3 ) { context.font = this.config.style.mismatchFont; context.fillStyle = mismatch.type == 'deletion' ? 'white' : 'black'; context.fillText( mismatch.base, mRect.l+(mRect.w-charSize.w)/2+1, mRect.t+mRect.h/2 ); } } else if( mismatch.type == 'insertion' ) { context.fillStyle = 'purple'; context.fillRect( mRect.l-1, mRect.t+1, 2, mRect.h-2 ); context.fillRect( mRect.l-2, mRect.t, 4, 1 ); context.fillRect( mRect.l-2, mRect.t+mRect.h-1, 4, 1 ); if( mRect.w >= charSize.w && mRect.h >= charSize.h-3 ) { context.font = this.config.style.mismatchFont; context.fillText( '('+mismatch.base+')', mRect.l+2, mRect.t+mRect.h/2 ); } } else if( mismatch.type == 'hardclip' || mismatch.type == 'softclip' ) { context.fillStyle = mismatch.type == 'hardclip' ? 'red' : 'blue'; context.fillRect( mRect.l-1, mRect.t+1, 2, mRect.h-2 ); context.fillRect( mRect.l-2, mRect.t, 4, 1 ); context.fillRect( mRect.l-2, mRect.t+mRect.h-1, 4, 1 ); if( mRect.w >= charSize.w && mRect.h >= charSize.h-3 ) { context.font = this.config.style.mismatchFont; context.fillText( '('+mismatch.base+')', mRect.l+2, mRect.t+mRect.h/2 ); } } else if( mismatch.type == 'skip' ) { context.clearRect( mRect.l, mRect.t, mRect.w, mRect.h ); context.fillStyle = '#333'; context.fillRect( mRect.l, mRect.t+(mRect.h-2)/2, mRect.w, 2 ); } },this); context.textBaseline = 'alphabetic'; }, getCharacterMeasurements: function( context ) { return this.charSize = this.charSize || function() { var fpx; try { fpx = (this.config.style.mismatchFont.match(/(\d+)px/i)||[])[1]; } catch(e) {} fpx = fpx || Infinity; return { w: fpx, h: fpx }; }.call(this); } }); });