# Filters and drilldowns

Follow a chart selection into a list, a record and a nested destination.

Queries produce data. Charts encode that data. A dashboard visual instance owns
its interaction settings, so the same saved query/chart can filter one dashboard
and open a detail view on another.

## Authoring

Open a chart's menu and choose **Interactions**. Set **On selection** to filter
the current view, open a view as a side panel or page, or run a published workflow.
Map **Selected item** fields into declared parameters or workflow inputs. Source
and output metadata populate the field picker without executing the query.

An ordinary click, Enter or Space runs the primary action. **Additional actions**
appear on right-click, Shift+F10 or the keyboard menu key. When no primary action
exists, ordinary selection opens that menu. Menus and drawers preserve keyboard
focus. Editing a dashboard never executes these actions.

Filter actions update declared page parameters. Each chart receives only the
parameters declared by its query, so independent charts keep their result and do
not query again. A null mapping removes an override, restoring any declared
default. Navigation maps values to the destination's parameters and retains the
parent page when opening a drawer.

## Selections

`@bytesmap/core` exports `DataSelection`, a map of scalar values under `values`.
`@bytesmap/ui` chart renderers accept an optional
`onSelect(selection, { intent: 'activate' | 'menu' })` callback. Without a callback,
charts retain their ordinary passive behavior. SDK hosts can supply that callback
or use the shared page runtime and interaction dispatcher.

Selections use original result rows, including scalar IDs hidden from the chart.
Sorted tables select the displayed row. When a mark merges rows, only identical
fields shared by those rows remain available; reaggregated measures and ambiguous
IDs are omitted. Generated Other/gap marks do not invent a record identity.
Reserved prototype field names are excluded. Keep an explicit stable key in the
query output when a detail view or workflow needs it.

Bindings preserve field names exactly. A joined alias such as `users.id` is one
field, while `profile.id` may describe two nested segments. Known-field choices
retain that distinction; manual paths can use JSON arrays such as `["users.id"]`
or `["profile", "id"]`. Invalid path edits do not overwrite the committed binding.

## Events and application records

Use two source nodes: filter and summarize ClickHouse events by an explicit ID,
then connect the application table to the right side of a Join. Choose **Look up
matching records** to fetch only matching entity IDs in parameterized batches.
The result can contain `productId`, `productName`, `productImage` and `clickCount`,
with the interaction passing `productId` rather than the displayed name.

Lookup supports one equality key, left/inner joins and a directly connected
structured table. Aggregate first and index the lookup key. Existing general joins
retain multiple keys and other operators. See [cross-source queries](https://github.com/oblien/bytesmap/blob/main/docs/cross-source-queries.md)
for execution, precision and complete-result rules.

## Workflow execution

Visual workflows reuse the existing pinned action revision, bindings, execution
permissions and idempotency store. `workspaces.interact` accepts the visual/action
identity, selection and runtime context; the server retrieves the saved published
configuration. The browser cannot provide an alternative workflow definition.
Explicit refresh targets can include charts, application panels and source metrics.
Workflow after-effects reuse existing navigation/refresh/close behavior.

The shared host-session intent registry freezes resolved parameters, selection and
request keys across retries and component remounts. Reordered or unused selection
fields do not create another intent. Uncertain outcomes retain their key; a
different mapped input cannot silently replace that pending intent. Completion
from an older page, parameter set or publication cannot redirect the current page.
This in-memory recovery lasts for the host session; it does not claim exactly-once
delivery across a browser reload or a new independent user intent.

English/Arabic copy and RTL use the shared locale package. The editor, controls,
menus, focus and themes use the product UI library.
