# Types and Formats

## Measure Types

This section describes the various types that can be assigned to a **measure**.
A measure can only have one type.

### `string`

This measure type allows defining measures as a `string` value.

The `sql` parameter is required and must include any valid SQL expression
with an aggregate function that returns a value of the string type.

In the example below, we create a `string` measure by converting a numerical
value to a string:

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    high_or_low: {
      type: `string`,
      sql: `CASE WHEN ${CUBE.number} > 100 THEN 'high' ELSE 'low' END`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: high_or_low
        sql: "CASE WHEN {CUBE.number} > 100 THEN 'high' ELSE 'low' END"
        type: string
```

</CodeTabs>

### `time`

This measure type allows defining measures as a `time` value.

The `sql` parameter is required and must include any valid SQL expression
with an aggregate function that returns a value of the timestamp type.

In the example below, we create a `time` measure from an existing dimension:

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    last_order: {
      sql: `MAX(created_at)`,
      type: `time`
    }
  },

  dimensions: {
    created_at: {
      sql: `created_at`,
      type: `time`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: last_order
        sql: "MAX(created_at)"
        type: time

    dimensions:
      - name: created_at
        sql: created_at
        type: time
```

</CodeTabs>

### `boolean`

The `boolean` measure type can be used to condense data into a single boolean
value.

The `sql` parameter is required and must include any valid SQL expression
with an aggregate function that returns a value of the boolean type.

The example below adds an `is_completed` measure which only returns `true` if
**all** orders have the `completed` status:

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    is_completed: {
      sql: `BOOL_AND(status = 'completed')`,
      type: `boolean`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: is_completed
        sql: "BOOL_AND(status = 'completed')"
        type: boolean
```

</CodeTabs>

### `number`

The `number` type is usually used, when performing arithmetic operations on measures,
e.g., in [calculated measures][ref-calculated-measures].

The `sql` parameter is required and must include any valid SQL expression
with an aggregate function that returns a value of the numeric type.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    purchases_ratio: {
      sql: `1.0 * ${purchases} / ${count}`,
      type: `number`,
      format: `percent`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: purchases_ratio
        sql: "1.0 * {purchases} / {count}"
        type: number
        format: percent
```

</CodeTabs>

You can put any sql into `number` measure as long as it's an aggregate
expression:

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    ratio: {
      sql: `SUM(${CUBE}.amount) / count(*)`,
      type: `number`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: ratio
        sql: "SUM({CUBE}.amount) / count(*)"
        type: number
```

</CodeTabs>

### `number_agg`

The `number_agg` type is used when you need to write a custom aggregate function
in the `sql` parameter that isn't covered by standard measure types like `sum`,
`avg`, `min`, etc.

<WarningBox>

The `number_agg` type is only available in Tesseract, the [next-generation data modeling
engine][link-tesseract]. In versions before v1.7.0, it was not enabled by default.

</WarningBox>

Unlike the `number` type which is used for calculations on measures (e.g.,
`SUM(revenue) / COUNT(*)`), `number_agg` indicates that the `sql` parameter contains
a direct SQL aggregate function.

The `sql` parameter is required and must include a custom aggregate function that returns a numeric
value.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    median_price: {
      sql: `PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY price)`,
      type: `number_agg`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: median_price
        sql: "PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY price)"
        type: number_agg
```

</CodeTabs>

### `count`

Performs a table count, similar to SQL's `COUNT` function. However, unlike
writing raw SQL, Cube will properly calculate counts even if your query's
joins will produce row multiplication.

You do not need to include the `sql` parameter for the measure of this type.

`drill_members` parameter is commonly used with type `count`. It allows users to
click on the measure in the UI and inspect individual records that make up a
count. [Learn more about Drill Downs][ref-drilldowns].

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    number_of_users: {
      type: `count`,
      // optional
      drill_members: [id, name, email, company]
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: number_of_users
        type: count
        drill_members:
          - id
          - name
          - email
          - company
```

</CodeTabs>

### `count_distinct`

Calculates the number of distinct values in a given field. It makes use of SQL's
`COUNT DISTINCT` function.

The `sql` parameter is required and must include any valid SQL expression
of any type (without an aggregate function).

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    unique_user_count: {
      sql: `user_id`,
      type: `count_distinct`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: unique_user_count
        sql: user_id
        type: count_distinct
```

</CodeTabs>

### `count_distinct_approx`

Calculates approximate number of distinct values in a given field. Unlike
`count_distinct` measure type, `count_distinct_approx` is decomposable aggregate
function or **additive**. This allows its usage in **additive** [rollup
pre-aggregations][ref-schema-ref-preaggs-rollup] which are much more versatile
than **non-additive** ones. It uses special SQL backend-dependent functions to
estimate distinct counts, usually based on HyperLogLog or similar algorithms.
Wherever possible Cube will use multi-stage HLL which significantly improves
calculation of distinct counts at scale.

The `sql` parameter is required and must include any valid SQL expression
of any type (without an aggregate function).

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    unique_user_count: {
      sql: `user_id`,
      type: `count_distinct_approx`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: unique_user_count
        sql: user_id
        type: count_distinct_approx
```

</CodeTabs>

### `sum`

Adds up the values in a given field. It is similar to SQL's `SUM` function.
However, unlike writing raw SQL, Cube will properly calculate sums even if your
query's joins will result in row duplication.

The `sql` parameter is required and must include any valid SQL expression
of the numeric type (without an aggregate function).

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    revenue: {
      sql: `amount`,
      type: `sum`
    },

    revenue_2: {
      sql: `${charges_amount}`,
      type: `sum`
    },

    revenue_3: {
      sql: `fee * 0.1`,
      type: `sum`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: revenue
        sql: amount
        type: sum

      - name: revenue_2
        sql: "{charges_amount}"
        type: sum

      - name: revenue_3
        sql: fee * 0.1
        type: sum
```

</CodeTabs>

### `avg`

Averages the values in a given field. It is similar to SQL's AVG function.
However, unlike writing raw SQL, Cube will properly calculate averages even if
your query's joins will result in row duplication.

The `sql` parameter is required and must include any valid SQL expression
of the numeric type (without an aggregate function).

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    avg_transaction: {
      sql: `${transaction_amount}`,
      type: `avg`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: avg_transaction
        sql: "{transaction_amount}"
        type: avg
```

</CodeTabs>

### `min`

Type of measure `min` is calculated as a minimum of values defined in `sql`.

The `sql` parameter is required and must include any valid SQL expression
of the numeric type (without an aggregate function).

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    date_first_purchase: {
      sql: `date_purchase`,
      type: `min`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: date_first_purchase
        sql: date_purchase
        type: min
```

</CodeTabs>

### `max`

Type of measure `max` is calculated as a maximum of values defined in `sql`.

The `sql` parameter is required and must include any valid SQL expression
of the numeric type (without an aggregate function).

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    date_last_purchase: {
      sql: `date_purchase`,
      type: `max`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: date_last_purchase
        sql: date_purchase
        type: max
```

</CodeTabs>

## Measure Formats

When creating a **measure** you can explicitly define the format you'd like to
see as output.

### `percent`

`percent` is used for formatting numbers with a percent symbol.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    purchase_conversion: {
      sql: `1.0 * ${purchase} / ${checkout}`,
      type: `number`,
      format: `percent`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: purchase_conversion
        sql: "1.0 * {purchase} / {checkout}"
        type: number
        format: percent
```

</CodeTabs>

<WarningBox>

When using the `percent` format, do not multiply by 100 in your SQL expression.
Presentation tools like [Explore][ref-explore], [Workbooks][ref-workbooks], and
[Dashboards][ref-dashboards] apply this multiplication implicitly when displaying
percent-formatted values, e.g., a value of `0.5` will be displayed as `50%`.

</WarningBox>

<InfoBox>

Use `1.0 * numerator / denominator` to ensure decimal division, as integer
division would truncate the result, e.g., `5 / 10` may return `0`, not `0.5`,
depending on your data source and column types.

</InfoBox>

### `currency`

`currency` is used for monetary values.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    total_amount: {
      sql: `amount`,
      type: `sum`,
      format: `currency`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: total_amount
        sql: amount
        type: sum
        format: currency
```

</CodeTabs>

### Custom numeric formats

Measures with numeric types support custom formatting
using [d3-format][link-d3-format] specifier strings.

<InfoBox>

Custom numeric formatting is subject to support in [visualization tools][ref-viz-tools].
Check [APIs & Integrations][ref-apis-support] for details.

</InfoBox>

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  measures: {
    total_amount: {
      sql: `amount`,
      type: `sum`,
      format: `$,.2f`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    measures:
      - name: total_amount
        sql: amount
        type: sum
        format: "$,.2f"
```

</CodeTabs>

#### Common format examples

| Format string | Description | Example output |
|---------------|-------------|----------------|
| `.2f` | Fixed-point, 2 decimal places | 1234.57 |
| `,.0f` | Grouped thousands, no decimals | 1,235 |
| `$,.2f` | Currency with grouped thousands | $1,234.57 |
| `.0%` | Percentage, no decimals | 12% |
| `.2s` | SI prefix, 2 significant digits | 1.2k |
| `+.2f` | Explicit sign, 2 decimal places | +1234.57 |
| `.2~f` | Trimmed trailing zeros, 2 decimals | 1234.5 |

#### Format specifier syntax

The full syntax for a d3-format specifier is:

```
[[fill]align][sign][symbol][0][width][,][.precision][~][type]
```

| Component | Description |
|-----------|-------------|
| `fill` | Character to use for padding |
| `align` | `>` (right), `<` (left), `^` (center), `=` (pad after sign) |
| `sign` | `-` (negative only, default), `+` (positive and negative), `(` (parentheses for negative) |
| `symbol` | `$` (currency prefix), `#` (alternate form for binary/octal/hex) |
| `0` | Enable zero-padding (shorthand for `fill=0` with `align==`) |
| `width` | Minimum field width |
| `,` | Enable comma grouping separator |
| `.precision` | Number of digits after the decimal point (for `f`, `%`) or significant digits (for other types) |
| `~` | Trim trailing zeros |
| `type` | Output format type (see table below) |

#### Supported type characters

| Type | Description |
|------|-------------|
| `f` | Fixed-point notation |
| `e` | Exponent notation |
| `g` | Either decimal or exponent notation, rounded to significant digits |
| `r` | Decimal notation, rounded to significant digits |
| `s` | Decimal notation with an SI prefix, rounded to significant digits |
| `%` | Multiply by 100 and format with `f`, followed by percent sign |
| `p` | Multiply by 100, round to significant digits, followed by percent sign |
| `d` | Integer; ignores non-integer values |
| `b` | Binary |
| `o` | Octal |
| `x` | Hexadecimal (lowercase) |
| `X` | Hexadecimal (uppercase) |
| `c` | Character data (converts integer to Unicode) |
| (none) | Similar to `g`, but trims trailing zeros |

## Dimension Types

This section describes the various types that can be assigned to a
**dimension**. A dimension can only have one type.

### `time`

In order to be able to work with time series data, Cube needs to identify
a time dimension which is a timestamp column in your database. You can define
several time dimensions in a single cube.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    completed_at: {
      sql: `completed_at`,
      type: `time`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: completed_at
        sql: completed_at
        type: time
```

</CodeTabs>

Note that the type of the target column should be `TIMESTAMP`.
If your time-based column is type `DATE` or another temporal type,
you should cast it to a timestamp in the `sql` parameter of the dimension.

<ReferenceBox>

Please see [this recipe][ref-string-time-dims] if your datetime information is stored
as a string.

</ReferenceBox>

### `string`

`string` is typically used with fields that contain letters or special
characters.

The `sql` parameter is required and must include any valid SQL expression
with an aggregate function that returns a value of the string type.

The following model creates a field `full_name` by combining 2 fields:
`first_name` and `last_name`:

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    full_name: {
      sql: `CONCAT(${first_name}, ' ', ${last_name})`,
      type: `string`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: full_name
        sql: "CONCAT({first_name}, ' ', {last_name})"
        type: string
```

</CodeTabs>

### `number`

`number` is typically used with fields that contain number or integer.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    amount: {
      sql: `amount`,
      type: `number`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: amount
        sql: amount
        type: number
```

</CodeTabs>

### `boolean`

`boolean` is used with fields that contain boolean data or data coercible to
boolean. For example:

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    is_enabled: {
      sql: `is_enabled`,
      type: `boolean`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: is_enabled
        sql: is_enabled
        type: boolean
```

</CodeTabs>

### `switch`

`switch` type is used to define a dimension that can only take one of the predefined
set of values. It is similar to an enum type in programming languages. They are
particularly useful for defining [`case` measures][ref-case-measures].

<WarningBox>

`switch` dimensions are powered by Tesseract, the [next-generation data modeling
engine][link-tesseract]. In versions before v1.7.0, it was not enabled by default.

</WarningBox>

You do not need to include the `sql` parameter for the dimension of this type.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    currency: {
      type: `switch`,
      values: [
        `USD`,
        `EUR`,
        `GBP`
      ]
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: currency
        type: switch
        values:
          - USD
          - EUR
          - GBP
```

</CodeTabs>

<InfoBox>

When `switch` dimensions are queried or introspected using the [`/v1/meta` REST API
endpoint][ref-meta-api], they are represented as dimensions of type `string`.

</InfoBox>

### `geo`

`geo` dimension is used to display data on the map. Unlike other dimension types
it requires to set two fields: latitude and longitude.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    location: {
      type: `geo`,
      latitude: {
        sql: `${CUBE}.latitude`
      },
      longitude: {
        sql: `${CUBE}.longitude`
      }
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: location
        type: geo
        latitude:
          sql: "{CUBE}.latitude"
        longitude:
          sql: "{CUBE}.longitude"
```

</CodeTabs>

## Dimension Formats

### `imageUrl`

`imageUrl` is used for displaying images in table visualization. In this case
`sql` parameter should contain full path to the image.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    image: {
      sql: `CONCAT('https://img.example.com/id/', ${id})`,
      type: `string`,
      format: `imageUrl`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: image
        sql: "CONCAT('https://img.example.com/id/', {id})"
        type: string
        format: imageUrl
```

</CodeTabs>

### `id`

`id` is used for IDs. It allows to eliminate applying of comma for 5+ digit
numbers which is default for type `number`. The `sql` parameter is required and
can take any valid SQL expression.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    image: {
      sql: `id`,
      type: `number`,
      format: `id`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: image
        sql: id
        type: number
        format: id
```

</CodeTabs>

### `link`

`link` is used for creating hyperlinks. `link` parameter could be either String
or Object. Use Object, when you want to give a specific label to link. See
examples below for details.

The `sql` parameter is required and can take any valid SQL expression.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    order_link: {
      sql: `'http://myswebsite.com/orders/' || id`,
      type: `string`,
      format: `link`
    },

    crm_link: {
      sql: `'https://na1.salesforce.com/' || id`,
      type: `string`,
      format: {
        label: `View in Salesforce`,
        type: `link`
      }
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: order_link
        sql: "'http://myswebsite.com/orders/' || id"
        type: string
        format: link

      - name: crm_link
        sql: "'https://na1.salesforce.com/' || id"
        type: string
        format:
          label: View in Salesforce
          type: link
```

</CodeTabs>

### `currency`

`currency` is used for monetary values.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    amount: {
      sql: `amount`,
      type: `number`,
      format: `currency`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: amount
        sql: amount
        type: number
        format: currency
```

</CodeTabs>

### `percent`

`percent` is used for formatting numbers with a percent symbol.

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    open_rate: {
      sql: `COALESCE(1.0 * ${uniq_open_count} / NULLIF(${delivered_count}, 0), 0)`,
      type: `number`,
      format: `percent`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: open_rate
        sql:
          "COALESCE(1.0 * {uniq_open_count} / NULLIF({delivered_count}, 0), 0)"
        type: number
        format: percent
```

</CodeTabs>

### Custom numeric formats

Dimensions with the `number` type support custom formatting using
[d3-format][link-d3-format] specifier strings.

<InfoBox>

Custom numeric formatting is subject to support in [visualization tools][ref-viz-tools].
Check [APIs & Integrations][ref-apis-support] for details.

</InfoBox>

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    amount: {
      sql: `amount`,
      type: `number`,
      format: `$,.2f`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: amount
        sql: amount
        type: number
        format: "$,.2f"
```

</CodeTabs>

See the [Custom numeric formats](#custom-numeric-formats) section under [Measure
Formats](#measure-formats) for the full format specifier syntax and supported
type characters.

### Custom time formats

Dimensions with `time` type support custom formatting using
[POSIX strftime][link-strftime] format strings with [d3-time-format][link-d3-time-format] extensions.

<InfoBox>

Custom time formatting is subject to support in [visualization tools][ref-viz-tools].
Check [APIs & Integrations][ref-apis-support] for details.

</InfoBox>

<CodeTabs>

```javascript
cube(`orders`, {
  // ...

  dimensions: {
    created_at: {
      sql: `created_at`,
      type: `time`,
      format: `%Y-%m-%d %H:%M:%S`
    }
  }
})
```

```yaml
cubes:
  - name: orders
    # ...

    dimensions:
      - name: created_at
        sql: created_at
        type: time
        format: "%Y-%m-%d %H:%M:%S"
```

</CodeTabs>

#### Common format examples

| Format string | Example output |
|---------------|----------------|
| `%m/%d/%Y %H:%M` | 12/04/2025 14:30 |
| `%Y-%m-%d %H:%M:%S` | 2025-12-04 14:30:00 |
| `%B %d, %Y` | December 04, 2025 |
| `%b %d, %Y` | Dec 04, 2025 |
| `%I:%M %p` | 02:30 PM |
| `%A, %B %d` | Thursday, December 04 |
| `Q%q %Y` | Q4 2025 |
| `Week %V, %Y` | Week 49, 2025 |

#### Supported format specifiers

| Specifier | Description |
|-----------|-------------|
| `%a` | Abbreviated weekday name |
| `%A` | Full weekday name |
| `%b` | Abbreviated month name |
| `%B` | Full month name |
| `%c` | Locale's date and time |
| `%d` | Day of month [01,31] |
| `%e` | Space-padded day of month |
| `%f` | Microseconds |
| `%g` | ISO 8601 year without century |
| `%G` | ISO 8601 year with century |
| `%H` | Hour (24-hour) [00,23] |
| `%I` | Hour (12-hour) [01,12] |
| `%j` | Day of year [001,366] |
| `%L` | Milliseconds |
| `%m` | Month [01,12] |
| `%M` | Minute [00,59] |
| `%p` | AM or PM |
| `%q` | Quarter [1,4] |
| `%Q` | Milliseconds since UNIX epoch |
| `%s` | Seconds since UNIX epoch |
| `%S` | Second [00,61] |
| `%u` | Monday-based weekday [1,7] |
| `%U` | Sunday-based week number [00,53] |
| `%V` | ISO 8601 week number |
| `%w` | Sunday-based weekday [0,6] |
| `%W` | Monday-based week number [00,53] |
| `%x` | Locale's date |
| `%X` | Locale's time |
| `%y` | Year without century [00,99] |
| `%Y` | Year with century |
| `%Z` | Time zone name |
| `%%` | Literal percent sign |

[ref-string-time-dims]: /product/data-modeling/recipes/string-time-dimensions
[ref-schema-ref-preaggs-rollup]:
  /product/data-modeling/reference/pre-aggregations#rollup
[ref-calculated-measures]: /product/data-modeling/concepts/calculated-members#calculated-measures
[ref-drilldowns]: /product/apis-integrations/recipes/drilldowns
[link-strftime]: https://pubs.opengroup.org/onlinepubs/009695399/functions/strptime.html
[link-d3-time-format]: https://d3js.org/d3-time-format
[ref-viz-tools]: /product/configuration/visualization-tools
[ref-apis-support]: /product/apis-integrations/core-data-apis#data-modeling
[link-tesseract]: https://cube.dev/blog/introducing-next-generation-data-modeling-engine
[ref-case-measures]: /product/data-modeling/reference/measures#case
[ref-meta-api]: /product/apis-integrations/rest-api/reference#base_pathv1meta
[ref-explore]: /product/exploration/explore
[ref-workbooks]: /product/exploration/workbooks
[ref-dashboards]: /product/presentation/dashboards
[link-d3-format]: https://d3js.org/d3-format
