-
Notifications
You must be signed in to change notification settings - Fork 31
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
Improve draw #400
Improve draw #400
Conversation
Ports the three test cases we had for the rectangular layout
(wasn't getting used anywhere. why was i keeping track of this lol)
Progress on biocore#184. Since it looks like the unrooted layout handles these properly, all that's left for this issue should be just not drawing arcs for internal nodes with 1 child. Should be doable by modifying the js circular layout to give 1-child nodes -1 for their arc / angle values or something to signal to empress.js to not bother with arcs.
related to biocore#271, but needs extending to other layouts
I was having precision issues with the circular layout scaling (tldr: Math.cos(Math.PI / 2) is very close to but not quite 0, so it was messing up the max / min X computation), but this makes it so we shouldn't have to even worry about things for this case.
Close to making sure biocore#184 is done :)
Gonna say that this closes biocore#184.
Closes biocore#184! I forget if i already did that so i'm doing it again.
The following artifacts were built for this PR: empire-biplot.qzv, empire.qzv, empress-tree.qzv, just-fm.qzv, plain.qzv |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks cool, thanks for getting this ready!
Read over things, and I have a few suggestions. I think the most important are:
-
The structure of the
getTreeCoords
/getTreeColor
functions in empress.js -- would it be possible to merge these back into a single function, maybe by adding a parameter that controls whether it returns colors or coordinates? I think duplicating this logic will cause some problems (although I understand that it's already kinda duplicated betweengetCoords
andthickenColoredNodes
now, though). -
Use of 256 as the "base" for the compressed colors -- since hex colors range from [0, 255], I think we should use 255 instead.
Also, I am not sure what is causing it, but it looks like there is a strange bug when turning off collapsed clades where the colors become broken and some nodes remain hidden. My guess is that this might be a problem with getTreeCoords
and getTreeColor
getting out of sync, but I'm not confident about that.
Co-authored-by: Marcus Fedarko <[email protected]>
Thanks @fedarko for the feedback. I believe all of your comments have been addressed. A couple of things:
I think this should get moved to a different PR. We already have multiple functions that use the same pattern so, creating a single function will require a bit of restructuring that I is a bit outside of the scope of this PR. |
good catch @fedarko! It should be fixed now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't gone through all of the export util / empress stuff yet, but have gone through about everything else. Have a few mostly small comments. This is looking great, thanks so much!!!
@@ -119,7 +123,7 @@ define(["underscore", "chroma"], function (_, chroma) { | |||
|
|||
// create a circle for each node | |||
if (drawer.showTreeNodes) { | |||
radius = drawer.NODE_CIRCLE_DIAMETER / 2; | |||
var radius = drawer.NODE_CIRCLE_DIAMETER; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the var
is needed :), but I think we should still divide this by 2 right?
... I guess it doesn't matter too much since the "units" are kind of arbitrary, but idk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The circles were not really visible when we divide by 2 (at least on my monitor with the moving pictures data set)
Linked are two svg. One that divides the diameter by 2 and one that does not. Let me know which one looks better - it could just be my monitor :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the examples! It's subjective, but I think keeping the division by 2 looks slightly better, so I think we should stick with that for right now. It does make it harder to see node circles when zoomed out, but things look less cluttered when the SVGs are zoomed in (... at least on my computer :) --
Neither solution is great, honestly, since the size of node circles isn't proportional to the tree size or anything. We should ideally try to scale node circles based on the tree dimensions, similarly to the stuff for edge thicknesses described in #276.
Co-authored-by: Marcus Fedarko <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks good! (And sorry for taking a few days to get back to you on this.) The bulk of this is basically ready as is, but there are some documentation / internal code things I think we should sort out first.
Besides the comments I made here, there are a few places with old documentation saying "RGB arrays" instead of RGB floats, including:
Part of Empress.colorSampleGroups()
:
empress/empress/support_files/js/empress.js
Lines 1926 to 1927 in aaac6e3
// convert hex string to rgb array | |
var rgb = Colorer.hex2RGB(group); |
Collapsed clade data:
empress/empress/support_files/js/empress.js
Line 310 in aaac6e3
* color: <[r,g,b]> |
Part of Empress._colorTree()
:
empress/empress/support_files/js/empress.js
Lines 2206 to 2211 in aaac6e3
* @param{Object} cm Maps categories to the colors to color their nodes | |
* with. Colors should be represented as RGB arrays, for | |
* example as is done in the color values of the output | |
* of Colorer.getMapRGB(). | |
*/ | |
Empress.prototype._colorTree = function (obs, cm) { |
Part of BarplotLayer.initFMDiv()
:
empress/empress/support_files/js/barplot-layer.js
Lines 246 to 250 in aaac6e3
// To my knowledge, there isn't a straightforward way of | |
// getting an RGB array out of the "TinyColor" values passed in | |
// by Spectrum: see | |
// https://bgrins.github.io/spectrum#details-acceptedColorInputs | |
scope.defaultColor = Colorer.hex2RGB(newColor.toHexString()); |
The border color stuff in the barplot panel handler:
empress/empress/support_files/js/barplot-panel-handler.js
Lines 139 to 140 in aaac6e3
// Borders (when enabled) default to white. (This is an RGB array.) | |
this.borderColor = [1, 1, 1]; |
empress/empress/support_files/js/barplot-panel-handler.js
Lines 267 to 284 in aaac6e3
// this.borderColor is always a RGB array, for the sake of everyone's | |
// sanity. However, spectrum requires that the specified color is a hex | |
// string: so we have to convert it to hex first here (only to later | |
// convert it back to RGB on change events). Eesh! | |
// A SILLY NOTE: Apparently chroma.gl() modifies the input RGB array if | |
// you pass it in directly, converting it into a weird thing that | |
// is represented in the browser console as "(4) [255, 255, 255, | |
// undefined, _clipped: false, _unclipped: Array(3)]". Unpacking the | |
// input array using ... (as done here with this.borderColor) seems to | |
// avoid this problem. | |
var startingColor = chroma.gl(...this.borderColor).hex(); | |
$(this.borderColorPicker).spectrum({ | |
color: startingColor, | |
change: function (newColor) { | |
scope.borderColor = Colorer.hex2RGB(newColor.toHexString()); | |
}, | |
}); |
empress/empress/support_files/js/empress.js
Lines 1840 to 1855 in aaac6e3
var borderColor = this._barplotPanel.borderColor; | |
var borderLength = this._barplotPanel.borderLength; | |
var maxD = prevLayerMaxD + borderLength; | |
// TODO: Should be changed when the ability to change the background | |
// color is added. Basically, we get a "freebie" if the border color | |
// matches the background color, and we don't need to draw anything -- | |
// we can just increase the displacement and leave it at that. | |
// (This works out very well if this is the "outermost" border -- then | |
// we really don't need to do anything.) | |
if ( | |
borderColor[0] === 1 && | |
borderColor[1] === 1 && | |
borderColor[2] === 1 | |
) { | |
return maxD; | |
} |
I haven't gone extremely thoroughly through things yet, so there may be additional places throughout the code/docs which exhibit this problem.
None of these are really urgent issues, since only one of them impacts the user directly, but I would like to try to fix as many of them as we can in advance (to avoid the master codebase having confusing docs).
For what it's worth the barplot panel handler stuff does very slightly impact the program behavior -- the "freebie" checking stuff should be changed to check if the border color is equal to exactly white (as a float), rather than the current behavior which still assumes that the color is stored as an RGB array. The consequence of this right now is that "freebies" are detected whenever the border color is unchanged (since it defaults to [1,1,1]), but even if the user changes the color and then changes it back to exactly white (16777215), no "freebie" is given since the checks still assume this is an array. This makes drawing barplot borders slower... albeit in this one, extremely tiny corner case :P
Anyway, hope this clarifies things. Happy to zoom sometime this week and go through these, or to just defer some of this work to a new issue if you'd prefer (since we have a lot of open PRs to get through). Thanks so much!
// So, if coords[node+2] == DEFAULT_COLOR then coords[node+2+5] will | ||
// also be equal to DEFAULT_COLOR. Thus, we can save checking three | ||
// array elements here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// So, if coords[node+2] == DEFAULT_COLOR then coords[node+2+5] will | |
// also be equal to DEFAULT_COLOR. Thus, we can save checking three | |
// array elements here. |
I think we'd need to update this comment about the colors
array -- honestly I'd be ok just removing this comment since I'm not sure if it's really applicable here.
@@ -313,6 +313,36 @@ define(["chroma", "underscore", "util"], function (chroma, _, util) { | |||
return _.mapObject(this.__valueToColor, Colorer.hex2RGB); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't comment on it directly (??? github is weird), but the docs comment for getMapRGB
should be updated to mention that the colors are RGB floats not arrays
…ength legends; export collapsed clade shapes and barplots (#392) * ENH: support collecting+exporting barplot legends * BUG: Fix legend SVG title centering; <g> => <svg> Also added a newline after </style> * BUG: Improve legend SVG for SVG importers -Use "long form" font specification for the style SVG (fixes problems with GIMP and Inkscape) -Put the style code higher up in the output legend SVG -- has the effect of applying the rect stroke to the topmost legend rect, which was a problem in Inkscape but not in chromium (:thonk:) -Add note about GIMP choking on dominant-baseline (tldr not worth worrying abt now i think) * STY: reorder/split up text and .title svg styles (the text styles are now across multiple lines) * MNT: hang on to continuous props in Legend for SVG similar to what we do for categorical export * ENH: add newlines to within gradient svgs make life less painful (tm) * MNT: abstract some code within legend export; grad svg work * MNT: Refactor colorer/legend handling of gradients Now, things are split up into a "Solo" and "HTML" SVG -- the gradient shown on the page is a combo of these, and the one we export is just the Solo one. This makes scaling it properly for the export SO MUCH EASIER AHH All we gotta do now is just add in value text and update rowsUsed / maxLineWidth. think that should be good? oh also this is gonna explode the tests ofc. that is a job for TOMORROW MARCUS (tm) * ENH: Finish? gradient legend SVG exporting! IT WORKS SO WELL AOGIHDSOIGHJ something worth noting: there seems to be some unaccounted-for horizontal padding on the right side in the cat legend export. i matched it in the continuous legend export b/c it looks nice but worth looking into...? * MNT: add explicit padding to right side of cat SVG it looks like things are the opposite from how i thought -- looks like the perceived extra space was just due to the boldfont used in estimating the texts (when you make the text bold it's almost snug with the border on the right side). may as well add the same padding as for the continuous legends so things look consistent ish. Still, this leaves it kinda unclear as to why continuous legends were so comparatively snug with the border until i added padding ... maybe boldface numbers are just not that bigger? idk UPDATE: yeah i checked it and bold numbers are basically the same size but bold letters are much larger. mystery solved :100: * ENH: initial support for exporting length legends looks not great (gotta align max and min headers like in table) but good enough tm * ENH: make exported length legend look purdy * STY: pret * ENH: export collapsed clade shapes! #303 Actually not that bad. wack. * ENH: draw full rectangle for unrooted collapsing removes line in the middle * ENH/STY: use stroke on svg triangles; prettify * MNT: also use stroke for unrooted clade export * DOC: document todos for clade collapsing export * ENH: support exporting barplots in SVG! Need to use paths for circular barplot curves, and maybe better stuff for rect barplots. but it works :D * Update readme re: #303 fixes :D * PERF: Only specify stroke width for thick lines since default is 1 * MNT: apply shape-rendering to SVG shoutouts to https://stackoverflow.com/a/53309814/10730311. this is very easy to configure (just a line in the svg header), so if users prefer different things we can document this. * MNT: make polygon exporting util func * MNT: attempt to fix bounding box stuff export is broken (height is somehow nan?) but at least this works now * STY: prettify * negate y coords and declare maxy in bb still broken but much less so * Space out adjacent polygon pts fixes things! hey this works now * PERF/BUG: don't even draw 0-length barplots previously they were showing up in the SVG, probs due to precision pbms. should beo k now * STY: prett * DOC: remove svg export disclaimer :D #303 * BUG: Fix #421 still gotta test, tho, which will likely need to be deferred until after fixing the other pbms with this pr and tests .______. * TST: fix a gradient svg test * specify combined svg * TST: split up test ref svgs by solo/html * TST: Fix most of the colorer tests * MNT: redo public attr stuff with a func approach is safer -- delegates checking that colorer is continuous to, well, colorer. * TST: unbreak colorer tests! * Say missing and/or not numeric in warning * TST: unbreak legend tests :D * STY: prettify tests * MNT: Drastically simplify legend exporting At least for cat legends -- no longer do we have to worry about rows and units and all that. each legend just returns its width and height, and that's all we care about. * STY: pret * UNBREAK CONTINUOUS LEGENDS :D * Fix length legends * ENH: show missing/nonnumeric warn in grad legends * DOC: fix some docs stuff * fix stats format * populateTreeStats fixes * STY: whoops * MNT: Move radius bb expansion to sep function addresses a comment from @kwcantrell * PERF: don't cache barplot buffer addresses @kwcantrell comment. Required breaking up the barplot drawing stuff into a separate function that returns the coords * BUG: fix reversed continuous color map legends tldr gotta reverse the stop colors. reason this worked _before_ was that it was accessing the interpolator to build up the stop colors * simplify grad svg code a bit * TST: test reverse color gradient bug is fixed * STY * MNT: Simplify gradient ID / suffix stuff Addresses @kwcantrell comment. * DOC: fix documentation stuff wrt #400
Thanks @ElDeveloper for pointing this out!
…menu; fix "Add" button (#432) * ENH: add BiomTable.hasFeatureID * Prevent errors+warn on tips not in table #314 * fix warn msg * tidy styling/stuff * Make int sample presence handle bad case&test #314 still gotta clean up tests, and actually integrate this into the selection menu, and etc. but a start. * tidy up #314 int test * child -> descendant tips in int sample presence * TST: beef up int sample presence tests * STY: prettifififify * Show warning for int nodes w/ all tips not in tbl Closes #314. However, the UI here could still be improved a lot! So gonna tidy things up a bit before getting this PR in. May knock out #272 while we're at it. * polish selected node menu a bit Still kinda broken, but I think i have an idea of how to fix it * TST: Add selected node menu test skeleton :D Because manually testing this is going to give me a stroke * TST: test a sel node menu error case; chg init'ing Didn't seem like there was much of a reason to keep initialize out of the selected node menu constructor, so just went ahead and moved it there. * TST/MNT: add + tidy up ssn tests; tidy err cases since the tip case is afaict literally impossible to test * More s.node menu tests; revamp HTML ._. not thrilled about doing this the brute force way but it works * beef up showNodeMenu tip test * rename SelectedNodeMenu.notes to .smNotes for clarity's sake, since .notes seems way more general than the actual purpose this element serves * beef up tip menu test * MNT: simplify showing/hiding HTML eles in S.N.Menu was getting tired of writing stuff out * TODOs for menu fixing #314 * STY * BUG: hide add ui eles after all sm fields added Closes #272. * Reorganize and restyle selection menu Not done yet (gotta move stuff around for SM), but this already makes the organization here clearer i think. Having FM and SM be separate clearly marked sections should make things easier to understand, since it will be very easy to say "oh this node has no feature metadata" or "oh this node isn't in the table" (#314). * STY: pret * MNT: take advantage of makeFMtable being nonstatic This makes calling this, and doing state-modifying stuff from within this function, so much less of a pain. not sure why i thought this would be a good idea back in june lmao * MNT; take advantage of sm table being nonstatic * some #314 esque menu fixes have things planned out, just gotta go through and refactor stuff * Refactor feature metadata in s.node menu * css todo * Refactor SM stuff :D Closes #314 for good, I think. Some bugs (#272 rears its head again) and i wanna test this, but this is already a big improvement * Fix #272 bug (...again.) ok this seems good. just gotta add tests and then pr should be ready * STY * TST: unbreak s. node menu tests * Simplify s. node menu js tests :D * TST: add an int node s node menu test * Apparently qunit is case sensitive wrt "teardown" :thinking: I can't believe I just spent like 15 minutes trying to debug this lmao * TST: test #272 case wound up being a surprisingly large pain. turns out the (main) reason was that we actually shouldn't have been creating a new selected node menu in the tests; we should've just used the test data's copy. Stuff was being initialized twice, so there were 6 (not 3) s.m. fields in the <select>, and i was tearing my hair out lmao * TST: test ambiguous internal node menu case * MNT/TST: simplify js test code * MNT/TST: abstract out fm table checking in snm tst * test sm table population * tidy up selected node menu code formatting * STY: appease jshint by declaring a var in scope WHOOPS * TST: test sm notes txt in one of the cases * checktips fix * Update now-outdated-due-to-#400 comment Thanks @ElDeveloper for pointing this out! * Update empress/support_files/js/select-node-menu.js Co-authored-by: Yoshiki Vázquez Baeza <[email protected]> * HACK: Fix adjacent sm/fm section border CSS thing YEEESH * ENH: Actually, nvm, ditch menu section borders But make things look a lot nicer -- e.g. show note in sm section when no columns selected, remove extraneous <br />, etc. * cats can have a little <hr />, as a treat * TST: unbreak select node menu tests ._. * STY: prettify test Co-authored-by: Yoshiki Vázquez Baeza <[email protected]>
@antgonza if you have some spare time, can you test this pr on one of your large trees? thanks