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 is | You use it to | |
|---|---|---|
crossfilter | what marks filter by | filter a widget of your own by the same brush |
selected | every chart clause on the page, flattened into one plain union | read — 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
| Field | Type | What it is |
|---|---|---|
coordinator | Coordinator | the caller's coordinator, also registered as vgplot's active one |
crossfilter | Selection | the shared selection marks filter by |
selected | Selection | every clause on the page, flattened — a read model |
registerSelection | (selection: Selection, options?: { relay?: boolean }) => () => void | enrol a selection of your own; returns the unregister |
reset | () => void | clear the shared selections and every registered chart selection |
Throws useMosaic must be used within a <MosaicProvider>. when there is no provider above it.