@gmod/jbrowse
Version:
JBrowse - client-side genome browser
148 lines (130 loc) • 5.49 kB
JavaScript
define(
[
'dojo/_base/declare',
'JBrowse/has',
'JBrowse/View/Track/BlockBased'
],
function( declare, has, BlockBased ) {
return declare( BlockBased,
/**
* @lends JBrowse.View.Track.FixedImage.prototype
*/
{
/**
* A track that displays tiled images (PNGs, or other images) at fixed
* intervals along the reference sequence.
* @constructs
* @extends JBrowse.View.Track.BlockBased
*/
constructor: function( args ) {
this.trackPadding = args.trackPadding || 0;
},
handleImageError: function(ev) {
var img = ev.currentTarget || ev.srcElement;
img.style.display = "none";
dojo.stopEvent(ev);
},
/**
* @private
*/
makeImageLoadHandler: function( img, blockIndex, blockWidth, composeCallback ) {
var handler = dojo.hitch( this, function() {
this.imageHeight = img.height;
img.style.height = img.height + "px";
img.style.width = (100 * (img.baseWidth / blockWidth)) + "%";
this.heightUpdate( img.height, blockIndex );
if( composeCallback )
composeCallback();
return true;
});
if( has('ie') )
// in IE, have to delay calling it for a (arbitrary) 1/4
// second because the image's height is not always
// available when the onload event fires. >:-{
return function() {
window.setTimeout(handler,250);
};
else
return handler;
},
fillBlock: function( args ) {
var blockIndex = args.blockIndex;
var block = args.block;
var leftBase = args.leftBase;
var rightBase = args.rightBase;
var scale = args.scale;
var finishCallback = args.finishCallback || function() {};
var blockWidth = rightBase - leftBase;
this.store.getImages(
{ scale: scale, start: leftBase, end: rightBase },
dojo.hitch(this, function(images) {
dojo.forEach( images, function(im) {
im.className = 'image-track';
if (!(im.parentNode && im.parentNode.parentNode)) {
im.style.position = "absolute";
im.style.left = (100 * ((im.startBase - leftBase) / blockWidth)) + "%";
switch (this.config.align) {
case "top":
im.style.top = "0px";
break;
case "bottom":
/* fall through */
default:
im.style.bottom = this.trackPadding + "px";
break;
}
block.domNode.appendChild(im);
}
// make an onload handler for when the image is fetched that
// will update the height and width of the track
var loadhandler = this.makeImageLoadHandler( im, blockIndex, blockWidth );
if( im.complete )
// just call the handler ourselves if the image is already loaded
loadhandler();
else
// otherwise schedule it
im.onload = loadhandler;
}, this);
finishCallback();
}),
dojo.hitch( this, function( error ) {
if( error.status == 404 ) {
finishCallback();
} else {
this.fillBlockError( blockIndex, block, error );
}
finishCallback();
})
);
},
startZoom: function(destScale, destStart, destEnd) {
if (this.empty) return;
},
endZoom: function(destScale, destBlockBases) {
this.clear();
},
clear: function() {
this.inherited( arguments );
},
transfer: function(sourceBlock, destBlock, scale,
containerStart, containerEnd) {
if (!(sourceBlock && destBlock)) return;
var children = sourceBlock.domNode.childNodes;
var destLeft = destBlock.startBase;
var destRight = destBlock.endBase;
var im;
for (var i = 0; i < children.length; i++) {
im = children[i];
if ("startBase" in im) {
//if sourceBlock contains an image that overlaps destBlock,
if ((im.startBase < destRight)
&& ((im.startBase + im.baseWidth) > destLeft)) {
//move image from sourceBlock to destBlock
im.style.left = (100 * ((im.startBase - destLeft) / (destRight - destLeft))) + "%";
destBlock.domNode.appendChild(im);
}
}
}
}
});
});