vega / vega-lite

A concise grammar of interactive graphics, built on Vega.
https://vega.github.io/vega-lite/
BSD 3-Clause "New" or "Revised" License
4.7k stars 618 forks source link

Introduce macro/composite mark for creating tables #8063

Open joelostblom opened 2 years ago

joelostblom commented 2 years ago

I think it would be quite useful with a mark_table to quickly create tables in Vega-Lite. I often do this myself to troubleshoot complex transforms, where I want the intermediate output to be printed so that I understand what is going on. It can also be useful to display on its own, or together with filtering on another chart.

I think a sensible default would be to include all columns in the data, with a parameter to reduce the selection, e.g. mark_table(table_columns=['col1', 'col2'). I have found a few different ways tables could be created with Vega-Lite, that could be called when this composite mark is used:

Using repeat

The issue here is the spacing between the columns (due to https://github.com/vega/vega-lite/issues/8062) and that I am not aware of an easy way to show the column names on top:

image Open the Chart in the Vega Editor

Using facet

While the spacing between charts/table columns can be adjusted here (both via spacing and resolve_scale(x='independent'), I am not aware of a way to automatically adjust to the width of the column/header name:

image Open the Chart in the Vega Editor

Using hconcat

This is the visually most pleasing option, but it would involve a loop outside the Vega-Lite spec to create the charts that are to be concatenated:

image Open the Chart in the Vega Editor


One complications is making this mark work together with selections in a chart as in this example. The reason is that there needs to be a filter transform with the selection and a window transform injected before the transform that limits the number of rows displayed in the table by default. One workaround could be to not limit the number of rows as a default but that takes away much of the convenience of this function since it now requires the user to manually write out the two transforms to display less than the max number of rows (and displaying all rows is rarely desired).

joelostblom commented 1 year ago

Using an encoding

This article has an interesting suggestion for how to make a table. Slightly modified spec here: Open the Chart in the Vega Editor. Unfortunately this still suffers from the issue of each column having the same width rather than optimized based on the length of the column name.

PBI-David commented 1 year ago

Joel - I use a technique where I transparently add all the text marks to the origin point and find the max length in pixels using a bounds calculation. I can then use this information to either size a container or restrict the text to the size of the bounds. I did exactly this to ensure text never overlapped a bubble in the bubble chart below. I use this technique all the time but perhaps someone has found a better way of doing this. You can definitely use this technique to size your columns though.

Editor

image

joelostblom commented 1 year ago

Thank you so much for sharing @PBI-David ! I had a look at your example but couldn't quite figure out how it would apply in creating the tables. The two table-approaches where it would be helpful to have an auto-adjustment based on column name length would be in either of the following two:

Even with your calculation I am a bit lost of how to apply the calculated value to the individual facets / x-axis items.

PBI-David commented 1 year ago

Apologies Joel - I thought this was a Vega issue rather than VL. My approach relies on reactive geometry. I don't think VL supports reactive geometry, does it?

I'm happy to provide a minimum reproducible example in Vega if it helps craft a VL solution under the covers?

I use this technique all the time to ensure text never overflows a container (like the bubbles) OR to size a container to the text length (like your table example). My Sankey below (Vega again) ensures the labels always have a nice white background container sized exactly to the length of the text mark.

Editor

image

dhirschfeld commented 1 year ago

I think having a mark_table convenience function would add a huge amount of value for a lot of users.

PBI-David commented 9 months ago

@joelostblom I previously thought reactive geometry was not possible in VL but here is an implementation showing dynamically truncated text: https://stackoverflow.com/questions/78123330/vega-lite-dynamic-label-width-reactive-geometry/78123803

jwadelauer commented 8 months ago

The implementation of this by Hex is very good. Would love something similar in vega-lite natively

image

https://learn.hex.tech/docs/explore-data/cells/transform-cells/pivot-cells