-
Notifications
You must be signed in to change notification settings - Fork 10
Upset plot, svg/charting overhaul #55
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
Conversation
❌ Deploy Preview for molevolvr failed.
|
|
Hey @vincerubinetti, nice work on this; it's a pretty ambitious refactor and IMHO makes common functionality a lot more streamlined for these components. I did a little bit of testing both on the Netlify preview and running the frontend locally. All the testes were on my M1 Macbook running OS X 15.5 ("Sequoia") with the following browsers:
I ran into a few issues during testing, mostly with saving charts as PDFs, specifically:
|
|
@vincerubinetti: Also, would it be possible to seed the RNG via a querystring parameter? It'd help to reproduce specific issues. It'd be nice if the current RNG seed were displayed on the page somewhere for copying, too, like the "Fake Analysis ID" near the top. You might even consider making it a link with the seed included for the parameter. No worries if this is difficult, but I thought I'd ask. It is cool that it uses random data, by the way. |
|
Will look into those bugs today. Seeded random shouldn't be too difficult and will help for debugging the testbed. |
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 code looks much improved from before; I can see that centralizing the charting functionality in the Chart component reduces a lot of duplicated effort across the rest of the charting components, so kudos for that.
I made a comment on the PR about some PDF issues I ran into during testing. I'm wondering if they're side effects of the DOM being changed due to the swapping to a portal containing just the element for printing (that I had just said were a good idea...)
If you need additional evidence of the bugs, I can make screen recordings and post them to the PR; just let me know.
|
Thanks for the in-depth testing and review. I hope that this is the last large scale refactor I have to do, and the experimentation I did makes me confident that this is a good way to construct custom general-purpose SVG charts in the future.
Added.
Re-added.
Fixed.
Fixed. It had something to do with the fact that I was passing the I fixed it by providing a "manual" callback ref like so: ref={(el) => {
containerRef.current = el;
return () => {
containerRef.current = null;
};
}}But it was my understanding that this was exactly what I also saw that moving all the print code and state from
I couldn't replicate this, but I have a feeling it might have been fixed by the fix above.
Looks like this is occurring in the current Unfortunately, setting |
Not sure what to do about this. At the moment, Though, the APIs of these two libraries are very similar, so it should be easy to switch, so I'll try switching and see if it helps. Also luckily for us, FF is the least popular browser of the three major ones (behind Chrome and Safari). |
I can't seem to replicate this in Chrome, all of the charts appear page-centered for me. Are you using any custom settings in the print dialog?
I was able to fix this by just moving the print controlling to the chart component itself, as I discussed above in the "callback ref" stuff. I've never seen the pattern that I was doing (assigning a component to a var with refs, and passing that component to another component as a prop to be rendered in a portal), so it's probably best to just avoid it. I imagine the error has something to do with the the order in which ref inits and cleanups are being called (or not called at all), and keeping it all in the same component fixes that. With this change, don't need the ref callbacks at all. It's a shame I can't keep this code in the Download component to keep it general, but perhaps it's better anyway as if I'm trying to print something besides a chart, it might require different behavior or print styles anyway.
I can't replicate this. Could you provide more detail? Maybe the latest commit fixed it? Could you try hard refreshing to make extra sure your browser isn't using old js?
Created #58 to track.
It appears the only hint we can give the browser for the filename is the document title. So I've added some lines to set the title to match the filename of the other downloads, then revert it to the original title after printing. Also I'm seeing Firefox also give the document title as the filename, not "blank". |
|
Note regarding the failures: https://status.npmjs.org/ |
|
I thought I'd refreshed the browser, but maybe not! In any case, whether it's a combination of your commits or that, it looks like the issues I had reported are all fixed: all the figures are centered in the PDF now, the IPR sequence no longer extends past its parent frame, and the PDFs are saving with appropriate names in both Chrome and Firefox. I'm also unable to replicate that issue I was seeing where the other export formats wouldn't work after using the PDF one, so I'll assume that's fixed, too. Just for completeness' sake, this is what I had observed in Chrome:
Anyway, it appears to be fixed now, and I haven't encountered any other issues aside from the known Firefox one with PNGs and JPEGs. Nice work! |
|
I'll wait until NPM is back up before merging, as the new app wont be able to build and deploy properly until then anyway. |



Unfortunately this became a big PR because everything here was intertwined, and I wanted to (hopefully) solve all these related issues permanently. So, the diff is very big and difficult to review, and the individual commits won't be very clean or helpful. Instead I will mark certain parts of the code to look at. And know that converting the old SVGs to use the new chart wrapper component involved a lot of copy-pasting large blocks of code. Most importantly, please re-test every visualization component on the Netlify preview.
At a high level, here are the changes:
If you poke through the commit history, you can see some of the many complicated approaches I experimented with for handling sizing and positioning in the SVGs.
I wanted to scale the SVG shapes up/down based on the available width but keep the font size matching the document's. This was already sort of implemented before this PR, where the viz components made repeated use of a useSvgTransform hook. But it was verbose, so I first attempted to extract it out to a single hook, and then a component. It required iteratively content-fitting and font-sizing back and forth, which would (usually) converge to a stable configuration. But it was very difficult to find a foolproof way to prevent infinite re-renders or weird edge cases. I also tried leveraging simply defining font size in the root of the SVG that matched the document's, then specifying positions/sizes in terms of
emunits, which the browser could use synchronously with no JS. But there are some limitations to this, like not being able to use relative units in things liketransforms, and some weird exceptions that caused runaway calculations like when anem-sized element exceeded the available width of the container. Trying to implement automatic text truncation made this even more complicated.The MSA & IPR viz's also required a "fill remaining space" feature, i.e. have a column of labels on the left of a fixed width, and use all the remaining space on the right for the tracks/sequences. Another small problem to solve was that
getBBox, the method used for fitting the view box to the SVG contents, doesn't work withclip-path'ed elements, which is needed for IPR's zoom area.There's much more that I tried or thought about and didn't commit, which has already left my brain, but I think it's not that valuable.
What I landed on keeps things much simpler. The SVG units always match the DOM units, no exception (hopefully). If there isn't enough room on the page to show the SVG's content, instead of trying to shrink dynamically, it will just overflow and show scrollbars. Not only does this avoid needing iterative fitting, it's probably better UX wise since graphical elements stay in the same position and size -- instead of shrinking to an unreadable size -- and you just need to scroll over to see it all. Also this makes the testbed page much more performant. The "fill remaining" feature is accomplished by providing the available width to the consuming component, and letting it use it however it wants.
Regarding the MSA auto-wrapping, currently the code is basically:
This is just a loose, hard-coded wrapping point that would generally not overflow the page width when printing portrait mode, US letter.
This PR doesn't change our inability to look inside the print dialog, as discussed in #50 and this comment. But I've taken out the hard-coded
40. I figure now with the resize handle available on every chart, the user can pre-size the chart to whatever they want before opening the print dialog.I wanted to mention this because, if you look at the preview on a normal desktop or laptop screen width and have your print dialog on defaults, you'll usually see the MSA overflow the page, and I'm aware of it.