Tables

Use tables to display an interactive grid of data used in your visualization. Tables support commonly used operations like sorting, filtering, pagination and a variety of other customization options.

Basics

In its most simple form, the table() function will display the contents of the Data provided. For example, the following:

from inspect_viz import Data
from inspect_viz.table import table

penguins = Data.from_file("penguins.parquet")
table(penguins)

results in a table displaying all the columns and rows in the penguins dataset:

In addition to providing the base Data for the table, you may also select which columns are displayed:

from inspect_viz import Data
from inspect_viz.table import table

penguins = Data.from_file("penguins.parquet")
table(penguins, columns=[
    "species", 
    "island", 
    "sex", 
    "body_mass"])

Tables have a number of global options for configuring the behavior, but also have many options specific to one or more columns. To specify column level options, using the column function in the list of columns rather than simply passing the column name:

from inspect_viz import Data
from inspect_viz.table import column, table

penguins = Data.from_file("penguins.parquet")
table(penguins, columns=[
    column("species", align="center"), 
    "island", 
    "sex", 
    "body_mass"])

Size

By default, tables will have a height which matches the size of their content and a width which files their container (with a default maximum size of 500px). You can explicitly provide a height and width value in pixels for the table if you’d like the table to be a specific size:

from inspect_viz import Data
from inspect_viz.table import table

penguins = Data.from_file("penguins.parquet")
table(penguins, height=200, width=550)

You can use max_width to constrain the maximum width of the table in pixels. It will still attempt to fill its container, but it’s width will not exceed the max_width.

Columns

When providing column data for a table, you can provide a list of columns names from your Data to be displayed. You can also use the column function to provide additional options for each column. For example, to customize the string that is displayed in the header for the column, using the label option like:

from inspect_viz import Data
from inspect_viz.table import column, table

penguins = Data.from_file("penguins.parquet")
table(penguins, columns=[
    "species", 
    "island", 
    "sex", 
    column("body_mass", label="mass")])

Width

If no explicit column size is provided, the width of each column is an equal share of the available space. You can specify the width of columns either using an explicit pixel size:

from inspect_viz import Data
from inspect_viz.table import column, table

penguins = Data.from_file("penguins.parquet")
table(penguins, width=370, columns=[
    column("species", width=80), 
    column("island", width=100), 
    column("sex", width=70), 
    column("body_mass", width=100)])

or using flex for some or all of the columns. Flex sizing works by dividing the remaining space in the grid among all flex columns in proportion to their flex value.

from inspect_viz import Data
from inspect_viz.table import column, table

penguins = Data.from_file("penguins.parquet")
table(penguins, width=550, columns=[
    column("species", flex=1), 
    column("island", flex=1.2), 
    column("sex", width=70), 
    column("body_mass", flex=1)])

You can also use max_width to set a maximum width for a column or min_width to set a minimum width for a column. This will be used to provide caps on width when columns are being sized automatically using flex sizing.

Alignment

You can control the alignment of the values within each columns header and body using the align and header_align options. For example:

from inspect_viz import Data
from inspect_viz.table import column, table

penguins = Data.from_file("penguins.parquet")
table(penguins, columns=[
    column("species", align="center", header_align="center"), 
    column("island"), 
    column("sex"), 
    column("body_mass")])

Formatting

You can control the formatting of each cell’s value using the format option. The format option accepts a d3-format string for numeric values and a d3-time-format string for date values to define how the value will be formatted.

table(penguins, columns=[
    column("species"), 
    column("island"), 
    column("sex"), 
    column("body_mass", format=",.2f")])

Default formats for values are as follows:

type format
integer ','
number
float
',.2~f'
decimal ',.4~f'
date '%Y-%m-%d'
datetime
timestamp
'%Y-%m-%d %H:%M:%S'

Text Wrapping

You can control the text wrapping behavior of the values within each columns header and body using the wrap_text and header_wrap_text options. This is most frequently paired with auto_height to create rows with automatic heights which wrap text. For example:

table(penguins, columns=[
    column("species", auto_height=True, wrap_text=True), 
    column("island", flex=1.2), 
    column("sex", width=70), 
    column("body_mass", flex=1)])

Rows

Height

By default, each row of the the table, including the header row, is 29px tall. You can set an explicit row size for the body of the table using the row_height argument. Set the header’s row height using the header_height argument:

from inspect_viz import Data
from inspect_viz.table import table

penguins = Data.from_file("penguins.parquet")
table(penguins, header_height=60, row_height=50)

Auto Height

In addition to explicitly providing the heights for rows, you can also allow the content to determine the height of the row. To do this, configure one or more column with auto_height. The height of the row will then be determined using the largest height required to display the content of any columns with the auto_height option.

table(penguins, width=550, columns=[
    column("species", flex=1), 
    column("island", flex=1.2, auto_height=True), 
    column("sex", width=70), 
    column("body_mass", flex=1)])

You can also use the header_auto_height option to specify columns that will automatically size the header row height.

Sorting

Each column in the table is sortable by clicking on the header for the column you’d like to sort. Each click toggles between the sorting ascending, sorting descending, and not sorting. Holding shift while clicking will add the clicked column as a secondary sort, preserving any other sorts that have already been specified.

You can disable sorting for the entire table using the sorting argument:

table(penguins, sorting=False)

You can control whether individual columns can be sorted using the sortable option for column:

table(penguins, columns=[
    column("species", sortable=False), 
    column("island"), 
    column("sex"), 
    column("body_mass")])

Filtering

Each column of the table is filterable by clicking the filter icon in the header of the column. Depending upon the type of data in the column, different filtering options will be presented to the user. To disable filtering for a table, use filtering:

table(penguins, filtering=False)

You can control whether individual columns can be filtered using the filterable option for column:

table(penguins, columns=[
    column("species", filterable=False), 
    column("island"), 
    column("sex"), 
    column("body_mass")])

Filter Location

You can control where in the table filters appear by passing other header or row as the value for filter. header places in the filter as buttons in the header row next to the header text. row creates` a separate row with inline filter UI for filtering columns. For example:

table(penguins, filtering='row')

Resizing

Each column of the table may be resized by the user by clicking and dragging the separator between columns in the header row. To make the table columns not resizable, use the resizing option:

table(penguins, resizing=False)

You can control whether individual columns can be resized using the resizable option for column:

table(penguins, columns=[
    column("species", resizable=False), 
    column("island"), 
    column("sex"), 
    column("body_mass")])

Pagination

When configured, tables can display pages of items with pagination controls at the bottom of the table rather than display all the items in a scrollable body. To enable pagination, simply provide the pagination argument to the table:

from inspect_viz.table import column, table
table(penguins, 
      columns=[
        column("species"), 
        column("island"), 
        column("sex"), 
        column("body_mass")],
      pagination=True)

By default, the table will automatically set the page size to use the available space in the table without scrolling. You can also explicitly choose page size and page size options:

from inspect_viz.table import column, table, Pagination
table(penguins, 
      columns=[
        column("species"), 
        column("island"), 
        column("sex"), 
        column("body_mass")],
      pagination=Pagination(page_size=20, page_size_selector=[20,40,60]))

Grouping

When displaying tabular data, it can be useful to group the data by specific fields. For example, to display a table with the average attributes of male and female penguins based upon their species, you can using grouping function for some columns:

from inspect_viz.transform import avg, count
table(penguins, 
      height=120,
      columns=[
        column("species"), 
        column(avg("body_mass")),
        column(avg("flipper_length"))])

When providing transforms to apply to columns (e.g. avg, sum), columns without aggregating transforms will be treated as columns to group by. So in the above example, the table is grouped by species displaying the rest of the values using their aggregate values.

Literal Data

You can also pass literal values (an int | float | bool) as a column by passing one or more values as the column itself. For example:

table(penguins, 
      columns=[
        column([1,2,3,4,5,6,7,8,9], label="sample_bucket"),
        column("species"), 
        column("body_mass"),
        column("flipper_length")])

If a single value is passed, that value will be repeated for every row in the dataset. If a list of values is passed, each row will increment through the list and include the value from the row index. If the list is shorter than the dataset, values will be repeated by repeatedly iterating through the list.

Selection

By default, the table will display the selection provided by the data source. If you’d like, you can provide an alternative selection by using filter_by.

Targeting Selections

It can be useful to use selected rows within a table to target a selection to be used elsewhere (for example, in highlighting points within a dot plot). To do this, use the target option to select the output selection. This will cause a selection clause of the form column IN (rows) to be added to the selection for each currently selected table row.

For example:

table(penguins, 
      target=selection)

You can use the select option to control how selection works within the table. By default, select is set to single_row which will allow selection of one row at a time by clicking the row. Other options are listed below:

Option Action
hover The selection will be updated when the user’s mouse hovers over a row.
single_row The selection will be updated when a single row is selected. The selected row will be highlighted.
multiple_row The selection will be updated when one or more rows are selected. The selected rows will be highlighted.
single_row_checkbox The selection will be updated when a single row is selected using a checkbox.
multiple_row_checkbox The selection will be updated when one or more rows is selected using a checkbox.

Appearance

Tables have a minimal default appearance using the AG Grid Balham theme. If the table is being displayed in a Quarto page or dashboard, it will automatically inherit the theme of the page on which it is hosted.

You can customize most aspects of the table appearance using the style argument like:

from inspect_viz.table import column, table, Pagination, TableStyle
table(penguins, 
      columns=[
        column("species"), 
        column("island"), 
        column("sex"), 
        column("body_mass")],
      style=TableStyle(
        background_color="#FCFAFF",  
        foreground_color="purple", 
        accent_color="#E8FFB3"))

Color

Using the three following basic color options will provide new colors for the table (with the overall colors of the table derived from these three themes). Each of these colors accepts a css color value (for example a hex color string or a named value like red).

Option Target
background_color The background color use for cells.
foreground_color The foreground color used for values within cells.
accent_color Accent color used for things like selection and highlights.

In addition to the previous basic options, you can do further customization of the colors by passing a css color value to the following:

Option Target
text_color The text color for UI elements presented within the table.
header_text_color The color for text in the header row.
cell_text_color The color for text in cell within the body of the table.
selected_row_background_color The background color of selected rows.

Fonts

You can control the fonts used by the table by passing a css font-family value in the following options:

Option Target
font_family The default font for all text within the table.
header_font_family The font used for text within the header row.
cell_font_family The font used for text within the body of the table.

Border

You can control the border of the table using the following border options:

Options Target
border_color The color of the border (value css color value).
border_width The width in pixels of the border.
border_radius The border radius in pixels.

Spacing

The spacing options controls how tightly data and UI elements are packed together in the table. All the padding within in the table is defined relative to this value, so changing this value will affect the spacing of everything in the table.

By default, tables have 4 pixels of spacing. To change this value, pass the number of pixels like so:

table(penguins, 
      columns=[
        column("species"), 
        column("island"), 
        column("sex"), 
        column("body_mass")],
      style=TableStyle(spacing=20))