Dynamic Filters
The explore sidebar derives dataset-specific filters from detected field metadata and queries their values against the visible event subset. The implementation lives in apps/web/components/filters/event-filters.tsx.
Filter Components
DataSourceSelectorselects datasets individually or toggles all datasets in a catalog.TimeRangeSlidercombines date selection with a temporal histogram. It is hidden when the selected data has no visible temporal data.CategoricalFiltersrenders enum-value dropdowns.NumericRangeFiltersrenders numeric bounds.
Categorical and numeric controls appear only when exactly one dataset is selected. Their React Query hooks, useDatasetEnumFieldsQuery and useDatasetNumericFieldsQuery, receive the active filters and debounced map bounds so available values and ranges reflect the visible subset. The parent passes their results to the controls.
Enum candidates originate in schema detection. For current field selection and counts, follow useDatasetEnumFieldsQuery to /api/v1/datasets/[id]/enum-stats; do not maintain a second set of thresholds in UI code.
API Filters
The shared event query contract is EventFiltersSchema in apps/web/lib/schemas/events.ts; wire-format parsers live in lib/schemas/common.ts.
| Parameter | Wire format | Example |
|---|---|---|
catalog | Numeric catalog ID | catalog=1 |
datasets | Comma-separated numeric dataset IDs | datasets=2,3 |
startDate, endDate | Date strings | startDate=2024-01-01 |
bounds | JSON bounding box | {"north":52.6,"south":52.4,"east":13.6,"west":13.2} |
ff | JSON categorical filters | {"category":["Music","Art"]} |
rf | JSON numeric ranges | {"price":{"min":10,"max":50}} |
Encode JSON values as URL query parameters, for example with URLSearchParams. Numeric range endpoints accept null or omitted bounds for open-ended ranges.
Event routes use resolveEventQueryContext to resolve access and dataset interpretation. It calls buildCanonicalFilters to construct the shared filter representation, including date normalization and view scope constraints. URL filters are not an authorization boundary. Malformed filter JSON and invalid field keys are rejected rather than silently broadening the query.
URL State
useFilters in lib/hooks/use-filters.ts manages datasets, startDate, endDate, ff, and rf through nuqs. Catalog selection updates dataset IDs; it is not a separate catalog URL parameter in this hook. Changing datasets, including toggling a catalog’s datasets, clears both categorical and numeric filters.
Map position (lat, lng, zoom) and the selected event (event) have separate hooks, useMapPosition and useSelectedEvent. These URL-backed values make exploration state shareable.
ADR 0031 records the original design; the current implementation includes numeric ranges.