VelocityScatter

rendered, live
the wire — click a line to scrub
the contract — VelocityScatter in catalog.json
{
  "type": "object",
  "properties": {
    "component": {
      "const": "VelocityScatter"
    },
    "label": {
      "$ref": "https://a2ui.org/specification/v1_0/common_types.json#/$defs/DynamicString",
      "description": "The chart's title and accessible name. Required."
    },
    "xLabel": {
      "type": "string",
      "description": "X axis meaning, e.g. 'Support volume'. Required — an unlabelled axis is unreadable."
    },
    "yLabel": {
      "type": "string",
      "description": "Y axis meaning, e.g. 'Sentiment'. Required."
    },
    "subjectKind": {
      "type": "string",
      "description": "What the points are. Default 'account'; merged into pointAction context with the point's id.",
      "default": "account"
    },
    "points": {
      "oneOf": [
        {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "The subject id this point drills to."
              },
              "label": {
                "type": "string",
                "description": "Human name, e.g. 'Acme Corp'. Required — points are read aloud, not just plotted."
              },
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "dx": {
                "type": "number",
                "description": "Momentum along x since the previous window. Raw signed number."
              },
              "dy": {
                "type": "number",
                "description": "Momentum along y since the previous window. Raw signed number."
              },
              "intent": {
                "enum": [
                  "good",
                  "bad",
                  "warning",
                  "info",
                  "neutral"
                ]
              },
              "weight": {
                "type": "number",
                "description": "Sizes the point, e.g. by revenue. Raw number."
              }
            },
            "required": [
              "id",
              "label",
              "x",
              "y",
              "dx",
              "dy"
            ],
            "additionalProperties": false
          }
        },
        {
          "$ref": "https://a2ui.org/specification/v1_0/common_types.json#/$defs/DataBinding"
        }
      ],
      "description": "The accounts as points with momentum vectors. Bind with {\"path\": ...} to stream."
    },
    "pointAction": {
      "$ref": "https://a2ui.org/specification/v1_0/common_types.json#/$defs/Action",
      "description": "Fired on point activation. subjectKind, subjectId (the point's id), pointLabel, x, and y are merged into its context automatically."
    }
  },
  "required": [
    "label",
    "xLabel",
    "yLabel",
    "points"
  ]
}
the prompt-pack — paste into your agent
### VelocityScatter — accounts as points with momentum vectors

Where every account is and which way it's moving. Axis labels are required — an unlabelled axis
is unreadable.

| prop          | type                  | notes                                                 |
| ------------- | --------------------- | ----------------------------------------------------- |
| `label`       | string, required      | title and accessible name                             |
| `xLabel`      | string, required      | e.g. `"Support volume"`                               |
| `yLabel`      | string, required      | e.g. `"Sentiment"`                                    |
| `subjectKind` | free string           | what the points are, in your words; default `"item"`  |
| `points`      | point[] \| `{"path"}` | shape below; bind to stream                           |
| `pointAction` | action                | subject + `pointLabel`, `x`, `y` merged automatically |

Point shape — `id`, `label`, `x`, `y`, `dx`, `dy` required; `weight` sizes (e.g. by revenue),
`intent` judges:

```
{"id":"acct-acme","label":"Acme Corp","x":84,"y":32,"dx":9,"dy":-12,"intent":"bad","weight":480000}
```

```
{"id":"velocity","component":"VelocityScatter","label":"Account health velocity","xLabel":"Support volume (30d)","yLabel":"Sentiment","points":{"path":"/accounts"},"pointAction":{"event":{"name":"account_drilled","context":{"board":"velocity"}}}}
```