gt icon indicating copy to clipboard operation
gt copied to clipboard

Gg gt

Open thebioengineer opened this issue 3 years ago • 6 comments

Summary

Thank you for contributing to gt! To make this process easier for everyone, please explain the context and purpose of your contribution. Also, list the changes made to the existing code or documentation.

This PR adds "as_grob" to gt. This allows converting a gt table to a native grob. preserving a lot of the aesthetics that are found in html. The benefit is that now the table could be saved directly as a png, without having to round-trip through webshot2.

additionally, this solves #961, making it work nicely with patchwork and cowplot.

More testing and features may be needed to add parity to html functionality, but it does a good chunk at this point.

Related GitHub Issues and PRs

  • Ref: #961

Checklist

thebioengineer avatar Aug 18 '22 19:08 thebioengineer

Related also to this issue in patchwork: #thomasp85/patchwork/issues/203 @thomasp85 - I do have some questions about how we could get it to potentially do add information to allow the table to alignment with axis lables in a ggplot, but for now this seems to get the job done.

@jthomasmock - tagging for knowledge

thebioengineer avatar Aug 18 '22 22:08 thebioengineer

Realized there is no documentation. The new function is 'as_grob', call it on a gt table and it will be converted.

Still some to-dos exist, like making footnotes and supporting in-cell ggplots

thebioengineer avatar Aug 19 '22 05:08 thebioengineer

Amazing - I was planning on haggling this in the autumn so this PR is a blessing

Let me have a deeper look at the PR and see if I can suggest ways to align with ticks but I'm afraid it won't be easy (or at least non-hacky)

thomasp85 avatar Aug 19 '22 05:08 thomasp85

Good to hear that it this could be helpful for you, @thomasp85. Yeah, any help is appreciated, my experience with grid is pretty limited, so I did a lot of guess/check when making this and trying to make reasonable decisions. If you have any questions on what and why I did something happy to talk more.

thebioengineer avatar Aug 19 '22 13:08 thebioengineer

I've read through the code somewhat, but I'm not deeply familiar with gt at the moments so some of the comments might not make sense.

I think I find the order of operations a bit awkward compared to how I would have chosen to implement it but again there might be very valid reasons for this - would it be possible for you to outline the rendering process a bit with words etc to inform me of your thoughts...

To give an example I think I would naively start by creating a grob of every cell and placing it in a matrix, and then, based on that matrix resolve the width and height of each column and row respectively, then afterwards add surrounding elements to the body of the table...

thomasp85 avatar Sep 06 '22 09:09 thomasp85

Thanks for your comments, @thomasp85. They are well taken, and I can add some comments/information around.

I think I find the order of operations a bit awkward compared to how I would have chosen to implement it but again there might be very valid reasons for this - would it be possible for you to outline the rendering process a bit with words etc to inform me of your thoughts...

A lot of what the code is doing is based on how other gt output renderers work. Which is sections of the table are created and then put together into the final output. I liked this approach when I helped with word output, so I kept it here to try to keep it consistent.

The base function behind a lot of this on the creation of the table is the table_cell_grob - which takes in text, and a variety of descriptions of the cell (text, font, background color, text color, column and row spans, etc). This should have most of the things we are looking for. Then we iterate over the gt_tbl sections to create the content to be added. First, the "header" gets created (title & subtitle), then the column labels (including row spans), the body of the table, footer, then finally source notes.

Once we have all the table components (which are contained inside lists), we construct the gtable to slot in the grobs into. I do a quick search across the incoming grobs to define for each row what the tallest grob will be and for each column the widest and set gtable dimensions to that. I determine height based on the text rows in the cell, and width based on the maximum number of characters in a text row. As you pointed out above, we could extract the grob dims, I just didnt know we could or how.

Finally I insert the grobs into the gtable entries based on their set column, row, and spans(if any).

Based on your comment, we had a similar thought on constructing a grob for every cell, but the rest is shaped based on trying to be consistent with how other rendering functions behave and the builder/helper functions from gt.

thebioengineer avatar Sep 06 '22 16:09 thebioengineer

Thanks for the contribution here but going to close the PR as we have this feature now with https://github.com/rstudio/gt/pull/1563.

rich-iannone avatar May 18 '24 19:05 rich-iannone