Apply color formatting to columns
This guide shows you how to color cells, columns, and entire rows in your static or dynamic tables. It covers the three formatting methods, the ways to specify a color, and conditional formatting with ternary expressions and heat maps.
Caution
Formatting adds hidden columns that compute each cell's format. Apply formatting as the last step, after all other data processing is complete.
Example table
Let's start with the students table that every example in this guide uses. Run this code first:
Formatting methods
Deephaven provides three methods for applying color formatting to tables: formatColumns, formatColumnWhere, and formatRowWhere.
formatColumns
The formatColumns method is the foundational formatting method. Each color format is a string of the form "<ColumnName> = <color expression>":
- The left side names the column to color.
- The right side is a formula that Deephaven evaluates for each row to produce a color. It can include a condition, as shown in Advanced conditional formatting.
The following query sets the background of the GPA column to VIVID_YELLOW. Deephaven picks a contrasting text color for you, as Background and foreground colors explains:
formatColumns also sets number formats with Decimal(...), as its reference page describes.
formatColumnWhere
The formatColumnWhere method applies conditional color formatting to a single column. The following example formats the TestGrade column when the GPA is below 3.0:
formatColumnWhere(col, cond, formula) is shorthand for a ternary in formatColumns: formatColumns("<col> = (cond) ? formula : NO_FORMATTING"), where formula is a color expression and NO_FORMATTING leaves non-matching cells unformatted. The shorthand also converts each branch to the same type, so you can pass any color expression, including bg or heatmap.
formatRowWhere
The formatRowWhere method applies conditional color formatting to entire rows. For example, the code below highlights rows where Name is Jane:
formatRowWhere(cond, formula) is the same shorthand with * as the column name. The * column name stands for the entire row. Use * directly in formatColumns when one expression needs to choose among several row colors, as shown in Advanced row formatting.
Combine row and column formatting
You can combine row and column formatting in one table. Where they overlap, column formatting takes precedence over row formatting:
Colors
Every color format assigns a color. This section covers the ways to write a color, whether it colors a cell's background or its text, and how to choose readable color combinations.
Color types
You can specify a color by name, as a hex string, or with a color function such as colorRGB or colorHSL.
Named color values
Deephaven has hundreds of predefined colors. For the full list, with a swatch and hex value for each, see Named colors. Refer to a predefined color by its name in capital letters, such as VIVID_YELLOW or BRIGHT_GREEN.
Note
The NO_FORMATTING predefined value applies no format. Use it as the fallback branch of a ternary in formatColumns to leave non-matching cells or rows unformatted. Both branches of a ternary must have the same type. Named colors, colorRGB, and NO_FORMATTING are colors, while bg, fg, bgfg, bgfga, and heatmap return an encoded format. To pair one of those functions with an unformatted branch, use bg(NO_FORMATTING).
Hex colors
A hex color has three pairs of hexadecimal digits for red, green, and blue (RRGGBB). Each pair is a value from 00 to FF that sets the intensity of that component. A pound sign precedes every hex color, for example #0099FF.
A format string is a query string, so a hex color inside it needs backticks: "Name = `#87CEFA`". The same applies to the color argument of formatColumnWhere and formatRowWhere, which is also a formula: "`#87CEFA`".
RGB, RGBA, and HSL colors
The colorRGB function creates a color from its red, green, and blue components. Each component is either:
- An int from 0 to 255, as in the following example.
- A float from 0.0 to 1.0, written with an
fsuffix, as incolorRGB(0.5f, 0.5f, 0.5f). A plain decimal such as0.5is a double, whichcolorRGBdoes not accept.
colorRGB also accepts a fourth alpha (transparency) component, but table formatting uses only the red, green, and blue components and ignores alpha. The following example renders the same as the RGB example above:
The colorHSL function creates a color from hue (degrees), saturation (percent), and lightness (percent) instead. Its arguments are floats, so pass integers or f-suffixed decimals, as in colorHSL(200, 50.5f, 40).
Background and foreground colors
When formatting table cells, you can control two aspects of the cell's appearance:
- Background: The fill color of the cell.
- Foreground: The color of the text shown in the cell.
Pass a color to one of the following auto-imported color functions to set the background, the foreground, or both:
bgorbackground— Set the background to a specific color without changing the foreground.fgorforeground— Set the foreground to a specific color without changing the background.bgfgorbackgroundForeground— Set both background and foreground to specific colors.bgfgaorbackgroundForegroundAuto— Set the background to a specific color while Deephaven automatically chooses a contrasting foreground color.fgoorforegroundOverride— Set the foreground likefg. It also marks the color as an override for the selection highlight, but the Deephaven web UI doesn't use that mark: a selected cell looks the same as withfg.bgoorbackgroundOverride— Set the background likebg. It also marks the color as an override for the selection highlight, but the Deephaven web UI doesn't use that mark: a selected cell looks the same as withbg.
Assigning a color directly (for example, "GPA = VIVID_YELLOW") sets the background and automatically picks a contrasting foreground, the same as bgfga.
The following examples apply bg, fg, bgfg, and bgfga:
Color combination best practices
Background and foreground colors interact, and combinations without adequate contrast are hard to read:
- High contrast combinations (like black on white or dark blue on light yellow) are generally easier to read.
- Low contrast combinations (like light gray on white or dark blue on black) can strain the eyes and make text difficult to distinguish.
- Highly saturated colors of very different hues (like red on blue) create a vibrating effect that causes visual fatigue.
- Colorblind-safe combinations that differ in brightness, not just hue, stay readable for users with color vision deficiencies.
When you choose colors:
- Prefer automatic contrast: use a plain color or
bgfga, which pick a contrasting foreground for you, instead ofbgfgunless you need a specific text color. - Be consistent: use the same color schemes for similar data patterns across your application.
- Use colors meaningfully: colors should help communicate information, not just make the table look interesting.
- Test your color schemes: try them with actual data before deploying to production.
The following examples demonstrate both effective and problematic color combinations:
Conditional formatting
Conditional formatting allows you to apply colors to cells, columns, or rows based on specific criteria. This can be as simple as highlighting values above a certain threshold or as complex as using multi-part logical expressions.
Basic conditional formatting
The formatColumnWhere and formatRowWhere examples above each apply a single rule. Conditions can also use arithmetic on column values. For example, this highlights HomeworkGrade when it is more than 5 points above TestGrade:
Advanced conditional formatting
Because formatColumns evaluates each format as a query-language formula, you have access to powerful formatting capabilities. A format can use:
- Complex expressions involving multiple columns.
- User-defined closures and variables.
- All built-in query-language functions.
Ternary expressions
The formatColumns method supports ternary expressions for more complex conditional formatting:
A nested ternary can test several conditions in turn. For example, this code colors the Name column based on test grades, homework grades, and GPA:
The nested ternary checks its conditions in order and applies the first one that matches:
- Yellow background when either
TestGradeorHomeworkGradeis below 85. - Otherwise, light red background when
GPAis 3.0 or lower. - Otherwise, no special formatting.
Steven's name is yellow because of his test grade. Andy's grades are both 85, so his name falls through to the second rule and is light red because of his 3.0 GPA. Claire's and Jane's names have no formatting.
Advanced row formatting
As the formatRowWhere section explains, * as the column name in formatColumns formats entire rows. Using * directly lets one ternary expression choose among several row colors. Row formatting is useful for highlighting groups of rows, such as performance tiers:
This creates a table with:
- Light green rows for high-achieving students (
GPA≥ 3.5). - Light blue rows for good students (3.0 ≤
GPA< 3.5). - Bright yellow rows for students who may need additional support (
GPA< 3.0).
Heat maps
Heat maps are a powerful way to visualize numeric ranges in your data. A heat map colors each cell by where its value falls in a numeric range. Use the heatmap function:
Where:
colNameis the column whose value determines the color.minimumValueandmaximumValuedefine the range.minimumBackgroundColorandmaximumBackgroundColorare the colors to interpolate between.
For example, this creates a heat map for GPA values ranging from 1.0 to 4.0:
In this example:
- Values at or below 1.0 get
BRIGHT_RED. - Values at or above 4.0 get
BRIGHT_GREEN. - Values in between get a color interpolated proportionally between
BRIGHT_REDandBRIGHT_GREEN.
You can also create foreground heat maps with heatmapFg or heatmapForeground to color the text instead of the background.