/** * This object is a hovering data cell which flys between two existing data cells * and copys the value from the source data cell to the target data cell. */ var MOVE_INTERVAL = 17; var DEFAULT_STEP = 2; /** * Constructor * source - Source DataCell * target - Target DataCell * srcLeft - Absolute left coordinate of the source data cell * srcTop - Absolute top coordinate of the source data cell * trgtLeft - Absolute left coordinate of the target data cell * trgtTop - Absolute top coordinate of the target data cell * width - Width of the flying data cell * height - Height of the flying data cell * highlight - Defines whether the flying cell is highlighted or not * speed - Speed of the flying cell (values between 1 to 5) */ function FlyingData(source, target, srcLeft, srcTop, trgtLeft, trgtTop, width, height, highlight, speed) { var d0 = document.createElement("DIV"); d0.style.position = "absolute"; d0.style.left = srcLeft - 1; d0.style.top = srcTop - 1; d0.style.width = target.itemDiv.offsetWidth; //width; d0.style.height = target.itemDiv.offsetHeight; //height; d0.style.borderStyle = "Solid"; d0.style.borderWidth = "1px"; d0.style.borderColor = "#000000"; d0.style.fontFamily = "Arial"; d0.style.lineHeight = parseInt(height) + "px"; d0.style.fontSize = CELL_FONT_SIZE; d0.style.textAlign = "center"; d0.style.fontWeight = "Bolder"; d0.style.display = "none"; if (!highlight) d0.style.backgroundColor = "#FFFF00";//CELL_COLOR; else d0.style.backgroundColor = CELL_HIGHLIGHT; document.body.appendChild(d0); d0.innerHTML = source.getStringValue(); var that = this; /** * Private function * Starts the fly */ function flyTo(x, y) { var sx = Math.abs(getAbsLeft(d0) - x); var sy = Math.abs(getAbsTop(d0) - y); var xStep = DEFAULT_STEP + speed * 2; var yStep = Math.round(xStep * (sy/sx)); var slowX = (xStep > yStep * 2); var slowY = (yStep > xStep * 2); if (yStep < 1) yStep = 1; setTimeout(function() { moveX(d0, x - 1, xStep, slowX); }, 2); setTimeout(function() { moveY(d0, y - 1, yStep, slowY); }, 1); var interval = MOVE_INTERVAL; /** * Moves the cell on X axis */ function moveX(obj, x, moveStep, slow) { var pLeft = parseInt(obj.style.left); if (pLeft < x) { obj.style.left = pLeft + moveStep; } else { obj.style.left = pLeft - moveStep; } if (parseInt(obj.style.left) < x - moveStep || parseInt(obj.style.left) > x + moveStep) setTimeout(function() { moveX(obj, x, moveStep); }, interval * (slow ? 2 : 1)); else { obj.style.left = x; upSemaphore(); } } /** * Moves the cell on Y axis */ function moveY(obj, y, moveStep, slow) { var pTop = parseInt(obj.style.top); if (pTop < y) { obj.style.top = pTop + moveStep; } else { obj.style.top = pTop - moveStep; } if (parseInt(obj.style.top) < y - moveStep || parseInt(obj.style.top) > y + moveStep) { setTimeout(function() { moveY(obj, y, moveStep); }, interval * (slow ? 2 : 1)); } else { obj.style.top = y; upSemaphore(); } } /** * A semaphore-like data structure, used to signal when both X and Y axes move are done. */ var semaphore = -2; var available = true; function upSemaphore() { if (!available) { setTimeout(upSemaphore, 1); return; } available = false; semaphore++; if (semaphore == 0) ready(); available = true; } } var onReadyFunc; /** * Setting up the operation of this object and initiates the fly * onReady - a reference to a function to be called when done */ this.fly = function(onReady) { d0.style.display = "block"; onReadyFunc = onReady; flyTo(trgtLeft, trgtTop); } /** * Finalizes the operation of this object, disposes HTML DOM objects and calls * the onReady function. */ function ready() { function _ready() { document.body.removeChild(d0); d0 = null; onReadyFunc(); } setTimeout(_ready, 700 * (1.0 / speed)); } }