Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions empress/support_files/css/empress.css
Original file line number Diff line number Diff line change
Expand Up @@ -696,3 +696,52 @@ p.side-header button:hover,
margin-top: 0;
margin-bottom: 0;
}

#metadata-slick-grid-container {
top: 50%;
left: 50%;
position: absolute;
transform: translate(-50%, -50%);
background: #ffffff;
border: double;
z-index: 500;
width: 85%;
max-height: 85%;
z-index: 500;
height: fit-content;
}

#greyout-empress-screen {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: black;
filter: alpha(opacity=30);
opacity: 0.3;
z-index: 499;
}

.close-button {
background-color: #cc0000;
color: white;
cursor: pointer;
border: none;
text-align: center;
outline: none;
margin: 0;
width: 5%;
}

.close-button:hover {
background-color: #999;
}

.close-bar {
background-color: #777;
width: 100%;
display: inline-block;
margin: 0;
padding: 0;
}
60 changes: 60 additions & 0 deletions empress/support_files/js/abstract-observer-pattern.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
define(["underscore"], function (_) {
/**
* @abstract
* @class AbstractObserverPattern
*
* From Wikipedia: https://en.wikipedia.org/wiki/Observer_pattern
* The observer pattern is a software design pattern in which an object,
* named the 'Subject', maintains a list of its dependents, called
* 'Observers',and notifies them automatically of any state changes, usually
* by calling one of their methods.
*
* Any class that inherits AbstractObserverPattern will become a 'Subject'.
*
* @param{String} notifyFunction The function that Subject will call on all
* of its observers. observers must implement
* this function in order to register as an
* observer.
*/
class AbstractObserverPattern {
constructor(notifyFunction) {
if (this.constructor === AbstractObserverPattern) {
throw new Error(
"Abstract class: " +
"AbstractObserverPattern cannot be instantiated."
);
}

this.observers = [];
this.notifyFunction = notifyFunction;
}

/*
* Adds an observer to the observer list.
*/
registerObserver(observer) {
if (!this.hasNotifyFunction(observer)) {
throw new Error(
"Cannot register observer: missing " + this.notifyFunction
);
}
this.observers.push(observer);
}

/**
* Notify all observers.
*/
notify(data) {
var scope = this;
_.each(this.observers, function (obs) {
obs[scope.notifyFunction](data);
});
}

hasNotifyFunction(observer) {
return typeof observer[this.notifyFunction] === "function";
}
}

return AbstractObserverPattern;
});
77 changes: 75 additions & 2 deletions empress/support_files/js/bp-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,17 @@ define(["ByteArray", "underscore"], function (ByteArray, _) {
* @return{Number} The excess at position i
* @private
*/
BPTree.prototype.excess_ = function (i) {
BPTree.prototype.excess = function (i) {
// need to subtract 1 since i starts at 0
// Note: rank(1,i) - rank(0,i) = (2*(rank(1,i)) - i
return 2 * this.r1Cache_[i] - i - 1;
// if (i < 0) {
// return 0;
// }
// return 2 * this.r1Cache_[i] - i - 1;

// this method is used frequently and thus has been updated
// to use a cached version
return this.eCache_[i];
};

/**
Expand Down Expand Up @@ -1103,5 +1110,71 @@ define(["ByteArray", "underscore"], function (ByteArray, _) {
};
};

/*
* Finds the minimum excess between i and j.
*
* @param {Number} i The ith index of the bp array.
* @param {Number} j The jth index of the bp array.
*
* @return The miniumn excess between i and j.
*/
BPTree.prototype.rmq = function (i, j) {
if (j < i) {
var temp = j;
j = i;
i = temp;
}
var minK = i;
var minV = this.excess(i);
for (var k = i; k < j + 1; k++) {
var obsV = this.excess(k);
if (obsV < minV) {
minK = k;
minV = obsV;
}
}
return minK;
};

/*
* Test to see if i if the ancestor of j.
*
* @param {Number} i The ith index of the bp array.
* @param {Number} j The jth index of the bp array.
*
* @return true if i is the ancestor of j, false otherwise.
*/
BPTree.prototype.isAncestor = function (i, j) {
if (i === j) {
return false;
}

if (!this.b_[i]) {
i = this.open(i);
}

return i <= j && j < this.close(i);
};

/*
* Finds the lowest common ancestor of i and j
*
* @param {Number} i The ith index of the bp array.
* @param {Number} j The jth index of the bp array.
*
* @return The index of the lca of i and j.
*/
BPTree.prototype.lca = function (i, j) {
if (i === j) {
return i;
} else if (this.isAncestor(i, j)) {
return i;
} else if (this.isAncestor(j, i)) {
return j;
} else {
return this.parent(this.rmq(i, j) + 1);
}
};

return BPTree;
});
28 changes: 24 additions & 4 deletions empress/support_files/js/canvas-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ define(["underscore", "glMatrix", "SelectedNodeMenu"], function (
// update the node selection menu
selectedNodeMenu.updateMenuPosition();
};

var previousCursorValue = canvas.style.cursor;
// stops moving tree when mouse is released
var stopMove = function (e) {
document.onmouseup = null;
document.onmousemove = null;
scope.mouseX = null;
scope.mouseY = null;
canvas.style.cursor = "default";
canvas.style.cursor = previousCursorValue;
};

// adds the listeners to the document to move tree
Expand All @@ -116,6 +116,7 @@ define(["underscore", "glMatrix", "SelectedNodeMenu"], function (
scope.mouseY = center - e.clientY;
document.onmouseup = stopMove;
document.onmousemove = moveTree;
previousCursorValue = canvas.style.cursor;
canvas.style.cursor = "none";
};

Expand All @@ -137,6 +138,7 @@ define(["underscore", "glMatrix", "SelectedNodeMenu"], function (

// removes the selected node menu if the mouseMove flag is not set
var mouseClick = function (e) {
var shiftPressed = e.shiftKey;
if (!scope.mouseMove) {
// clear old select menu
selectedNodeMenu.clearSelectedNode();
Expand Down Expand Up @@ -201,12 +203,23 @@ define(["underscore", "glMatrix", "SelectedNodeMenu"], function (
scope.placeNodeSelectionMenu(
empress.getNodeInfo(closeNode, "name"),
false,
closeNode
closeNode,
shiftPressed
);
}
}
};

var shiftPress = function (e) {
if (e.shiftKey) {
canvas.style.cursor = "pointer";
} else {
canvas.style.cursor = "default";
}
};
document.onkeydown = shiftPress;
document.onkeyup = shiftPress;

// uncollapses a clade if double clicked on
var doubleClick = function (e) {
var treeSpace = drawer.toTreeCoords(e.clientX, e.clientY);
Expand Down Expand Up @@ -419,8 +432,15 @@ define(["underscore", "glMatrix", "SelectedNodeMenu"], function (
CanvasEvents.prototype.placeNodeSelectionMenu = function (
nodeName,
moveTree,
nodeKey
nodeKey,
shiftPressed = false
) {
if (shiftPressed) {
this.empress.setSelectedNode(nodeKey);
// this.selectedNodeMenu.setSelectedNodes([nodeKey]);
// this.empress.drawTree();
return;
}
var scope = this;
var node;
/**
Expand Down
52 changes: 52 additions & 0 deletions empress/support_files/js/drawer.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ define(["underscore", "glMatrix", "Camera", "Colorer"], function (
s.treeColorBuff = c.createBuffer();
this.treeColorSize = 0;

// buffer object for path coordinates
s.pathCoordBuff = c.createBuffer();
this.pathCoordSize = 0;

// buffer object to store path color
s.pathColorBuff = c.createBuffer();
this.pathColorSize = 0;

// buffer object used to thicken node lines
s.thickNodeBuff = c.createBuffer();
this.thickNodeSize = 0;
Expand All @@ -148,6 +156,9 @@ define(["underscore", "glMatrix", "Camera", "Colorer"], function (
// buffer object for active 'selected' node
s.selectedNodeBuff = c.createBuffer();

// buffer object for active 'selected' node
s.highlightedNodesBuff = c.createBuffer();

// buffer object for colored clades
s.cladeBuff = c.createBuffer();
this.cladeVertSize = 0;
Expand Down Expand Up @@ -315,6 +326,27 @@ define(["underscore", "glMatrix", "Camera", "Colorer"], function (
this.fillBufferData_(this.sProg_.treeColorBuff, data);
};

/**
* Fills the buffer used to draw the selected path.
*
* @param {Array} data The coordinates [x, y, ...] to fill pathCoordBuff
*/
Drawer.prototype.loadPathCoordsBuff = function (data) {
data = new Float32Array(data);
this.pathCoordSize = data.length / 2;
this.fillBufferData_(this.sProg_.pathCoordBuff, data);
};

/**
* Fills the buffer used to draw the selected path.
*
* @param {Array} data The color data to fill pathColorBuff
*/
Drawer.prototype.loadPathColorBuff = function (data) {
data = new Float32Array(data);
this.pathColorSize = data.length;
this.fillBufferData_(this.sProg_.pathColorBuff, data);
};
/**
* Fills the buffer used to thicken node lines
*
Expand Down Expand Up @@ -349,6 +381,17 @@ define(["underscore", "glMatrix", "Camera", "Colorer"], function (
this.fillBufferData_(this.sProg_.selectedNodeBuff, data);
};

/**
* Fills the selected node buffer
*
* @param {Array} data The coordinate and color of selected node
*/
Drawer.prototype.loadHightlightedSelectedNodeBuff = function (data) {
data = new Float32Array(data);
this.highlightedNodeSize = data.length / this.VERTEX_SIZE;
this.fillBufferData_(this.sProg_.highlightedNodesBuff, data);
};

/**
* Fills the buffer used to draw nodes
*
Expand Down Expand Up @@ -409,11 +452,20 @@ define(["underscore", "glMatrix", "Camera", "Colorer"], function (
this.bindBuffer(s.selectedNodeBuff, 1, 3);
c.drawArrays(gl.POINTS, 0, this.selectedNodeSize);

// draw highlighted node
c.uniform1f(s.pointSize, this.SELECTED_NODE_CIRCLE_DIAMETER);
this.bindBuffer(s.highlightedNodesBuff, 1, 3);
c.drawArrays(gl.POINTS, 0, this.highlightedNodeSize);

c.uniform1i(s.isSingle, 0);
this.bindBuffer(s.treeCoordBuff, 2, 2);
this.bindBuffer(s.treeColorBuff, 3, 1);
c.drawArrays(c.LINES, 0, this.treeCoordSize);

this.bindBuffer(s.pathCoordBuff, 2, 2);
this.bindBuffer(s.pathColorBuff, 3, 1);
c.drawArrays(c.LINES, 0, this.pathCoordSize);

this.bindBuffer(s.thickNodeBuff, 1, 3);
c.drawArrays(c.TRIANGLES, 0, this.thickNodeSize);

Expand Down
Loading