Skip to content

Svg corrections #555

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

Merged
merged 4 commits into from
May 5, 2020
Merged

Svg corrections #555

merged 4 commits into from
May 5, 2020

Conversation

hyanwong
Copy link
Member

Fixes #467 . I have left it as 3 separate commits in case these should be separated out, as they do different but related (and dependent) things.

@hyanwong
Copy link
Member Author

No tests added, but there were none in this area before, either, AFAIK.

@hyanwong
Copy link
Member Author

By the way, I haven't done as @jeromekelleher suggested and "put the id(ts) as prefix to all the values", because it is perfectly possible that someone might try to draw the same tree (or tree sequence) in a notebook but with different parameters, e.g. for height and width. We need an id for the trees in a svg tree sequence, because the id is used to position the tree along the x-axis. But if we use IDs that are the same for a given tree seq then we hit the same problem of duplicate SVG ids for what should be different drawings.

Instead, I have a small function to generate a (pretty much) unique UID suffix for the trees in a ts. I could increase the number of characters in the UID, but at the moment it generates one of ~10^14 possible identifiers, so I think the chances of clashing are low.

We needn't worry about the obscureness of the notation, I think, as it's an internal thing only. If we want to target a particular SVG drawing (tree or tree sequence) my new svg_id parameter allows a user-defined id to be passed in, which is then a handle to the correct image.

Ping @benjeffery as I think he knows about this stuff.

@codecov
Copy link

codecov bot commented Apr 24, 2020

Codecov Report

Merging #555 into master will increase coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #555      +/-   ##
==========================================
+ Coverage   87.29%   87.31%   +0.01%     
==========================================
  Files          21       21              
  Lines       16484    16502      +18     
  Branches     3237     3242       +5     
==========================================
+ Hits        14389    14408      +19     
  Misses       1029     1029              
+ Partials     1066     1065       -1     
Flag Coverage Δ
#c_tests 88.49% <100.00%> (+0.02%) ⬆️
#python_c_tests 90.40% <100.00%> (+0.03%) ⬆️
#python_tests 99.24% <100.00%> (+0.03%) ⬆️
Impacted Files Coverage Δ
python/tskit/drawing.py 99.82% <100.00%> (+0.18%) ⬆️
python/tskit/trees.py 98.66% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 48ed653...bb295af. Read the comment docs.

@hyanwong
Copy link
Member Author

Just modified the last commit so that we are guaranteed all svg tree ids in a TS are unique. Overkill, but hey...

@hyanwong
Copy link
Member Author

I'm being stupid here. If we place the trees in a drawn tree sequence in their own group, rather than using SVG <def>s, then we don't need a unique ID at all for each tree, and can get rid of all that messy UID stuff. This is much more sensible, as we aren't reusing the tree plots anyway (which is the point of <def>). So I've re-written the last commit to remove any need for IDs at all. I've checked and this does solve #467

@petrelharp
Copy link
Contributor

Oh good! That makes much more sense.

@hyanwong
Copy link
Member Author

While I'm on it, I would also like to be able to rotate the text labels by 90 degrees (see #26). It would be nice to allow this by simply changing the CSS, but it turns out to be a little complex (see here). The simplest solution would be to wrap all text elements in a <g> tag, so for each label, rather than outputting

<text class="n14" x="70.15" y="129.62">14</text>

we would use the more verbose

<g transform="translate(70.15 129.62)"><text class="n14">14</text></g>

But then we could style specific types of labels with e.g.

.labels .nodes .sample text {transform:rotate(90deg)}

I think the extra size in the svg is probably worth it. Opinions @benjeffery / @jeromekelleher ?

Copy link
Member

@jeromekelleher jeromekelleher left a comment

Choose a reason for hiding this comment

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

This is great, thanks @hyanwong!

Re testing, you're right there wasn't really any, but I think we should add some to verify the class structure of the output. We should be able to do this by parsing the XML output. We can put this into the verify_basic_svg function, and therefore not have to add any new tests.

The docs look great, but they're in the wrong place.

I've asked @benjeffery for a review - I'll leave it between the two of you to finish this one out as you both know more about this than I do.

@jeromekelleher
Copy link
Member

I think the extra size in the svg is probably worth it. Opinions @benjeffery / @jeromekelleher ?

I don't think we need to worry too much about SVG size. If we have a useful feature we want, and it needs less than quadratic space then I say we add it.

@jeromekelleher
Copy link
Member

Also, can you update the CHANGELOG to highlight this new feature (& bugfix)?

@benjeffery
Copy link
Member

<g> are generally a good thing in SVG. I wouldn't worry about adding them. For example when doing animations changes to <g> generally give a much better frame rate than other elements.

Also def needs tests. At a bare minimum comparing the raw html string output to known good. This lets us update deps etc. with confidence.

@hyanwong
Copy link
Member Author

<g> are generally a good thing in SVG. I wouldn't worry about adding them. For example when doing animations changes to <g> generally give a much better frame rate than other elements.

I agree. Do you want me to add the <g> on text as a separate PR, or roll it into this one?

Also def needs tests. At a bare minimum comparing the raw html string output to known good. This lets us update deps etc. with confidence.

happy to add a known string test. Will start coding that up now.

@benjeffery
Copy link
Member

benjeffery commented Apr 27, 2020

happy to add a known string test. Will start coding that up now.

Parsing the XML is much better as it ignores whitespace and attribute changes.
Using xmlunittest is an option:

from xmlunittest import XmlTestCase
class TestSVG(XmlTestCase):
    test_case.assertXmlEquivalentOutputs(xml_string, expected_xml_string)

hyanwong added a commit to hyanwong/tskit that referenced this pull request Apr 28, 2020
hyanwong added a commit to hyanwong/tskit that referenced this pull request Apr 28, 2020
@hyanwong hyanwong force-pushed the svg-corrections branch 2 times, most recently from 01a6503 to 02778c4 Compare April 28, 2020 17:43
@hyanwong
Copy link
Member Author

@benjeffery I think this is ready to review. It seems to be failing appveyor because the appveyor config is not reading requirements/CI/requirements.txt and so is not installing xmlunittest. Not sure why Appveyor is set up like this: do you know, and also how to fix it?

@benjeffery
Copy link
Member

@hyanwong Appveyor installs from python\requirements\conda-minimal.txt

@hyanwong
Copy link
Member Author

hyanwong commented May 1, 2020

I'm also hesitant about documenting the exact pixel-sizes of the layouts,

Are we committing to keeping those sizes though? Could we not say “Currently the defaults are xxx but this may be subject to change in future releases”?

@jeromekelleher
Copy link
Member

Are we committing to keeping those sizes though? Could we not say “Currently the defaults are xxx but this may be subject to change in future releases”?

No, but documentation like this has a nasty habit of going out of date because we forget about it. I wouldn't put in any details that we aren't confident are stable. It's not an important detail that users need to know.

@hyanwong hyanwong force-pushed the svg-corrections branch 2 times, most recently from 21fd658 to 73ea88b Compare May 1, 2020 18:55
@hyanwong
Copy link
Member Author

hyanwong commented May 1, 2020

This is all done. If you are happy @jeromekelleher and @benjeffery, I'll squash the last commit which addresses the last concerns into the one before it, check if it needs rebaseing, and then someone can merge.

@benjeffery
Copy link
Member

A thought on customising I had today (not for this PR) - one way to do it would be to have callback params that allow functions to be specified that return HTML for nodes and edges etc. The callback would be called with the node/edge/mutation data and the default HTML entity. The callback then either makes a new HTML entity, or modifies the default and returns it.

@hyanwong hyanwong force-pushed the svg-corrections branch from 73ea88b to 7e0fbcf Compare May 2, 2020 18:05
@hyanwong hyanwong mentioned this pull request May 2, 2020
@hyanwong
Copy link
Member Author

hyanwong commented May 2, 2020

An observation that any styling passed in to one SVG on a Jupyter notebook will affect all the trees in the notebook (as per a comment I saw: "scoped CSS has been removed from the specs, so any <style> tags in the document will be hoisted to the global scope"). The only way to stop this is to given an ID to the SVG and target the style at that SVG. We should probably give an example of this in the docs, as it's a bit unexpected to the uninitiated.

@benjeffery
Copy link
Member

@hyanwong A quick added sentence on the style param docs should do it.

@jeromekelleher
Copy link
Member

This is great, thanks @hyanwong, let's get this one merged in ASAP. Looks like we're basically there.

@benjeffery
Copy link
Member

Yep, think it is just the doc mention of style hoisting.

hyanwong added a commit to hyanwong/tskit that referenced this pull request May 4, 2020
@hyanwong hyanwong force-pushed the svg-corrections branch from 7e0fbcf to 9f17dc8 Compare May 4, 2020 10:58
@hyanwong
Copy link
Member Author

hyanwong commented May 4, 2020

Added note about styles and squashed the PR changes into the last commit. Should be OK to merge I guess @benjeffery

hyanwong added 3 commits May 5, 2020 22:27
…dd classes

Fixes tskit-dev#467

This changes class names to use simple ids, and documents the class structure

As described in tskit-dev#467 (comment)

Placing trees in a ts using groups emoves the need for any IDs
@hyanwong hyanwong force-pushed the svg-corrections branch from 9f17dc8 to 95438a1 Compare May 5, 2020 21:29
@hyanwong hyanwong force-pushed the svg-corrections branch from 95438a1 to bb295af Compare May 5, 2020 21:52
@benjeffery
Copy link
Member

@hyanwong I see you've just made some changes, is this ready for a once over as am keen to merge this so the others can proceed?

@hyanwong
Copy link
Member Author

hyanwong commented May 5, 2020

It was probably accidental. I did squash the last PR corrections into the previous commit, but it should otherwise be the same. I think I'm confused as to what I did. Can you pinpoint any changes?

@hyanwong
Copy link
Member Author

hyanwong commented May 5, 2020

It's frustrating working on 5 interrelated PRs at once. Especially as I can't always do them on the same computer at the moment. So I never remember which local branches are pushed, etc etc. I think I've whinged to you before that I can't really get git to suit my workflow (which tends to be to not complete anything if I can see something shiny elsewhere)

@hyanwong
Copy link
Member Author

hyanwong commented May 5, 2020

@benjeffery it's definitely ready for a final look, and hopefully a merge, though. I did have to rebase too, as Daniel & Sunack's changes went in before this was sorted.

@benjeffery
Copy link
Member

benjeffery commented May 5, 2020

Ok, I'll give it the once over. Are you happy for me to make any small changes myself as might be late by the time I am done? (will leave anything big till the morning, although don't expect there to be anything big at all!)

Lets talk about git workflow on a call - would be good if we can make this easier for you.

@benjeffery benjeffery merged commit ea37280 into tskit-dev:master May 5, 2020
@hyanwong
Copy link
Member Author

hyanwong commented May 6, 2020

Wow, you're working late. I had gone to bed. Sorry! Thanks for merging

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SVG IDs not unique and being cached by Jupyter
4 participants