> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chronosphere.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Display data in a table

<Note>
  [Classic dashboards](/observe/dashboards/classic-dashboards) have their own panels
  and methods of configuring them. For details about panels in classic dashboards,
  see [Classic dashboard panels](/observe/dashboards/classic-dashboards/classic-panels).
</Note>

A *table* panel organizes and displays the data returned by a
[query](/investigate/querying) as table with sortable columns. Tables can
interpret time series data as columns or rows, or can render each raw data
point from a series in its own row. You can also add columns for each label
in a series, and for common calculations of each series' data.

To create a table chart or learn more about the configuration options common
to all panels, see [Panels](/observe/dashboards/panels).

## Table chart queries

Table charts use one or more
[queries](/observe/dashboards/panels#change-a-panels-query) to retrieve data to
visualize. Table charts use the following query **Options** to refine the
displayed information, depending on your **Datasource**:

<Tabs>
  <Tab title="Metrics (Prometheus)" id="queries-metrics">
    * **Type**: The [PromQL query](/investigate/querying/promql#basic-querying)
      type: **Instant**, or **Range**.

    - **Truncation strategy**: Truncation strategy to apply to the query. This modifies
      the raw query. Observability Platform selects the best strategy for fit when
      possible, and displays `Auto` as the selected strategy.

      Available strategies are:

      * `Auto`
      * `Off`
      * `Avg`
      * `Min`
      * `Max`

      Changing your truncation strategy adds truncation information as additional bands
      or bars on your chart and details into the legend.
  </Tab>

  <Tab title="Logs" id="queries-logs">
    For logs, enter a valid query.
  </Tab>
</Tabs>

### Query example

The following example creates a table with multiple label values:

```text theme={null}
sum by (instance, environment) (METRIC_NAME)
```

Replace *`METRIC_NAME`* with the name of any metric with labels.

## Use a table's tooltip

Observability Platform truncates the display of table values that exceed a column's
width. To view the complete value, hold the pointer over the truncated value in the
table.

## Export a table as CSV

You can export a table's values as a CSV file.

1. In the panel, click the <Icon icon="ellipsis-vertical" /> icon.
2. Select **Export CSV**.

## Configure a table

You can configure a table by
[modifying its <Icon icon="settings" /> **Settings**](/observe/dashboards/panels#edit-a-panel).

Any changes you make in the panel's **Settings** tab are immediately reflected in
the **Preview** pane, but take effect only when you click **Apply** in the **Edit panel**
interface and then **Save** the dashboard.

Observability Platform doesn't fully support directly editing a panel's JSON representation
and recommends configuring panels in the user interface. Use the JSON representation
only for managing your configuration as code with tools such as [Chronoctl](/tooling/chronoctl)
and [Terraform](/tooling/infrastructure/terraform).

### Modify a table's data format

The **Data Format** section in a table's **Settings** tab defines how the table
interprets the panel's query results for tabular display.

To define the table's data format, select a **Time series format**.

* **Series to Rows** displays each series as a row in the table. You must also select
  which **Calculations** to apply to the series and display in the table. If the
  series contains labels, you can also toggle **Label-based columns**, which adds
  a column for each series' label when enabled.
* **Series to Columns** displays each series as a column in the table. Each row
  in the table represents one data point in the series with the timestamp indicated
  in the **Time** column.
* **Raw** displays the timestamp and value for each data point of a selected series.

### Modify a table's sorting

The **Sorting** section in a table's **Settings** tab controls the table's sorting
order.

* **Sort by**: Determines the column used to sort the table.
* **Sort order**: Determines whether display the table's contents by its **Default**
  original data order, or to sort it in **Ascending** or **Descending** order.
  Observability Platform disables this field until you select a **Sort by** column.

To add multiple sorting criteria:

1. Set a **Sort by** column.
2. Click **+** (**Add sort**) to add a sorting criteria.

To remove a sorting criteria, click **<Icon icon="trash" alt="Delete icon" /> Delete**
on the row of the criteria you want to remove.

### Modify a table's units

The **Display** section in a table's **Settings** tab controls how Observability
Platform interprets the units of data in the table.

* **Unit**: Defines the unit used to render the Y-axis. This has the most significant
  effect when you enable Abbreviate. Defaults to `Decimal`.
  * **Decimal**: Base 10 values. Observability Platform renders a value of
    `1000000` as `1M`.
  * **Bytes**: As decimal multiple-byte units. Observability Platform renders a
    value of `1000000` as `1MB`.
  * **Time**: Determines the [unit of time](/overview/concepts/time-units)
    that Observability Platform uses to interpret a numeric value.
  * **Percent**: Interprets the value as a percentile, representing 0% to 100% in a
    range of either 0.0 to 1.0 (**Percent (0.0-1.0)**) or 0 and 100
    (**Percent (0-100)**).

    For example, Observability Platform renders a value of `1.0` in **Percent
    (0.0-1.0)** as `100%`, and in **Percent (0-100)** as `1%`.
* **Decimals**: Defines how many decimal places Observability Platform renders for
  values.
  **Default** renders decimal places only if necessary and rounds to the nearest
  value. Numeric values from `0` to `4` render the corresponding number of decimal
  places.
* **Abbreviate**: Toggles whether to abbreviate units on the Y-axis. For example, if
  enabled, Observability Platform renders a value of `100000000` as `100M`. You can
  toggle this setting only if you set the **Unit** to `Decimal` or `Bytes`; `Time`
  units are always abbreviated and `Percent` values don't require the toggle.
  Defaults to `true`.

### Configure a table's thresholds

The **Thresholds** section in a table chart's **Settings** tab defines values where
Observability Platform renders each threshold range. You can set a single threshold
to differentiate, or multiple thresholds to indicate severity level. For example,
you might want a warning value in orange, and a critical value in red.

To create a new threshold:

1. Edit a table panel.
2. Click the **Settings** tab.
3. In the **Thresholds** section, click the <Icon icon="plus" /> plus icon.
4. Enter a value in the **When value is >=** text box.
5. Use the color box to select a color for the threshold.
6. Optional: Click the caret (**>**) to expand a row and update the **Message** field.
7. Click the <Icon icon="plus" /> plus icon to add more threshold levels.
8. When finished, click **Apply**.

After applying the changes, the table updates with the selected color highlighting
the violated threshold.

To delete a threshold value, click the caret (**>**) to expand the threshold definition,
and then click
**<Icon icon="trash" alt="Delete icon" /> Delete threshold**.

### Configure a table's columns

The **Table columns** tab in a table's **Edit panel** interface controls whether
to display certain columns in the table and lets you edit their headings. The
tab lists each table column in a separate row.

* **Visibility**: Toggles whether to display the column.
* **Name**: Displays the column's original name.
* **Display Name**: Defines the name used in the column's header.
* **Order**: Use the arrows to reorder the table.

## Table examples

The following examples are [JSON formatted](/observe/dashboards/panels/json-representation)
dashboard code. Modify the variables in these examples for your tenant and applications.

### Table with severity by color

This table lists items sorted by severity, and applies color to the **Severity**
column based on the resulting value:

```json Table with colored severity expandable theme={null}
{
  "kind": "Panel",
  "spec": {
    "display": {
      "name": "Table by category",
      "description": ""
    },
    "plugin": {
      "kind": "Table",
      "spec": {
        "columnOverrides": [
          {
            "properties": {
              "displayName": "Category A",
              "format": {
                "kind": "Number",
                "thresholds": {
                  "base": {
                    "color": "#2A75CF"
                  }
                }
              }
            },
            "value": "sent_by_gmail"
          },
          {
            "properties": {
              "displayName": "Category B"
            },
            "value": "sent_by_exchange"
          },
          {
            "properties": {
              "displayName": "Category C"
            },
            "value": "sent_by_channel_c"
          },
          {
            "properties": {
              "displayName": "Resource ID",
              "format": {
                "kind": "String",
                "overrides": []
              }
            },
            "value": "account_id"
          },
          {
            "properties": {
              "displayName": "Category C"
            },
            "value": "sent_by_ticket"
          }
        ],
        "sort": [],
        "thresholds": {
          "base": {
            "color": "#2A75CF"
          }
        }
      }
    },
    "queries": [
      {
        "kind": "DataQuery",
        "spec": {
          "alias": "Category A",
          "plugin": {
            "kind": "LogsDataQuery",
            "spec": {
              "query": "#\"query 1\": \"@tags:MailRenderingJob* $NotificationId $AccountId \\\"sent by Gmail, response code is\\\"\"\n#\"query 2\": \"@tags:MailRenderingJob* $NotificationId $AccountId \\\"Using Exchange Connector\\\"\"\n#\"query 3\": \"@tags:MailRenderingJob* $NotificationId $AccountId -\\\"sent by Gmail, response code is\\\" -\\\"Using Exchange Connector\\\"\"\nservice=\"classic\"\ntags: \"MailRenderingJob\"\n\"$AccountId\"\n| summarize sent_by_gmail = countif(message: \"sent by Gmail\"), sent_by_exchange = countif(message: \"Using Exchange Connector\"), sent_by_ticket = countif(NOT  (\"Using Exchange Connector\" OR \"sent by Gmail, response code is\")) by account_id ",
              "reducer": "Sum",
              "series_name": {
                "name_pattern": "Category A",
                "type": "Labels"
              }
            }
          }
        }
      }
    ],
    "formulas": [],
    "links": []
  }
}
```

### Table with additional columns

This table overrides the default columns and adds additional columns:

```json Additional columns expandable theme={null}
{
  "kind": "Panel",
  "spec": {
    "display": {
      "name": "Table by delivery status",
      "description": ""
    },
    "plugin": {
      "kind": "Table",
      "spec": {
        "columnOverrides": [
          {
            "properties": {
              "displayName": "DATA.ENVELOPE.TARGET",
              "width": 540.5
            },
            "value": "data.envelope.recipient"
          },
          {
            "properties": {
              "displayName": "DATA.STATUS.CODE",
              "format": {
                "kind": "String",
                "overrides": [
                  {
                    "matcher": {
                      "type": "ByName"
                    },
                    "properties": {
                      "background_color": "#7edb76"
                    },
                    "value": "250"
                  },
                  {
                    "matcher": {
                      "type": "ByRegex"
                    },
                    "properties": {
                      "background_color": "#fadfc2"
                    },
                    "value": "4.*"
                  },
                  {
                    "matcher": {
                      "type": "ByRegex"
                    },
                    "properties": {
                      "background_color": "#f34949"
                    },
                    "value": "5.*"
                  }
                ]
              }
            },
            "value": "data.delivery_code"
          },
          {
            "properties": {
              "displayName": "DATA.SUMMARY.LABEL"
            },
            "value": "data.summary.customer"
          },
          {
            "properties": {
              "displayName": "LOGS"
            },
            "value": "count_"
          }
        ],
        "unit": {
          "abbreviate": true,
          "kind": "Decimal"
        }
      }
    },
    "queries": [
      {
        "kind": "DataQuery",
        "spec": {
          "plugin": {
            "kind": "LogsDataQuery",
            "spec": {
              "query": "#\"query\": \"service:example-service @data.summary.customer:* @email_id:* -@data.envelope.recipient:mailarchive *:$MessageId.value $AccountId\"\nservice=\"example-service\"\ndata.summary.customer EXISTS\nemail_id EXISTS\nNOT data.envelope.recipient: \"mailarchive\"\nmessage_id =~ \"$MessageId\"\naccount_id =~ \"$AccountId\"\n| summarize by data.delivery_code,data.envelope.recipient,data.summary.customer ",
              "reducer": "Last"
            }
          }
        }
      }
    ],
    "formulas": [],
    "links": []
  }
}
```

### Table with custom columns and color coding based on result

This table adds custom columns and adds color to one of the columns based on the
query result:

```json Custom columns and color coding expandable theme={null}
{
  "kind": "Panel",
  "spec": {
    "display": {
      "name": "Table with status codes",
      "description": ""
    },
    "plugin": {
      "kind": "Table",
      "spec": {
        "columnOverrides": [
          {
            "properties": {
              "format": {
                "kind": "String",
                "overrides": [
                  {
                    "matcher": {
                      "type": "ByRegex"
                    },
                    "properties": {
                      "background_color": "#fadfc2"
                    },
                    "value": "4.*"
                  },
                  {
                    "matcher": {
                      "type": "ByRegex"
                    },
                    "properties": {
                      "background_color": "#f34949"
                    },
                    "value": "5.*"
                  }
                ]
              }
            },
            "value": "data.delivery_code"
          },
          {
            "properties": {
              "displayName": "Source"
            },
            "value": "data.envelope.sender"
          }
        ],
        "unit": {
          "abbreviate": true,
          "kind": "Decimal"
        }
      }
    },
    "queries": [
      {
        "kind": "DataQuery",
        "spec": {
          "plugin": {
            "kind": "LogsDataQuery",
            "spec": {
              "query": "# \"query\": \"service:example-service @data.envelope.recipient:*example.com -@data.remote.mx:mailarchive -@data.envelope.sender:*.example.com $AccountId @data.mailfrom_account_id:* @message_id:*username@example.com> @test.service:out status:(warn OR error)\"\nservice = \"example-service\"\ndata.envelope.recipient: \"example.com\"\nNOT data.remote.mx = \"mailarchive\"\nNOT data.envelope.sender: \"example.com\"\naccount_id =~ \"$AccountId\"\ndata.mailfrom_account_id EXISTS\nmessage_id =~ \"username@example.com|username@example-staging.com\"\ntest.service: \"out\"\nseverity =~ \"ERROR|WARN\"\n| summarize by data.envelope.sender,data.delivery_code,data.response.text,data.summary.customer",
              "reducer": "Last"
            }
          }
        }
      }
    ],
    "formulas": [],
    "links": []
  }
}
```
