Skip to Content
⚠️Active Development Notice: TimeTiles is under active development. Information may be placeholder content or not up-to-date.
DevelopmentFeaturesDynamic Filters

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

  • DataSourceSelector selects datasets individually or toggles all datasets in a catalog.
  • TimeRangeSlider combines date selection with a temporal histogram. It is hidden when the selected data has no visible temporal data.
  • CategoricalFilters renders enum-value dropdowns.
  • NumericRangeFilters renders 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.

ParameterWire formatExample
catalogNumeric catalog IDcatalog=1
datasetsComma-separated numeric dataset IDsdatasets=2,3
startDate, endDateDate stringsstartDate=2024-01-01
boundsJSON bounding box{"north":52.6,"south":52.4,"east":13.6,"west":13.2}
ffJSON categorical filters{"category":["Music","Art"]}
rfJSON 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.

Last updated on