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

# Data structure

## Basic structure

Data is structured as a table with explicitly defined columns and rows:

```tsx theme={null}
const config: GraphConfig = {
  data: {
    columns: [
      { key: 'category', label: 'Category' },
      { key: 'value', label: 'Value' },
    ],
    rows: [
      { category: 'A', value: 100 },
      { category: 'B', value: 200 },
      { category: 'C', value: 150 },
    ],
  },
};
```

The `columns` array defines your data structure, while `rows` contains the actual values. Each row object must have keys matching the column keys.

## Automatic column mapping

Graphy automatically assigns your data columns to x-axis and y-axis, and creates series based on the detected value formats.

**Default mapping** for most graph types (bar, column, line, area):

* The first text or date column becomes the **x-axis**
* All numeric columns become the **y-axis**, with each numeric column creating a separate **series**

```tsx theme={null}
const config: GraphConfig = {
  data: {
    columns: [
      { key: 'month', label: 'Month' },       // date column → x-axis
      { key: 'revenue', label: 'Revenue' },    // numeric → series 1
      { key: 'expenses', label: 'Expenses' },  // numeric → series 2
    ],
    rows: [
      { month: 'January 2026', revenue: 5000, expenses: 3200 },
      { month: 'February 2026', revenue: 6200, expenses: 3800 },
      { month: 'March 2026', revenue: 5800, expenses: 3500 },
    ],
  },
};
```

**Graph-specific behaviour:**

| Graph type              | X-axis                    | Y-axis / values                             |
| ----------------------- | ------------------------- | ------------------------------------------- |
| Bar, column, line, area | First text or date column | All numeric columns (one series each)       |
| Combo                   | First text or date column | All numeric columns (last defaults to line) |
| Funnel, waterfall       | First text column         | First numeric column                        |

**Pie and donut** use the first text column for slices and the first numeric column for values. Additional columns are ignored.

**Scatter** requires at least 2 numeric columns: the first becomes the x-axis and the remaining become y-axis series. If a text column is present, it is used as a label for each point.

**Bubble** requires at least 3 numeric columns: the first is the x-axis, the second is the y-axis and the third controls the bubble size. Like scatter, the first text column is used as a label.

If your data contains only numeric columns, the first numeric column is used as the x-axis and the rest become series.

## Value format detection

Graphy automatically detects the format of values in each column. The first match wins:

### Numbers

Numbers and numeric strings are detected as quantitative values. Thousands separators, decimals and magnitude suffixes are supported:

```tsx theme={null}
{ category: 'A', value: 100 }
{ category: 'B', value: '1,250.50' }
{ category: 'C', value: '2.5m' }       // k, m, b, t suffixes supported
```

### Dates

Date-like strings are automatically parsed. Graphy recognises a wide range of formats, including ISO dates, named months and locale-specific orderings:

```tsx theme={null}
{ date: '2024-01-15', value: 100 }           // YYYY-MM-DD
{ date: 'January 2024', value: 200 }         // month name + year
{ date: '15/01/2024', value: 150 }           // DD/MM/YYYY (when data._metadata.parsingLocale is en-GB)
{ date: '01/15/2024', value: 150 }           // MM/DD/YYYY (en-US, the default locale)
{ date: '2024-01-15T12:30:00Z', value: 300 } // ISO datetime
{ date: 'Q1 2024', value: 400 }              // quarter
```

Short month names (`Jan`, `Feb`) are recognised alongside full names. Set `data._metadata.parsingLocale` to control whether ambiguous dates like `01/02/2024` are interpreted as MM/DD (en-US) or DD/MM (en-GB).

**Weekly date ranges** are also detected — values like `1 Feb – 7 Feb` or `1 Feb 2024 – 7 Feb 2024` representing 7-day spans.

### Percentages

Values with a `%` suffix are detected as percentages:

```tsx theme={null}
{ category: 'Desktop', share: '64.5%' }
{ category: 'Mobile', share: '28.3%' }
```

### Currencies

Currency-formatted strings are parsed with automatic symbol recognition. Supported symbols: `$`, `€`, `£`, `¥`, `₹`, `₱`, `₩`, `₪`, `₫`, `₽`, `฿`, `₦`, `₺`, `zł`, `kr`, `Fr`, `R`, `R$`, `Rp`, `RM`, `د.إ`, `﷼`, `Ch$`, `NT$`, `HK$`, `S$`, `A$`, `C$`, `NZ$`, `MX$`.

```tsx theme={null}
{ product: 'A', price: '$1,250' }
{ product: 'B', price: '£2,450.50' }
{ product: 'C', price: '€3,000' }
```

Symbols can appear as prefix or suffix, and negative values are supported (`-$100`, `$-100`).

### Text

Any value that doesn't match the above formats is treated as text (categorical data).

## Schema

<ParamField path="data.columns" type="Column[]" required>
  Array of column definitions. Each column defines the structure and metadata for a data field.
</ParamField>

<ParamField path="columns[].key" type="string" required>
  Unique, stable identifier for the column. Must match the keys used in `rows` objects.
</ParamField>

<ParamField path="columns[].label" type="string" optional>
  Human-readable label displayed in the UI (axis labels, legends, tooltips). Defaults to the `key` if not provided.
</ParamField>

<ParamField path="columns[]._metadata" type="object" optional>
  Internal column metadata. Managed automatically by the editor.

  <Expandable title="properties">
    <ParamField path="isHidden" type="boolean" optional>
      Whether the column is hidden from visualization.
    </ParamField>

    <ParamField path="aggregation" type="'count' | 'distinct' | 'max' | 'min' | 'sum' | 'mean' | 'mode' | 'median'" optional>
      Aggregation function applied to this column.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField path="data.rows" type="Row[]" required>
  Array of data rows. Each row is an object with keys matching the column keys. Values can be strings, numbers or null.
</ParamField>

<ParamField path="data._metadata" type="object" optional>
  Optional metadata for advanced data processing.

  <Expandable title="properties">
    <ParamField path="parsingLocale" type="'en-GB' | 'en-US'" optional>
      Locale for parsing dates and numbers. Defaults to `'en-US'`.

      * `'en-US'`: MM/DD/YYYY date format
      * `'en-GB'`: DD/MM/YYYY date format
    </ParamField>

    <ParamField path="isDataTransposed" type="boolean" optional>
      Whether the data is transposed. Used by the data table component.
    </ParamField>

    <ParamField path="isAggregated" type="boolean" optional>
      Whether aggregation is active. Managed automatically by the editor.
    </ParamField>

    <ParamField path="groupByTimeUnit" type="'year' | 'quarter' | 'month' | 'week' | 'day'" optional>
      Time unit for grouping time-based data.
    </ParamField>

    <ParamField path="sortBy" type="object" optional>
      Sort configuration.

      <Expandable title="properties">
        <ParamField path="columnKey" type="string" required>
          Column key to sort by.
        </ParamField>

        <ParamField path="direction" type="'asc' | 'desc'" required>
          Sort direction.
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField path="rollingDateFilter" type="object" optional>
      Rolling date filter configuration.

      <Expandable title="properties">
        <ParamField path="timeUnit" type="'year' | 'quarter' | 'month' | 'week' | 'day'" required>
          Time unit for the filter.
        </ParamField>

        <ParamField path="value" type="number" required>
          Number of time units (e.g., last 30 days: `{ timeUnit: 'day', value: 30 }`).
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<Note>
  Row object keys must exactly match the `key` values in your columns array. Data with keys that don't have a
  corresponding column definition will be ignored.
</Note>
