Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Animation #146

Merged
merged 73 commits into from
Apr 6, 2020
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
d992b88
added camera/tests
kwcantrell Jul 29, 2019
c6cc202
added tests
kwcantrell Jul 30, 2019
3714011
checkpoint
kwcantrell Aug 16, 2019
78f2383
naive implementation of bp tree
kwcantrell Aug 16, 2019
476b555
added travis
kwcantrell Aug 16, 2019
d930e75
removed travis
kwcantrell Aug 16, 2019
790129a
added preorder
kwcantrell Aug 16, 2019
3c9b2fa
Merge pull request #16 from kwcantrell/bp-tree
kwcantrell Aug 16, 2019
9044382
added basic drawer
kwcantrell Aug 20, 2019
5c686cc
added space
kwcantrell Aug 20, 2019
8e4ac07
addressed PR comments
kwcantrell Aug 20, 2019
bcabaab
addressed PR comment
kwcantrell Aug 20, 2019
4b26046
Merge branch 'master' of https://github.com/kwcantrell/empress into d…
kwcantrell Aug 20, 2019
fbf8ece
added hello-world test
kwcantrell Aug 27, 2019
6db1d0c
moved package.json
kwcantrell Aug 27, 2019
7e68666
changed travis
kwcantrell Aug 27, 2019
029f7b3
added dep
kwcantrell Aug 27, 2019
e53a9a6
update
kwcantrell Aug 27, 2019
1f38def
added yarn
kwcantrell Aug 27, 2019
ffdaaec
added dev
kwcantrell Aug 27, 2019
41314c3
npm
kwcantrell Aug 27, 2019
ef59362
npm
kwcantrell Aug 27, 2019
a04ae25
nodeJS 10
kwcantrell Aug 27, 2019
81157ba
removed node_modules
kwcantrell Aug 27, 2019
40fb511
Merge branch 'master' of https://github.com/biocore/empress into trav…
kwcantrell Aug 27, 2019
08622f1
intial side panel
kwcantrell Aug 28, 2019
9e574b9
fixed tests
kwcantrell Aug 28, 2019
88df7b4
fixed travis test
kwcantrell Aug 28, 2019
15d7407
added cache for open-close
kwcantrell Aug 28, 2019
e31bbd4
Merge branch 'bp-oc-cache' of https://github.com/kwcantrell/empress i…
kwcantrell Aug 28, 2019
d3a837c
first attempt to color sample
kwcantrell Sep 4, 2019
8d59e91
generalized coloring
kwcantrell Sep 4, 2019
d061f2c
Finished the sample coloring UI
kwcantrell Sep 19, 2019
5558099
removed Travis tests
kwcantrell Sep 19, 2019
8abc73e
Added python byte code folder
kwcantrell Sep 19, 2019
712585d
modularized sample coloring
kwcantrell Sep 30, 2019
25c7a4f
fixed biom.getSampleObs
kwcantrell Sep 30, 2019
07e967c
removed travis
kwcantrell Sep 30, 2019
c6d6e03
Merge branch 'master' into sample-color
kwcantrell Oct 1, 2019
78a6222
fixed biom-table getSampleObs
kwcantrell Oct 1, 2019
0e5701c
Merge branch 'sample-color' of https://github.com/kwcantrell/empress …
kwcantrell Oct 1, 2019
67cbccc
checkpoint
kwcantrell Oct 13, 2019
823c0d6
merged with master
kwcantrell Nov 22, 2019
3552adf
Basic Animator
kwcantrell Nov 25, 2019
87d3223
working but no auto play
kwcantrell Mar 6, 2020
3f33a4d
check before reversing traj and grad
kwcantrell Mar 8, 2020
7d087a1
checkpoint
kwcantrell Mar 27, 2020
81f2e9d
added documentation
kwcantrell Mar 28, 2020
cf74095
js lint
kwcantrell Mar 28, 2020
d097389
Merge branch 'master' into animation
kwcantrell Mar 28, 2020
576d7b6
Merge pull request #29 from kwcantrell/animation
kwcantrell Mar 28, 2020
2061e91
Update empress/_plot.py
kwcantrell Mar 30, 2020
6ce0cc9
Update empress/support_files/css/empress.css
kwcantrell Mar 30, 2020
8403e81
Update empress/support_files/js/biom-table.js
kwcantrell Mar 30, 2020
8217863
Update empress/support_files/js/biom-table.js
kwcantrell Mar 30, 2020
f274b1e
Update empress/support_files/js/animation-panel-handler.js
kwcantrell Mar 30, 2020
b2ded8c
Update empress/support_files/js/biom-table.js
kwcantrell Mar 30, 2020
f0a0f95
Update empress/support_files/js/empress.js
kwcantrell Mar 30, 2020
4d2b051
Update empress/support_files/js/animation-panel-handler.js
kwcantrell Mar 30, 2020
02fc054
Update empress/support_files/js/animation-panel-handler.js
kwcantrell Mar 30, 2020
ee93619
Update empress/support_files/js/animation-panel-handler.js
kwcantrell Mar 30, 2020
b2d7929
Update empress/support_files/js/animation-panel-handler.js
kwcantrell Mar 30, 2020
bc52acc
Update empress/support_files/js/animation-panel-handler.js
kwcantrell Mar 30, 2020
15c0499
Update empress/support_files/js/animation-panel-handler.js
kwcantrell Mar 30, 2020
2795510
Update empress/support_files/js/animation-panel-handler.js
kwcantrell Mar 30, 2020
23f8095
Update empress/support_files/js/animation-panel-handler.js
kwcantrell Mar 30, 2020
19fdbc5
Update empress/support_files/js/animation-panel-handler.js
kwcantrell Mar 30, 2020
4ee966f
Apply suggestions from code review
kwcantrell Mar 30, 2020
9a92ae1
Update empress/support_files/js/animator.js
kwcantrell Mar 31, 2020
e478628
#146
kwcantrell Mar 31, 2020
ef7daa0
Merge branch 'master' of https://github.com/kwcantrell/empress
kwcantrell Mar 31, 2020
4ff2664
back to light mode
kwcantrell Apr 6, 2020
262374f
Update empress/support_files/js/drawer.js
fedarko Apr 6, 2020
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
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ empress-biom.py
node_modules/

# Templated filed created when running empress-tree.py
test_init.html
*.html

# # Python Byte code folder
# empress/__pycache__/
Expand Down Expand Up @@ -142,3 +142,8 @@ dmypy.json

# Pyre type checker
.pyre/


# dev scripts/data
inf/
create-plt.bash
2 changes: 1 addition & 1 deletion .jshintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"esversion": 6
"esversion": 8
}
17 changes: 17 additions & 0 deletions empress/_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,22 @@ def plot(output_dir: str,
.to_dataframe().filter(feature_table.index, axis=0) \
.to_dict(orient='index')

# TODO: Empress is currently sorting all metadata as strings. This is
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think sample metadata is in general fine loaded as a string. Have you encountered any issues?

kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
# memory intensive an wont scale well. We should convert all numberic
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
# data/compress metadata.

# This is used in biom-table. Currently this is only used to ignore null
# data (i.e. NaN and "unknown") and also determines sorting order.
# The original intent is to signal what
# columns are discrete/continous.
# type of sample metedata (n - number, o - object)
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
sample_data_type = sample_metadata \
.to_dataframe().filter(feature_table.index, axis=0) \
.dtypes \
.to_dict()
sample_data_type = {k: 'n' if pd.api.types.is_numeric_dtype(v) else 'o'
for k, v in sample_data_type.items()}

# create a mapping of observation ids and the samples that contain them
obs_data = {}
feature_table = (feature_table > 0).T
Expand All @@ -91,6 +107,7 @@ def plot(output_dir: str,
'tree_data': tree_data,
'names_to_keys': names_to_keys,
'sample_data': sample_data,
'sample_data_type': sample_data_type,
'obs_data': obs_data,
'names': names,
})
Expand Down
12 changes: 12 additions & 0 deletions empress/support_files/css/empress.css
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,18 @@ p.side-header button {
margin-right: auto;
}

.control div.animate-btns {
margin-left: 10%;
margin-right: 10%;
display: grid;
grid-template-columns: auto auto auto;
justify-items: center;
}

/*.control div.animate-btns button {
background-color: #00ff00;
}*/

kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
.control hr {
border-top: 1px solid darkgray;
border-bottom: none;
Expand Down
257 changes: 257 additions & 0 deletions empress/support_files/js/animation-panel-handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
define(["Colorer"], function(Colorer) {
/**
*
* @class AnimationPanel
ElDeveloper marked this conversation as resolved.
Show resolved Hide resolved
*
* Creates tab for the animation panel and handles their events events.
*
* @param{Object} animator The object that creates the animations
*
* @return {AnimatePanel}
* construct AnimatePanel
*/
function AnimatePanel(animator) {
// used in event triggers
this.animator = animator;

// animation GUI components
this.colorSelect = document.getElementById("animate-color-select");
this.gradient = document.getElementById("animate-gradient");
this.trajectory = document.getElementById("animate-trajectory");
this.hideChk = document.getElementById("animate-hide-non-feature");
this.lWidth = document.getElementById("animate-line-width");
this.startBtn = document.getElementById("animate-start-btn");
this.stopBtn = document.getElementById("animate-stop-btn");
this.pauseBtn = document.getElementById("animate-pause-btn");
this.resumeBtn = document.getElementById("animate-resume-btn");
this.prevFrameBtn = document.getElementById("animate-prev-btn");
this.nextFrameBtn = document.getElementById("animate-next-btn");
}

/**
* Makes the play button visible. This is the menu shown before user has
* started the animation.
*
* @return {null}
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
* @private
*/
AnimatePanel.prototype.__startOptions = function() {
// hide the following buttons
this.stopBtn.classList.add("hidden");
this.pauseBtn.classList.add("hidden");
this.resumeBtn.classList.add("hidden");
this.prevFrameBtn.classList.add("hidden");
this.nextFrameBtn.classList.add("hidden");

// show the following buttons
this.startBtn.classList.remove("hidden");
};

/**
* Makes the stop/pause buttons visible. This is the menu shown during the
* animation.
*
* @return {null}
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
* @private
*/
AnimatePanel.prototype.__pauseOptions = function() {
// hide the following buttons
this.startBtn.classList.add("hidden");
this.resumeBtn.classList.add("hidden");
this.prevFrameBtn.classList.add("hidden");
this.nextFrameBtn.classList.add("hidden");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion at least :), it would be nice to have the prev/next-frame buttons present from the start of the animation -- it wasn't clear to me initially that these buttons were even available until I pressed Pause. For users who want to step through the animations at their own pace (either to go slower or faster), I suspect these buttons will be preferable.

Copy link
Collaborator Author

@kwcantrell kwcantrell Mar 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fedarko thanks for the suggestion! My goal with the GUI is to make things as intuitive and easy to use. One way I try to accomplish this is by only presenting options to the user that can be applied at that moment. Since the prev/next features can only be used when the animation is paused, I decided to hide those options unless the user pauses the animation.

Instead of hiding those buttons, I can disable them while the animation is running and enable them when the animation is paused. Also, I can start the animation is the pause state instead of the run state so users who wanted to manually step through the animation could do so without having to first pause the animation first.

@ElDeveloper how does Emperor handle this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In emperor we disable the buttons and still leave them visible (instead of hiding them).


// show the following buttons
this.stopBtn.classList.remove("hidden");
this.pauseBtn.classList.remove("hidden");
};

/**
* Makes the prev/next/stop/resume buttons visible. This is the menu shown
* when user pauses the animation.
*
* @return {null}
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
* @private
*/
AnimatePanel.prototype.__resumeOptions = function() {
// hide the following buttons
this.pauseBtn.classList.add("hidden");
this.startBtn.classList.add("hidden");

// show the following buttons
this.stopBtn.classList.remove("hidden");
this.resumeBtn.classList.remove("hidden");
this.prevFrameBtn.classList.remove("hidden");
this.nextFrameBtn.classList.remove("hidden");

// dont show previous button on frame 1
if (this.animator.onFirstFrame()) {
this.prevFrameBtn.classList.add("hidden");
}

// dont show next button on last frame
if (this.animator.onLastFrame()) {
this.nextFrameBtn.classList.add("hidden");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A slight problem with this approach is that the buttons are positioned such that, when the Next Frame button is hidden, the Previous Frame button is shifted over to where this button previously was:

Second-from-last frame in an animation
penultimate

Last frame in an animation
ultimate

This means that, for people who are manually clicking through the animation, they'll likely accidentally press Previous Frame when they get to the final frame. Not a big deal, but an annoyance nonetheless.

IMO it would be better to absolutely position these buttons, to attempt to stave off this problem.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! I'll update the PR to disable the prev/next button when on the first/last frame instead of hiding them.

}
};

/**
* enables/disable the drop down menus. When the animation is playing,
* the drop down menus are disable in order to prevent user from changing
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
* the gradient/trajectory during an animation.
*
* @return {null}
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
* @private
*/
AnimatePanel.prototype.__toogleSelects = function(disableStatus) {
this.colorSelect.disabled = disableStatus;
this.gradient.disabled = disableStatus;
this.trajectory.disabled = disableStatus;
};

/**
* Initializes GUI components/set up callback events
* @return {null}
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
*/
AnimatePanel.prototype.addAnimationTab = function() {
// used in closers
var ap = this;

// hide play/pause/next/previous/stop buttons
this.__startOptions();

// The color map selector
Colorer.addColorsToSelect(this.colorSelect);

// retrive gradient/trajectory categories
var categories = this.animator.getSampleCategories();

// add categories options to gradient drop down menu
for (var i = 0; i < categories.length; i++) {
var opt = document.createElement("option");
opt.value = categories[i];
opt.innerHTML = categories[i];
this.gradient.appendChild(opt);
}

// copy options and add them to trajectory drop down menu
var options = this.gradient.innerHTML;
this.trajectory.innerHTML = options;

/**
* Event: triggers when user clicks on the hide branch checkbox.
* Sets hide parameter in animation state machine.
*
* @return {null}
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
*/
this.hideChk.onchange = function() {
ap.animator.setHide(ap.hideChk.checked);
};

/**
* Event: triggers when user changes value of line width.
* Sets line width parameter in animation state machine.
*/
this.lWidth.onchange = function() {
var val = ap.lWidth.value;

// make sure line width is positve
if (val < 1) {
val = 1;
ap.lWidth = val;
}

// pass line width to state machine
ap.animator.setLineWidth(val);
};

/**
* Event: triggers when user clicks on the start button.
* Starts the animation.
*
* @return {null}
*/
this.startBtn.onclick = function() {
// change GUI components
ap.__toogleSelects(true);
ap.__pauseOptions();

// collect starting conditions for the animation
var gradient = ap.gradient.value;
var trajectory = ap.trajectory.value;
var cm = ap.colorSelect.value;
var hide = ap.hideChk.checked;
var lWidth = ap.lWidth.value;

// pass parameters to state machine
ap.animator.setAnimationParameters(
trajectory,
gradient,
cm,
hide,
lWidth
);

// start animation
ap.animator.startAnimation();
ElDeveloper marked this conversation as resolved.
Show resolved Hide resolved
};

/**
* Event: triggers when user clicks on pause button.
* Pauses the animation.
*
* @return {null}
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
*/
this.pauseBtn.onclick = function() {
ap.__resumeOptions();
ap.animator.pauseAnimation();
};

/**
* Event: triggers when user clicks on resume button.
* Resumes the animation.
*
* @return {null}
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
*/
this.resumeBtn.onclick = function() {
ap.__pauseOptions();
ap.animator.resumeAnimation();
};

/**
* Event: triggers when user clicks on stop button.
* Stops the animation and clears the state machine
*
* @return {null}
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
*/
this.stopBtn.onclick = function() {
ap.__toogleSelects(false);
ap.__startOptions();
ap.animator.stopAnimation();
};

/**
* Event: triggers when user clicks on previous button.
* Shows the previous frame in the animation
*
* @return {null}
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
*/
this.prevFrameBtn.onclick = function() {
ap.animator.prevFrame();
ap.__resumeOptions();
};

/**
* Event: triggers when user clicks on next button.
* Shows the next frame in the animation.
*
* @return {null}
kwcantrell marked this conversation as resolved.
Show resolved Hide resolved
*/
this.nextFrameBtn.onclick = function() {
ap.animator.nextFrame();
ap.__resumeOptions();
};
};

return AnimatePanel;
});
Loading