biocore / emperor

Emperor a tool for the analysis and visualization of large microbial ecology datasets
http://biocore.github.io/emperor/
Other
52 stars 50 forks source link

Parallel Plots #727

Closed dhakim87 closed 4 years ago

dhakim87 commented 5 years ago

This branch prototypes the ability to switch between scatter and parallel plots in the Axes tab. Parallel Plot display is a GL_LINES mesh that is computed once and drawn with shaders mirroring the _fast_init call. The Axes controller is setting a viewType field on the view that then modifies how the scene is rendered.

There are a couple of noteworthy changes that we might want to discuss further: When swapping scatter and parallel plots, we remove the existing meshes from the scene and add new ones. This can get weird in terms of maintaining controller properties (color, scale etc...) and has some overhead for tearing down and creating the new meshes. I'm also using a couple of dispose calls directly from sceneplotview3d since we don't have a better framework in place for managing gl objects.

Parallel plots require just slightly more information than scatters for normalization purposes, the same dimension ranges that are required to draw axes. I moved the computation of the dimension ranges into a new model object to shift it out of the sceneplotview3d.

For (re)applying controller properties, we're just using a fromJson(toJson) serialization trick, and that seems to work well for small datasets, but something isn't scaling well at 20000+. Since all controllers get reapplied at the same time, there's also potentially overhead in state changes that get overridden, and the potential for inconsistent intermediate states while the controllers are being applied.

dhakim87 commented 4 years ago

We had a conversation on properly hooking up UIState with require.js and I don't want those thoughts to disappear:

The unit test framework runs multiple tests within the same instance of the application, and sharing a UIState between them complicates the unit test procedure. We should think about mechanisms to pass a separate UIState with each test, either by swapping the UIState for a mock object or by configuring require.js in some special way with each test.

The jupyter notebook configuration likely shares UIState objects between multiple instances within a single notebook. This needs to be handled appropriately before the PR goes in.

ElDeveloper commented 4 years ago

The jupyter notebook configuration likely shares UIState objects between multiple instances within a single notebook. This needs to be handled appropriately before the PR goes in.

Thanks for bringing this up, let's talk about this and see what can we do right now. It sounds like this will need to be a require-specific solution that we'll need to think about.

antgonza commented 4 years ago

@dhakim87, this is pretty nice; thank you for your help with this.

A couple of minor suggestions and a question:

ElDeveloper commented 4 years ago

Thanks so much @dhakim87!!! This is going to be awesome!