Kanzo UI
Hooks

useMosaic

The Mosaic context in one call — the coordinator, the two shared selections, and the reset a "Clear filters" button needs.

Brush the histogram, click a region, and the count in the group above moves with them. The button calls reset(), which is not the same as resetting the crossfilter — see reset().

Usage

useMosaic lives on the @kanzo-tech/ui/analytics subpath, never the root barrel: the Mosaic/DuckDB stack is heavy and its peers are optional, so import { Button } from "@kanzo-tech/ui" never pulls it in.

import { useMosaic } from "@kanzo-tech/ui/analytics";
const { coordinator, crossfilter, selected, registerSelection, reset } = useMosaic();

It reads the context MosaicProvider publishes, and throws outside one. useCrossfilter and useSelected return one field each; reach for this when you want more than one of them, or any of the three that only live here.

The two selections

A page has two shared selections, not one, and the difference is the whole reason both are on the context:

What it isYou use it to
crossfilterwhat marks filter byfilter a widget of your own by the same brush
selectedevery chart clause on the page, flattened into one plain unionread — a chip row, a readout

selected is relayed into crossfilter, so a clause published by a chart reaches both. It is not a publish target: a page-wide selection names columns other charts do not group by, and ChartHighlight reading one is a binder error waiting to happen.

reset()

Selection.reset() travels downstream only. Resetting crossfilter therefore clears the shared selections and leaves every chart still holding the pick it published upstream — the bars stay highlighted, the brush rectangle stays drawn, and nothing on the page explains why.

reset() clears both shared selections and every registered chart selection, so it is the call a "Clear filters" button wants. ChartRoot registers the selection it mints for you; a selection of your own registers with registerSelection.

coordinator

The coordinator you handed MosaicProvider, for the work the client protocol does not cover — a fixed topology to draw, a schema, a one-off read that no brush should change. It is deliberately outside the crossfilter.

A number that should follow the brush does not belong here. A widget that runs coordinator.query() in an effect looks correct on its first paint and then reports unfiltered totals beside filtered charts — which nobody reads as a stale widget, they read it as a broken crossfilter. Use useChartQuery, or ChartStat for the tile case.

registerSelection

Passing your own as to a ChartRoot means the root stops wiring it for you: its clauses are not relayed onward, and reset() cannot see it. registerSelection(selection, { relay: true }) buys both back, and returns the unregister — which is exactly an effect's cleanup.

Without relay, the selection is enrolled in reset() only. That is the right option for a selection you filter by but never want flattened into the page's read model.

The unregister also calls selection.reset(), so a chart that unmounts — a tab, a conditional — cannot leave its clause filtering a page with nothing left on screen to clear it.

API Reference

useMosaic(): MosaicContextValue

FieldTypeWhat it is
coordinatorCoordinatorthe caller's coordinator, also registered as vgplot's active one
crossfilterSelectionthe shared selection marks filter by
selectedSelectionevery clause on the page, flattened — a read model
registerSelection(selection: Selection, options?: { relay?: boolean }) => () => voidenrol a selection of your own; returns the unregister
reset() => voidclear the shared selections and every registered chart selection

Throws useMosaic must be used within a <MosaicProvider>. when there is no provider above it.

On this page