# Distribution Chart Module

## Short Description

Distribution Chart Module is a reusable Yeeflow dashboard custom code template that groups records from a data list by category and displays the result as a clean chart module.

## Purpose / What This Is For

Use this template when a dashboard needs to show how records are distributed across categories such as status, department, source, warehouse zone, owner, region, product category, or approval stage.

It solves a common dashboard problem: users often need a quick visual answer to questions like "How many records are in each status?" or "Which department owns the most open requests?" Instead of building a custom chart each time, teams can configure this reusable module with a data list and a category field.

## Supported Placement

This template is optimized for:

- Dashboard page

It is not designed as an approval-form input control and does not write values back to form fields.

## When To Use This Template

Use Distribution Chart Module when:

- You need a category/count summary from a Yeeflow data list.
- You want a dashboard chart that can be reused across multiple apps.
- The chart should group records by one field and count the number of records in each group.
- You need a donut, pie, horizontal bar, or vertical bar view.
- You want a customer-friendly dashboard block with clear empty, loading, and error states.

## Input Parameters Overview

| Parameter | Type | Required | Purpose | Example Value |
| --- | --- | --- | --- | --- |
| `dataListId` | Expression editor | Yes | Target Yeeflow data list used as the data source. | `2034150397060198400` |
| `categoryField` | Expression editor | Yes | Field ID/name used to group records. | `Status` |
| `titleText` | Plain text | No | Title shown at the top of the module. | `Stock Status Distribution` |
| `subtitleText` | Plain text | No | Supporting text below the title. | `Current inventory grouped by stock status` |
| `chartType` | Plain text | No | Chart presentation mode. | `donut` |
| `maxCategories` | Numeric config | No | Maximum categories shown before remaining groups are combined. | `8` |
| `showLegend` | Expression editor | No | Whether the legend/count list is shown. | `true` |
| `showCount` | Expression editor | No | Whether record counts are shown. | `true` |
| `emptyText` | Plain text | No | Text shown when no data is available. | `No records found` |
| `colorMode` | Plain text | No | Color palette used by the chart. | `yeeflow` |
| `sortMode` | Plain text | No | Category sorting behavior. | `countDesc` |
| `filterExpression` | Expression editor | No | Optional query filter object, array, or JSON value. | `[{"field":"Status","operator":"neq","value":"Closed"}]` |
| `height` | Numeric config | No | Minimum chart area height in pixels. | `280` |
| `pageSize` | Numeric config | No | Maximum records queried for aggregation. | `500` |
| `unknownLabel` | Plain text | No | Label used when the category value is empty. | `Unknown` |
| `otherLabel` | Plain text | No | Label used for categories beyond the maximum. | `Other` |

## Detailed Parameter Explanation

### `dataListId`

The Yeeflow data list ID to query. This should point to the list that contains the records you want to summarize.

This parameter uses the expression editor so it can be configured from a static value, variable, temp variable, or expression result. The runtime value is normalized safely before the query runs.

### `categoryField`

The field ID or field name used for grouping records. For example, if you set `categoryField` to `Status`, all records with the same Status value are counted together.

Use the actual field ID/name that Yeeflow returns in list query results. The code reads common row shapes defensively, including direct fields, `values`, `Fields`, and array-style field values.

### `titleText`

Optional title displayed at the top of the module. This is display text only, so a plain text value is recommended.

### `subtitleText`

Optional helper text shown under the title. Use it to explain the data scope, such as "Open cases by source" or "Inventory grouped by warehouse zone."

### `chartType`

Controls the chart presentation.

Supported values:

- `donut`
- `pie`
- `horizontalBar`
- `bar`
- `verticalBar`

If blank or invalid, the module uses `donut`.

### `maxCategories`

Limits how many categories are displayed. If there are more categories than the configured maximum, the remaining categories are combined into the `Other` group.

Default: `8`

### `showLegend`

Controls whether the legend/count list appears beside or below the chart.

This parameter uses the expression editor and supports values such as `true`, `false`, `1`, `0`, `yes`, and `no`.

### `showCount`

Controls whether numeric record counts are shown in the chart labels and legend rows.

This parameter uses the expression editor and supports dynamic true/false values.

### `emptyText`

Text shown when the query succeeds but no records or categories are available.

### `colorMode`

Controls the chart palette.

Supported values:

- `yeeflow`
- `soft`
- `status`
- `slate`

Default: `yeeflow`

### `sortMode`

Controls category order.

Supported values:

- `countDesc`: largest groups first
- `countAsc`: smallest groups first
- `labelAsc`: A to Z
- `labelDesc`: Z to A
- `source`: first-seen order from the returned records

Default: `countDesc`

### `filterExpression`

Optional filter passed to the list query. This can be a JSON string, object, array, variable, or temp variable from the expression editor.

The template passes common filter aliases (`filters`, `filter`, `where`, and `filterExpression`) because exact Yeeflow query filter support may differ by runtime. If the filter shape is not supported by the current tenant/runtime, leave this parameter blank or adjust the filter format to match that environment.

### `height`

Minimum chart area height in pixels. Use this to align multiple dashboard modules visually.

Default: `280`

### `pageSize`

Maximum number of records queried for aggregation. Increase it for larger lists, but keep dashboard performance in mind.

Default: `500`

### `unknownLabel`

Label used when a record has no value in the category field.

Default: `Unknown`

### `otherLabel`

Label used when categories beyond `maxCategories` are combined.

Default: `Other`

## Step-By-Step Setup Guide

1. Add a Custom Code control to a Yeeflow dashboard page.
2. Open the code editor and paste the `distribution-chart-module.tsx` code.
3. Set `dataListId` to the target data list ID.
4. Set `categoryField` to the field ID/name to group by.
5. Add a clear `titleText`, such as `Stock Status Distribution`.
6. Choose a `chartType`, such as `donut` or `horizontalBar`.
7. Set `maxCategories`, `showLegend`, and `showCount` based on the dashboard layout.
8. Optionally configure `filterExpression` to limit which records are included.
9. Preview the dashboard and confirm the chart shows the expected counts.
10. Publish the dashboard when the result is correct.

## Result / Expected Output

After configuration, users see a dashboard card with:

- title and optional subtitle
- donut, pie, horizontal bar, or vertical bar chart
- total record count
- optional legend with category percentages and counts
- empty/loading/error states when appropriate

The template reads records from the configured data list and displays aggregated counts. It does not save values back to fields or variables.

## Real Business Examples

### Stock Status Distribution

Group inventory records by `StockStatus` to show how many items are Available, Low Stock, Reserved, or Out of Stock.

### Warehouse Zone Distribution

Group assets or stock items by `WarehouseZone` to show where operational volume is concentrated.

### Request Source Type

Group service requests by `SourceType`, such as Email, Portal, Phone, Partner, or Internal.

### Department Ownership

Group open tasks, approvals, or cases by `Department` so managers can quickly see workload distribution.

## Notes / Assumptions / Limitations

- The template is optimized for dashboard display and does not write output values.
- The query uses `yeeSDKClient.lists.queryItems(...)`.
- The code sends common query payload aliases for compatibility, but the exact filter format may vary by Yeeflow runtime.
- The module counts returned records; it does not perform server-side grouping.
- Very large lists should use a reasonable `pageSize` or a dashboard-specific filtered list for performance.
- Empty category values are grouped under `Unknown` or the configured `unknownLabel`.
- Categories beyond `maxCategories` are combined under `Other` or the configured `otherLabel`.

## Testing Checklist

- Confirm the module renders on a dashboard page.
- Confirm `dataListId` loads the correct data list.
- Confirm `categoryField` groups records correctly.
- Test `donut`, `pie`, `horizontalBar`, and `verticalBar`.
- Test `showLegend = true` and `showLegend = false`.
- Test `showCount = true` and `showCount = false`.
- Test empty/null category values.
- Test `maxCategories` with more categories than the limit.
- Test empty data state.
- Test missing configuration state.
- Test a valid `filterExpression` if filters are used.
- Test mobile or narrow dashboard widths.

## Troubleshooting

### The chart says to configure Data List ID and Category Field

Check that `dataListId` and `categoryField` are both configured. If using expression editor values, confirm the expression returns a real list ID and field ID/name.

### The chart shows no data

Confirm the data list contains records and the selected category field has values. Also check whether `filterExpression` is excluding all records.

### Counts do not match expectations

The template counts records returned by `queryItems`. Check `pageSize`, filters, and whether the data list has more records than the query limit.

### Category labels look wrong

Confirm that `categoryField` is the correct Yeeflow field ID/name. Some fields return object values, lookup values, or display text; the template normalizes common shapes, but custom fields may need the exact field key.

### Filter does not work

Filter support can vary by Yeeflow runtime. Try leaving `filterExpression` blank first. Then test the filter shape expected by your specific data list query environment.
