---
title: Layout
---

> [!WARNING]
> Legacy documentation: This documentation applies to **Legacy Deephaven Enterprise only** and does not apply to Core+.

> [!NOTE]
> For Core+ workers, see Community Core documentation for [layout hints](/core/docs/reference/cheat-sheets/cheat-sheet#use-layout-hints).

Deephaven provides many options to adjust table layout using the Layout Hints class.

> [!CAUTION]
> Unlike most operations on Deephaven tables, `layoutHints` does not create a new table. The `layoutHints` are not copied to any tables created from a table with `layoutHints`.

## Column groups

One thing you can do with the `layoutHints` API is define groups of columns via code. Column groups are made up of a group name, list of children names, and an optional color.

Group names must be valid column names and cannot be duplicates of other group or column names. Each child may only be included in one group. Colors may be specified as a hex string or the keyword string of any of the [named Deephaven colors](../../assets/color-formatting/Deephaven_Colors.pdf).

The code below demonstrates creating a table and then adding column groups via the `layoutHints` API. The columns are automatically moved in the UI so they are next to each other in the order specified in the children array. This movement only affects the UI, not the column order in the engine. Columns within groups can be rearranged in the UI via drag and drop; however, a column may not be dragged outside of its group.

```python
import deephaven.TableTools as ttools
from deephaven import convertToJavaList
from deephaven import LayoutHintBuilder

t = ttools.newTable(
    ttools.stringCol("A", ["A", "a"]),
    ttools.stringCol("B", ["B", "b"]),
    ttools.stringCol("C", ["C", "c"]),
    ttools.stringCol("D", ["D", "d"]),
    ttools.stringCol("E", ["E", "e"]),
    ttools.stringCol("Y", ["Y", "y"]),
    ttools.intCol("Even", [2, 4]),
    ttools.intCol("Odd", [1, 3]),
)

String = jpy.get_type("java.lang.String")

# Note this does not create a new table
t.layoutHints(
    LayoutHintBuilder.get()
    .columnGroup("Letters", jpy.array(String, ["Vowels", "Y", "Consonants"]), "#FCD65B")
    .columnGroup("Vowels", jpy.array(String, ["A", "E"]), "CORNFLOWERBLUE")
    .columnGroup("Consonants", jpy.array(String, ["B", "C", "D"]), "CORAL")
    .columnGroup("Numbers", jpy.array(String, ["Even", "Odd"]))
    .build()
)
```

```groovy
import com.illumon.iris.db.tables.utils.LayoutHintBuilder

t = newTable(
    col("A", ["A", "a"] as String[]),
    col("B", ["B", "b"] as String[]),
    col("C", ["C", "c"] as String[]),
    col("D", ["D", "d"] as String[]),
    col("E", ["E", "e"] as String[]),
    col("Y", ["Y", "y"] as String[]),
    intCol("Even", [2, 4] as int[]),
    intCol("Odd", [1, 3] as int[])
);

// Note this does not create a new table
t.layoutHints(
    LayoutHintBuilder.get()
    .columnGroup("Letters", ["Vowels", "Y", "Consonants"] as String[], "#FCD65B")
    .columnGroup("Vowels", ["A", "E"] as String[], COLOR_CORNFLOWERBLUE)
    .columnGroup("Consonants", ["B", "C", "D"] as String[], "CORAL")
    .columnGroup("Numbers", ["Even", "Odd"] as String[])
    .build()
);
```

![img](../../assets/columnGrouping.png)

## Lock column order

Designated columns in Deephaven tables can be "locked" in place at the start or the end of the column order. This enables the query author to ensure a consistent experience for all authorized users of that table. This feature uses the `.layoutHints` method.

Locking columns in starting or ending order in a table is accomplished in the query language by importing the `LayoutHintBuilder` class and then setting one or more of the following three parameters:

- `atFront()` – This method locks one or more columns to the beginning of the table. Column names are used as the argument(s).
- `atEnd()` – This method locks one or more columns to the end of the table. Column names are used as the argument(s).
- `savedLayouts()` – This parameter impacts users with whom this table is shared. When set to `true`, other users can rearrange the non-locked columns and then save their own layout for the specified table. When set to `false`, other users can rearrange the non-locked columns, but they cannot save the new column order. When the table is opened again, the column order will revert to the default order specified by the query author.

For example, the following query locks some of the table's columns:

```python
importjava("com.illumon.iris.db.tables.utils.LayoutHintBuilder")

t = db.t("LearnDeephaven", "StockQuotes").where("Date=`2017-08-25`")

t2 = t.update(java_array("java.lang.String", [])).layoutHints(
    LayoutHintBuilder.get()
    .atFront("USym", "Timestamp")
    .atEnd("Sym", "SecurityType")
    .savedLayouts(False)
)
```

```groovy
import com.illumon.iris.db.tables.utils.LayoutHintBuilder

t=db.t("LearnDeephaven", "StockQuotes").where("Date=`2017-08-25`")

t2=t.update().layoutHints(LayoutHintBuilder
	.get()
	.atFront("USym","Timestamp")
	.atEnd("Sym", "SecurityType")
	.savedLayouts(false)
	)
```

![img](../../assets/interfaces/layouthint1.png)

The query first imports the `LayoutHintBuilder` class, accesses the source data, then uses the `get()` method to create a new instance of the `LayoutHintBuilder` that:

- locks the USym and Timestamp columns to the front of the table,
- locks the Sym and SecurityType to the end of the table,
- and specifies that no changes to the layout can be saved by authorized users upon closing and reopening the table.

A `select`, `update`, `updateView`, or `where` operation must be included before the `.layoutHints()` operation in the query to ensure the changes are made only to the new `t2` table. This enables Deephaven to create the `t2` table as an individual object before continuing to the next method.

## Hide columns

When a table is open in Deephaven, columns can be manually hidden using [**Hide Column**](../legacy-ui/classic/column-name-context-menu.md#hide-column) in the right-click column header menu. However, columns can be hidden from view by default, ensuring they are hidden for all users who access that table. This feature uses the `.layoutHints` and `.hide` methods.

```python
from deephaven import *

t1 = (
    db.t("LearnDeephaven", "StockTrades")
    .where("Date=`2017-08-21`")
    .layoutHints(LayoutHintBuilder.get().hide("USym", "SecurityType", "Source"))
)
```

```groovy
import com.illumon.iris.db.tables.utils.LayoutHintBuilder

t1=db.t("LearnDeephaven", "StockTrades").where("Date=`2017-08-21`")
        .layoutHints(LayoutHintBuilder.get().hide("USym","SecurityType","Source"))
```

![img](../../assets/interfaces/layout-hint2.png)

- They can be unhidden via the **Choose Columns** option in the [right-click column menu](../legacy-ui/classic/column-name-context-menu.md#choose-columns).
- Selecting **Reset Columns** will hide them again.

## Freeze columns

Designated columns in Deephaven tables can be "frozen" in place on the left side of the table, and will remain in view even when horizontally scrolling through the table. Similar to the "freeze panes" option in spreadsheet software, this feature enables users to keep key columns in view as they read table data.

Deephaven offers two ways to accomplish this: by creating a new `LayoutHintsBuilder` and using the `freeze()` method in a query, or through the Deephaven console.

> [!NOTE]
> See:
> [Freeze Columns](../legacy-ui/classic/column-name-context-menu.md#freeze-columns)

```python
LayoutHintBuilder = jpy.get_type("com.illumon.iris.db.tables.utils.LayoutHintBuilder")
t = (
    db.t("LearnDeephaven", "StockTrades")
    .where("Date=`2017-08-21`")
    .layoutHints(LayoutHintBuilder.get().freeze("USym", "Exchange"))
)
```

```groovy
import com.illumon.iris.db.tables.utils.LayoutHintBuilder

t=db.t("LearnDeephaven", "StockTrades").where("Date=`2017-08-21`")
   .layoutHints(LayoutHintBuilder
      .get()
      .freeze("USym","Exchange")
   )
```

The horizontal scrollbar at the bottom of the table begins at the Date column because the USym and Exchange columns are frozen in place and always stay in view.

![img](../../assets/interfaces/freeze-columns.gif)

The frozen columns can be dragged and moved within their space to the left of the table.

> [!NOTE]
> To unfreeze a column in Deephaven Classic, right-click the column header and select **Unfreeze Column** from the drop-down list:
>
> ![img](../../assets/interfaces/classic/freeze-columns2.png)

This layout hint is compatible with other layout hints, such as [Saved Layouts](#lock-column-order). The following behaviors should be noted when freezing columns via a query:

- If a column is locked and also frozen by the query language, it cannot be unfrozen by using the right-click method in the GUI. If an unfrozen column is locked using the query language, it cannot be frozen in the GUI.
- Frozen columns are saved to the workspace and reloaded. If a user specifies columns to freeze via a query and then modifies those columns in the UI, the workspace will load the latest changes rather than what is in the query.
- Frozen columns can be hidden and restored just like any other column. The **Reset Columns** option will restore frozen columns to the original state defined in the query.

> [!WARNING]
> Freezing columns is not currently supported on Tree Tables.
