DataTable
The DataTable
is a component for building tables which organize information
into rows and columns.
Import
import { DataTable } from '@dynatrace/strato-components-preview/tables';
Use cases
Define header groups
It is possible to define header groups by providing a nested array of columns
via the columns
property in the column definition. Currently, a header group
can only contain columns and not another nested header group.
Enable sorting
By using the sortable
flag, you can enable sorting for the entire table.
Additionally, you have the option to disable sorting on a per-column basis by
configuring the disableSortBy
property in the column definition.
To monitor sorting changes within the DataTable
, you can employ the
onSortChange
callback. It's important to note that when you use the
onSortChange
callback, the DataTable's
built-in sorting functionality is
disabled by default. To continue using the DataTable's default sorting, you must
set the enableDefaultSort
property to true
.
The enableDefaultSort
property is specifically designed for use in conjunction
with the onSortChange
callback to enable or disable the built-in default
sorting behavior in the DataTable
. It cannot be set independently of an
onSortChange
handler.
Sort columns programmatically
By configuring the sortBy
prop on the DataTable level, you will be able to set
sorting initially and change it programmatically if needed. In this scenario,
the table is initially sorted in descending order by the 'Memory total' column.
When you click the first button, the table should be sorted in descending order
by the 'Traffic' column. When the second button is clicked, the table should be
sorted in ascending order by the 'Memory total' column. Be aware that sortBy
accepts an object value and that it needs to be memoized to prevent it from
causing unintentional re-rendering of the table.
Enable custom sorting
When you wish to implement custom sorting, you need to utilize the
onSortChange
callback. By default, using the onSortChange
callback will
disable the built-in sorting functionality of the DataTable
, expecting you to
provide your custom sorting logic and pass the sorted data directly to the
table.
Enable pagination
To enable pagination add the DataTable.Pagination
component to your table.
This component allows you to configure the page size and the page index via the
defaultPageSize
and defaultPageIndex
props.
Change page size options
The default page size options are 10, 20, 30, 40 and 50. To customize these
options, use the pageSizeOptions
prop, which allows you to pass the desired
page sizes as an array. Please ensure that the passed (default) page size aligns
with the defined options. The table will not sanitize page sizes that do not
exist in the options.
Control pagination
It is also possible to control the page size and the page index using the
pageSize
and the pageIndex
props together with the pageSizeChange
and the
pageIndexChange
callbacks. The onPageChange
callback allows you to react to
changes in both the page size and the page index.
Use server-side pagination
In addition to the regular client-side pagination, it is also possible to use
server-side pagination. For server-side pagination, pass the data for the
respective page to the table and update the enablePrevPage
and
enableNextPage
flags accordingly. Upon navigating to another page or changing
the page size the corresponding callbacks as well as the onPageChange
callbacks provide the updated values, allowing you to retrieve the corresponding
data.
Enable row selection
Set the selectableRows
flag on the table to activate the row selection. This
will render a checkbox in the first column. To select/deselect multiple rows at
once, it is possible to first select a start row and then select an end row
while holding shift.
The onRowSelectionChange
event allows you to react to changes in the selected
rows. The defaultSelectedRows
prop allows you to specify rows that are
selected from the start.
When used with pagination, row selections that are not visible on the current page will be deselected. In general, selections are also reset when the data changes.
Control row selection
To control the state of the selected rows, provide the selected rows using the
selectedRows
prop along with a handler for the onRowSelectionChange
callback. The onRowSelectionChange
callback includes the selected rows, their
original data, as well as a flag that indicates whether the selection change was
directly triggered by the user or internally.
As opposed to uncontrolled usage with pagination, the row selection is not automatically reset in a controlled scenario. However, it is crucial that the row selection always remains comprehensible for the user. It is therefore recommended not to allow row selections that are not visible, for example on pages other than the active one. If row selection on not visible pages is really necessary, the selected rows should at least be listed somewhere, so that the user can keep track of all selections.
Enable expandable rows
Expandable rows allow you to add additional data to a row. This information is only visible when the row is expanded.
The default state of each row can be controlled using the defaultExpandedRows
prop. To control each row over the lifetime of the table use the expandedRows
property and the onExpandedRowsChange
callback.
You can use the DataTableV2.ExpandableRowWrapper
to automatically wire up
variant styles applied on the DataTableV2
with the expanded row.
In this example, every second row is disabled for demo purposes.
Define column types
You can assign a predefined type to every column. Values in those columns will be rendered and sorted according to each type. Available types are 'text', 'log-content', 'markdown', 'date', 'bit', 'number', 'sparkline', and 'meterbar'.
Change text alignment
By default, if no column type is set, text within a cell is left-aligned and
vertically centered. To explicitly control the text alignment for a column, use
the alignment
property in the column definition.
Control column width behavior via column definitions
The DataTable
provides multiple ways of controlling the column width behavior.
- It is possible to make columns resizable by setting the
resizable
prop on theDataTable
. - To calculate the column width automatically, set
autoWidth
to true in the column definition. You can usemaxAutoWidth
per column definition to set an upper limit on the autoWidth value while still allowing resizing beyond that limit. If specified in the column definition,minWidth
andmaxWidth
still apply (also resizing beyond these is not possible). They have precedence over maxAutoWidth. - Alternatively, you can define ratios between columns using the
ratioWidth
prop.
Note: currently resizable
does not work in combination with ratioWidth
. When
the ratioWidth
flag is used on any column, resizable
will become inactive.
Get informed about column resizing
You can use the onColumnResize
callback event to obtain information about the
new widths of resized columns. This information can be used to store and persist
the resized column widths.
Auto-size columns based on the width of their contents
Setting autoWidth
for a column to true
, will cause the column width to match
the content width. In addition, maxAutoWidth
can be used to set an upper limit
here while still allowing resizing. If specified in the column definition,
minWidth
and maxWidth
still apply (also resizing beyond these is not
possible). They have precedence over maxAutoWidth
.
In the following example, all columns have autoWidth true and maxAutoWidth 300. When columns are resized it is possible to resize beyond the maxAutoWidth.
Customize cell rendering
To customize the cell rendering, pass the corresponding function to the cell
prop in the column definition. If you want to maintain default cell styling, you
need to wrap each return statement with DataTable.Cell
element. Also,
DataTable.Cell
supports className
and style
props, allowing further
customization of the cell appearance.
Customize header rendering
Similar to custom cell rendering, it is also possible to render a custom header.
Pass the desired custom header to the header
prop in the column definition. To
apply the default styles wrap the custom header with the DataTable.Cell
element.
Caution: Avoid placing interactive elements within a custom-rendered header if sorting is already configured for the same column. Since a column header with sorting already includes a button element, adding additional interactive elements inside may result in unexpected behavior.
Use custom cell data formatting
Use the formatters SDK from @dynatrace-sdk/units
in combination with custom
cell rendering to format numeric data within a cell.
Format cell data
You can format the cell data via the column definition, by specifying the column
property formatter
. For configuration, use the corresponding options from
'@dynatrace-sdk/units', i.e. FormatOptions
for numbers and FormatDateOptions
for dates.
Indicate data is empty
You can configure a customizable message to be displayed in the absence of data
in the DataTable
component. If a custom message is not specified DataTable
will show the default message - "No data available.".
Indicate table is loading
To set the initial loader for the entire table simply include the loading
prop
in the DataTable
component and control its state by toggling between true and
false values. When the loading state is set to true, a progress circle loader
will be displayed until all the data and columns are ready. When is set to false
table will be rendered.
Indicate data is loading
Use the loading
prop to display a loading indicator, which can be used when
waiting for data to be fetched or when performing actions like changing page
size or moving to the next page of the table.
Use the Sparkline chart in DataTable
It is possible to pass Timeseries data to the DataTable
and visualize it with
a Sparkline
charts. To achieve this, you need to set columnType
to
sparkline
in the column definition and use the column accessor
to point to
the timeseries data that you want to process.
The Sparkline chart in the DataTable
can be further configured via the column
definition. You can set its color and variant by adding
config: {color: string, variant: 'line' | 'area'}
. The default configuration
of sparkline is config: {color: 'categorical', variant: 'line'}
.
Use the MeterBarChart in DataTable
You can pass value:number
data to the DataTable
and visualize it using a
MeterBarChart
. For more information about the MeterBarChart
, refer to the
documentation. To render a
MeterBarChart
in the table, follow these steps:
- Set
columnType
tometerbar
in the column definition - Use the
accessor
property to specify which value data you want to process.
The MeterBarChart in the DataTable
column can be further customized through
the column definition. You can configure its appearance by using the config
prop, which includes the following options:
- color (string): Specifies the color of the
MeterBarChart
. - min (number): Sets the minimum value for the
MeterBarChart
. - max (number): Sets the maximum value for the
MeterBarChart
. - showTooltip (boolean): Controls whether tooltips are displayed.
- thresholds (array of objects
{name: string, value: number, color: string}
): Defines threshold values and their associated colors.
MultiMeterBarChart in tables
To add a MultiMeterBarChart
to the DataTable
, follow the steps in
MeterBarChart
in tables and then provide an array of value objects
(value: {name: string, value: number, color: string}
) as data, this will
enable DataTable
to visualize a MultiMeterBarChart
. For more information
about the MultiMeterBarChart
, refer to the
documentation
Again, similar to the MeterBarChart
, you can fine-tune the
MultiMeterBarChart
s appearance by setting the colorPalette
property to
define a color pattern specifically tailored for the MultiMeterBarChart
.
When data is provided as value array objects, color
and thresholds
props in
config
are ingored.
Enable line wrap
The DataTable
provides multiple ways to handle line wrapping of the content.
For the entire table
- Set the
lineWrap
property to true on theDataTable
. - Add
DataTable.LineWrap
to the toolbar.
Per column
- Set the
lineWrap
property to true in the column definition. - Add
TableUserActions.LineWrap
to the user actions.
Enable full width
By default, the DataTable is set to automatically expand and occupy the full
width of its parent element. However, this behavior changes when the table is
placed within a flex container. In such cases, if you wish to ensure that the
table maintains full width, you can include the fullWidth
prop when using the
DataTable component.
When the fullWidth
prop is enabled, the DataTable component will use 100% of
the available width within its parent container. In this setting, all the extra
width that is available will be taken by the last column in the table.
If this behavior is not conducive for your end-user experience, you have these other options:
- Setting
autoWidth
for each column totrue
, your column content is shown in full whether it's a full-width table or fixed width (maxAutoWidth
can be used to set an upper limit here while still allowing resizing). If specified in the column definition, minWidth and maxWidth still apply (also resizing beyond these is not possible). They have precedence over maxAutoWidth. - Setting
minWidth
for each column to an appropriate value, you have the ability to choose the right width for the content. - If there is a column that has wide content, if possible, make it the last one, so it gets maximum space when you are in a full-width table.
- If resizing columns is not a required feature for your end user, by setting
ratioWidth
to1
for all columns, you can distribute table width equally between all columns.
When this value is not set, it will grow as needed based on the number of columns and their width.
Customize DataTable look
The prop variant
, if set to various visual configuration options available in
TableVariantConfig
, provides a customized look of the DataTable
.
Configure table actions
We provide an additional space where you can place custom actions that affect
the whole table. It is located at the top above the table header and aligned to
the left, on the same line as the table toolbar which is always aligned to the
right. This space is available as a DataTable sub-component
DataTable.TableActions
.
Configure selected rows actions
Selected row actions enable you to perform actions on one or multiple rows in the DataTable simultaneously. These actions come into play when you select specific rows using the row checkboxes.
Configure column actions
Custom user actions can be configured for columns using special JSX tags that represent user actions.
ColumnActions
can be configured for specific columns by specifying the column
accessor. If default actions should be available for all columns that do not
explicitly have actions configured, the ColumnActions
column accessor is
omitted.
The ColumnActions
tag contains a function that is being called with the
instance of the current column so specific actions can be implemented for a
given column. The function needs to return a TableUserActions
object that
defines the user actions for the column.
Reorder columns via column actions
In the ColumnActions
, you can include ColumnOrder
action items that allow
the end user to rearrange the order of the columns.
Reorder columns via column settings modal
Column reordering can be also accomplished using the column settings within the
table toolbar. To enable this simply add the DataTable.ColumnOrderSettings
subcomponent to the table toolbar slot, following a similar approach as
configuring visibility settings. Both of these features are accessible within
the same toolbar overlay.
Configure cell actions
Custom user actions can also be configured for cells using special JSX tags that represent user actions.
CellActions
can be configured for specific columns by specifying the column
accessor. If default actions should be available for all columns that do not
explicitly have actions configured, the CellActions
column accessor is
omitted.
The CellActions
tag contains a function that is being called with an object
containing the instance of the current cell, row and column so specific actions
can be implemented for a given cell. The function needs to return a
TableUserActions
object that defines the user actions for the cell.
Configure row actions
You can configure row actions in the DataTable like in the following examples. The first simple example contains just one edit action. Specifying row actions causes an action column to be added on the rightmost side of the DataTable.
Furthermore, you can also provide several actions in a group. Actions that don't fit in the column will be automatically shown in an overflow menu. Note that you can provide a combination of icons and text per action. Here is another more complex example showing some of the available features. It also includes how to override the default width of the action column (the default width of the action column is 150px).
Configure column visibility
The DataTable.Toolbar
has an item VisibilitySettings
allowing you to toggle
the visibility of columns.
Regarding the columnVisibility
object, the default value for each column is
'visible' if nothing else is specified. Furthermore, you can specify 'hidden' so
that a column is initially hidden and you can specify 'always-visible' to
indicate that a column must always be visible (in other words, that is it cannot
be hidden). When 'always-visible' is specified, in the column settings dialog
the visibility checkbox is disabled.
In addition to controlling column visibility using the column settings overlay located in the table toolbar, hiding a column can also be accomplished by adding a 'hide column' column action.
Load Hidden Columns
When toggling hidden columns to visible, their data is populated automatically.
Highlight cells
Cells can be highlighted in different colors depending on the threshold
specified. In the column definition, you can configure the threshold for every
column. You can specify value
, comparator
, color
and backgroundColor
.
color
will be applied to the cell text and backgroundColor
to the cell
background.
If the column cell value passed is a string (text), the threshold comparator can
be set with either an equal-to
or not-equal-to
operator. On the other hand,
if your value is a number you can utilize one of the following operators:
greater-than
less-than
greater-than-or-equal-to
less-than-or-equal-to
equal-to
not-equal-to
Note: When multiple thresholds are applicable (evaluate to true) the last valid threshold has priority.
Highlight rows
You also have the possibility to highlight the whole row. The thresholds for
highlighting rows can be configured on the table level with the table prop
rowThresholds
. You can specify the same options as for the cell threshold but
now you can specify which cell value from the row threshold should apply by
defining an accessor/id
. You can add single or multiple rules to the threshold
definition. Multiple rules can be used to define multiple thresholds for
different cell values in a row but no matter which of them passes the same color
will be applied. In the case of both color
and backgroundColor
are
specified, the color will be applied to the row text.
Export DataTable config
The DataTable
's configuration can be exported at any time for various
purposes, such as sharing the configuration with other applications
through an intent. The current configuration
can be retrieved by creating and assigning a ref
to the corresponding ref
property of the DataTable
, and then calling ref.getConfig()
method.
ℹ️️ When the "getConfig" method is invoked, a snapshot of the serialized configuration is returned. As such, it will not change if the
DataTable
's configuration is subsequently modified. It is recommended to ensure that you apply all your required configurations to theDataTable
before calling this method
Import DataTable config
The configuration provider for the DataTable
accepts a JSON object and also
accepts a string
as input for importing a serialized configuration. When a
string is provided, it is internally parsed and applied as the DataTable
configuration.
ℹ️️ Please note that if the configuration provided does not match the properties of the
DataTable
configuration, any unknown properties will be ignored. Additionally, if required properties are not provided, or the given config is invalid, default values will be applied.
ℹ️️ It is important to note that due to potential version mismatches in
DataTable
packages used in different applications, importing a configuration from another application may produce an unintended outcome and not result in a perfect match.
Download data
The DataTable.Toolbar
has an item DownloadData
which enables the downloading
of the table data. Depending on your table configuration, you can choose between
downloading all data, downloading the current page and only downloading the
selected rows. Only visible columns are considered.
When downloading, double quotes are escaped and if the text has commas, new
lines, double quotes, tabs or carriage returns, the entire line is enclosed in
double quotes. In addition, values starting with =
, +
, -
, @
, \t
and
\r
are escaped with a single quote to mitigate CSV injection. Also note that
if you have custom cells you can provide a toString
function on the data
object for customized download output.
The DataTable
also provides the onDownloadData
callback that fires once data
has been downloaded. The callback's subset
parameter indicates whether all
data, the current page, or the selected rows were downloaded.
The preferred way is to use the toolbar item as above but if you have some good
reason not to use the toolbar you can create your own download trigger which
programmatically calls downloadData()
with one of the parameters 'all',
'page', or 'selected'. See the following example.
Get column data using accessors
Accessors specify how to get column data in the data structure. Normally strings with dots need to correspond to the structure of data where a dot represents one level. If the actual node name has a dot in it then you can escape the whole accessor with double quotes at the beginning and end of the string. Otherwise, you also have the option of specifying a function if you need more control. See the code here for examples of each.
Use Grail data
To facilitate easy use of the DataTable
in combination with Grail, we provide
the convertToColumns
function. This function takes a set of Grail field types
and converts them to a suitable column definition for the DataTable
.
Style fonts
The DataTable
can change the font style for the whole table or a specific
column. This can be achieved by configuring it in the table variant options or
the column definition. Additionally, it is possible to provide a toggle for
changing the font style of the entire table in the DataTable
's toolbar using
DataTable.FontStyle
. To provide a toggle targeting only a single column
TableUserActions.FontStyle
can be added as a column action. Through these
different mechanisms, you can customize the font style of the DataTable
.
Provide sub-rows
It is also possible to provide sub-rows in the DataTable
. Simply define the
respective sub-row data by adding the subRows
prop to the parent row's data
definition. If defined, an additional column containing the triggers for opening
and closing the sub-rows will automatically be added. The specified sub-rows
must have the same data structure as the parent rows and can be nested over
multiple levels.
Use the defaultOpenSubRows
prop to specify sub-rows that are already open upon
initial rendering. The onOpenSubRowsChange
handler allows you to react to
changes in the currently open sub-rows.
Control sub-rows
To control the state of the open sub-rows, provide the desired rows using the
openSubRows
prop along with a handler for the onRowSelectionChange
callback.
It is also possible to overwrite the default sub-rows column in your column
definition. You can e.g. provide a custom subRowsAccessor
for retrieving the
corresponding subRows for each row. Individual sub-rows can be disabled by
overwriting the disableSubRows
property.
Height
You can provide a height
value to the table which gives it a fixed height and
makes it scrollable. The headers are sticky, so scrolling will not remove them
from the view.
Enable column virtualization
To optimize performance for large tables with many columns, the DataTable
component provides the option to virtualize columns. This feature can be enabled
by setting the columnVirtualization
flag on the table. However, it is
important to note that there are some limitations associated with column
virtualization. To prevent layout shifting when virtualizing cells of different
heights, the row height is set based on the initially rendered columns.
Consequently, the linewrap
feature can only consider the initially rendered
columns, and the row height remains static after that. Similarly, due to the
fixed row heights, sub-rows cannot be used in conjunction with column
virtualization when there are varying row heights.
Get the current page data
To retrieve the currently displayed, sorted data, use the getCurrentPageData
method exposed on the ref
.