# Scatter with brush
> Scatter plot of 270 runs with a drag-to-select brush; the summary rolls to the selection's medians and the legend toggles groups.
- Element: `<hf-scatter>`
- React: `import { HfScatter } from "@/components/lumesec/hf-scatter"`
- Collection: Pixel HD (https://elements.lumesec.ai/components/pixel-hd)
- Registry item: https://elements.lumesec.ai/r/hf-scatter.json
- Page: https://elements.lumesec.ai/components/pixel-hd/scatter



Live preview: https://elements.lumesec.ai/view/hf-scatter

```html
<hf-scatter></hf-scatter>
```

## Playground

Change a prop and the component updates. Props marked live animate to the new value; the others rebuild the element.

## Installation

```bash
npx shadcn@latest add @lumesec/hf-scatter
```

First time with the @lumesec registry? Register it once, or install by URL:

```bash
npx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json
npx shadcn@latest add https://elements.lumesec.ai/r/hf-scatter.json
```

## Usage

React:

```tsx
import { HfScatter } from "@/components/lumesec/hf-scatter";

export function Example() {
  return (
    <HfScatter />
  );
}
```

HTML:

```html
<script type="module" src="https://elements.lumesec.ai/cdn/hf-scatter.js"></script>

<hf-scatter></hf-scatter>
```

## Behaviour

Three hundred runs that settle in, glowing where they cluster. Drag a box to select and the summary rolls to the selection’s medians; the legend toggles models.

## API reference

### Attributes

| Attribute | React prop | Type     | Default              | Description                         |
| --------- | ---------- | -------- | -------------------- | ----------------------------------- |
| `label`   | `label`    | `string` | `Latency vs. output` | Heading text. Read once on connect. |

### Events

Events bubble and cross the shadow boundary unless the description says otherwise.

| Event    | React prop | Detail              | Description                                                                                                                                    |
| -------- | ---------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `select` | `onSelect` | `{ count: number }` | Fires when a brush drag ends. `count` is the number of visible points inside the box; a click without dragging clears the brush and reports 0. |

## Accessibility

* The canvas has `role="img"` and an `aria-label` with the point count and the current summary.
* The summary under the heading is an `aria-live="polite"` region.
* Legend entries are buttons with `aria-pressed`.
* The brush is pointer-only; there is no keyboard equivalent.
* Reduced motion: points appear in place without settling and the summary changes without rolling; legend fades still ease.

## Theming

The element reads your shadcn theme tokens through its shadow root, so light and dark follow your theme. The accent comes from `--lumesec`. See [Theming](/docs/theming).

This component reads `--border`, `--card`, `--foreground`, `--lumesec` and `--muted-foreground`.

To restyle only LumeSec elements, set the matching `--ui-*` overrides: `--ui-accent`, `--ui-border`, `--ui-fg`, `--ui-muted` and `--ui-surface`.

## Notes

* Data is built in: 270 seeded points in three groups labelled Opus, Sonnet and Haiku, on axes of 0–4 s latency and 0–4k output tokens.
* Hidden groups are left out of the summary and the selection count.
* The plot is 190px tall and fills the width.


