You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fixes#596. Adds UI table formatting based on the spec.
### Features
- Multiple formatting rules allowed on one table
- Last matching rule for a formatting type is applied
- Single dataclass (ui.TableFormat) which encompasses the potential
formatting options
- The `cols` parameter applies formatting to specific columns. The `if_`
parameter provides further filtering for rows
- DH theme color keywords supported in addition to hex and CSS keyword
colors
- If a background color is specified with no text color, a contrasting
black/white text color is applied
### Example Code
```py
from deephaven import ui
import deephaven.plot.express as dx
t = ui.table(
dx.data.stocks(),
format_=[
ui.TableFormat(value="0.00%"),
ui.TableFormat(cols="Timestamp", value="E, dd MMM yyyy HH:mm:ss z"),
ui.TableFormat(cols="Size", color="info", if_="Size < 10"),
ui.TableFormat(cols="Size", color="notice", if_="Size > 100"),
ui.TableFormat(cols=["Sym", "Exchange"], alignment="center"),
ui.TableFormat(
cols=["Sym", "Exchange"], background_color="negative", if_="Sym=`CAT`"
),
ui.TableFormat(background_color="positive", if_="Sym=`DOG`", color='negative')
],
)
```
1. It is not necessary to use a UI table if you do not need any of its properties. You can just use the Deephaven table directly.
17
17
2. Use a UI table to show properties like filters as if the user had created them in the UI. Users can change the default values provided by the UI table, such as filters.
18
18
3. UI tables handle ticking tables automatically, so you can pass any Deephaven table to a UI table.
19
19
20
+
## Formatting
21
+
22
+
You can format the table using the `format_` prop. This prop takes a `ui.TableFormmat` object or list of `ui.TableFormat` objects. `ui.TableFormat` is a dataclass that encapsulates the formatting options for a table. The full list of formatting options can be found in the [API Reference](#tableformat).
23
+
24
+
### Formatting rows and columns
25
+
26
+
Every formatting rule may optionally specify `cols` and `if_` properties. The `cols` property is a column name or list of column names to which the formatting rule applies. If `cols` is omitted, then the rule will be applied to the entire row. The `if_` property is a Deephaven formula that indicates a formatting rule should be applied conditionally. The `if_` property _must_ evaluate to a boolean. If `if_` is omitted, then the rule will be applied to every row. These may be combined to apply formatting to specific columns only when a condition is met.
27
+
28
+
> [!NOTE]
29
+
> The `if_` property is a Deephaven formula evaluated in the engine. You can think of it like adding a new boolean column using [`update_view`](https://deephaven.io/core/docs/reference/table-operations/select/update-view/).
30
+
31
+
The following example shows how to format the `Sym` and `Exchange` columns with a red background and white text when the `Sym` is `DOG`.
32
+
33
+
```python
34
+
from deephaven import ui
35
+
import deephaven.plot.express as dx
36
+
37
+
t = ui.table(
38
+
dx.data.stocks(),
39
+
format_=[
40
+
ui.TableFormat(
41
+
cols=["Sym", "Exchange"],
42
+
if_="Sym = `DOG`",
43
+
background_color="red",
44
+
color="white",
45
+
)
46
+
],
47
+
)
48
+
```
49
+
50
+
### Formatting rule priority
51
+
52
+
The last matching formatting rule for each property will be applied. This means the lowest priority rules should be first in the list with higher priority rules at the end.
53
+
54
+
In the following example, the `Sym` column will have a red background with white text, and the rest of the table will have a blue background with white text.
Formatting rules for colors support Deephaven theme colors, hex colors, or any valid CSS color (e.g., `red`, `#ff0000`, `rgb(255, 0, 0)`). It is **recommended to use Deephaven theme colors** when possible to maintain a consistent look and feel across the UI. Theme colors will also automatically update if the user changes the theme.
72
+
73
+
#### Formatting text color
74
+
75
+
The `color` property sets the text color of the cell. If a cell has a `background_color`, but no `color` set, the text color will be set to black or white depending on which contrasts better with the background color. Setting the `color` property will override this behavior.
76
+
77
+
The following example will make all text the foreground color except the `Sym` column, which will be white. In dark mode, the foreground color is white, and in light mode, it is black. In light mode, the `Sym` column will be nearly invisible because it is not a theme color.
78
+
79
+
```py
80
+
from deephaven import ui
81
+
import deephaven.plot.express as dx
82
+
83
+
t = ui.table(
84
+
dx.data.stocks(),
85
+
format_=[
86
+
ui.TableFormat(color="fg"),
87
+
ui.TableFormat(cols="Sym", color="white"),
88
+
],
89
+
)
90
+
```
91
+
92
+
#### Formatting background color
93
+
94
+
The `background_color` property sets the background color of the cell. Setting the `background_color` without setting `color` will result in the text color automatically being set to black or white based on the contrast with the `background_color`.
95
+
96
+
The following example will make all the background color what is usually the foreground color. This means the table will have a white background with black text in dark theme and a black background with white text in light theme. The `Sym` column text will be the accent color in both themes.
97
+
98
+
```py
99
+
from deephaven import ui
100
+
import deephaven.plot.express as dx
101
+
102
+
t = ui.table(
103
+
dx.data.stocks(),
104
+
format_=[
105
+
ui.TableFormat(background_color="fg"),
106
+
ui.TableFormat(cols="Sym", color="accent"),
107
+
],
108
+
)
109
+
```
110
+
111
+
### Formatting numeric values
112
+
113
+
> [!WARNING]
114
+
> Datetime values are considered numeric. If you provide a default format for numeric values, it will also apply to datetime values. It is recommended to specify `cols` when applying value formats.
115
+
116
+
Numeric values can be formatted using the `value` property. The `value` property is a string that follows [the GWT Java NumberFormat syntax](https://www.gwtproject.org/javadoc/latest/com/google/gwt/i18n/client/NumberFormat.html). If a numeric format is applied to a non-numeric column, it will be ignored.
117
+
118
+
This example will format the `Price` and `Dollars` columns with the dollar sign, a comma separator for every 3 digits, 2 decimal places, and a minimum of 1 digit to the left of the decimal point. The `Random` column will be formatted with 3 decimal places and will drop the leading zero if the absolute value is less than 1.
Datetime and timestamp values can be formatted using the `value` property. The `value` property is a string that follows [the GWT Java DateTimeFormat syntax](https://www.gwtproject.org/javadoc/latest/com/google/gwt/i18n/client/DateTimeFormat.html) with additional support for nanoseconds. You may provide up to 9 `S` characters after the decimal to represent partial seconds down to nanoseconds.
136
+
137
+
The following example formats the `Timestamp` column to show the short date of the week, day of the month, short month name, full year, hours, minutes, seconds, and microseconds with the user selected timezone.
You can listen for different user events on a `ui.table`. There is both a `press` and `double_press` event for `row`, `cell`, and `column`. These events typically correspond to a click or double click on the table. The event payloads include table data related to the event. For `row` and `column` events, the corresponding data within the viewport will be sent to the event handler. The viewport is typically the visible area ± a window equal to the visible area (e.g., if rows 5-10 are visible, rows 0-15 will be in the viewport).
@@ -42,7 +173,7 @@ t = ui.table(
42
173
)
43
174
```
44
175
45
-
## Context Menu
176
+
## Context menu
46
177
47
178
Items can be added to the bottom of the `ui.table` context menu (right-click menu) by using the `context_menu` or `context_header_menu` props. The `context_menu` prop adds items to the cell context menu, while the `context_header_menu` prop adds items to the column header context menu. You can pass either a single dictionary for a single item or a list of dictionaries for multiple items.
48
179
@@ -106,7 +237,7 @@ t = ui.table(
106
237
)
107
238
```
108
239
109
-
### Dynamic Menu Items
240
+
### Dynamic menu items
110
241
111
242
Menu items can be dynamically created by passing a function as the context item. The function will be called with the data of the cell that was clicked when the menu was opened, and must return the menu items or None if you do not want to add context menu items based on the cell info.
112
243
@@ -130,7 +261,7 @@ t = ui.table(
130
261
)
131
262
```
132
263
133
-
## Column Order and Visibility
264
+
## Column order and visibility
134
265
135
266
You can freeze columns to the front of the table using the `frozen_columns` prop. Frozen columns will always be visible on the left side of the table, even when the user scrolls horizontally. The `frozen_columns` prop takes a list of column names to freeze.
136
267
@@ -153,7 +284,7 @@ t = ui.table(
153
284
154
285

155
286
156
-
## Grouping Columns
287
+
## Grouping columns
157
288
158
289
Columns can be grouped visually using the `column_groups` prop. Columns in a column group are moved so they are next to each other, and a header spanning all columns in the group is added. Columns can be rearranged within a group, but they cannot be moved outside of the group without using the table sidebar menu.
159
290
@@ -195,7 +326,7 @@ t = ui.table(
195
326
196
327

197
328
198
-
## Always Fetching Some Columns
329
+
## Always fetching some columns
199
330
200
331
Deephaven only fetches data for visible rows and columns within a window around the viewport (typically the viewport plus 1 page in all directions). This reduces the amount of data transferred between the server and client and allows displaying tables with billions of rows. Sometimes you may need to always fetch columns, such as a key column for a row press event. You can use the `always_fetch_columns` prop to specify columns that should always be fetched regardless of their visibility.
201
332
@@ -218,7 +349,7 @@ t = ui.table(
218
349
)
219
350
```
220
351
221
-
## Quick Filters
352
+
## Quick filters
222
353
223
354
Quick filters are an easy way to filter the table while also showing the user what filters are currently applied. These filters are applied on the server via request from the client, so users may change the filters without affecting other users. Unlike a `where` statement to filter a table on the server, quick filters can be easily changed by the user.
0 commit comments