# Graph 2D

An interactive Cartesian plane drawn with SVG. Plot any number of functions and points; drag to pan, scroll to zoom and hover to read values.

Pair it with `compileFn` from `@indoku/science` to plot expressions typed by the user. Discontinuities such as `tan(x)` are split automatically.

Group: Science

## Import

```tsx
import { Graph2D } from "@indoku/ui"
import { compileFn } from "@indoku/science"
```

## Examples

### Basic usage

Functions are plain JavaScript callbacks.

```tsx
function Graph2DBasic() {
  return (
    <Graph2D
      functions={[
        { fn: Math.sin, label: "sin x" },
        { fn: Math.cos, label: "cos x", color: "danger", dashed: true },
      ]}
    />
  )
}
```

### Points and viewport

Label key points and choose the initial area.

```tsx
function Graph2DPoints() {
  return (
    <Graph2D
      viewport={{ xMin: -2, xMax: 6, yMin: -4, yMax: 10 }}
      functions={[{ fn: (x) => x * x - 2 * x - 3, label: "x² − 2x − 3" }]}
      points={[
        { x: -1, y: 0, label: "root" },
        { x: 3, y: 0, label: "root" },
        { x: 1, y: -4, label: "vertex", color: "warn" },
      ]}
    />
  )
}
```

### Expression input

compileFn parses text without eval.

```tsx
function Graph2DExpression() {
  const [expr, setExpr] = useState("sin(x) / x")
  const result = useMemo(() => {
    try {
      return { fn: compileFn(expr), error: "" }
    } catch (e) {
      return { fn: null, error: (e as Error).message }
    }
  }, [expr])
  return (
    <div style={{ display: "grid", gap: 8 }}>
      <input value={expr} onChange={(e) => setExpr(e.target.value)} placeholder="f(x) = ..." style={{ padding: 6, fontFamily: "monospace" }} />
      {result.error && <small style={{ color: "crimson" }}>{result.error}</small>}
      <Graph2D functions={result.fn ? [{ fn: result.fn, label: `f(x) = ${expr}` }] : []} />
    </div>
  )
}
```

### Static

Turn off interaction and grid for a figure.

```tsx
function Graph2DStatic() {
  return <Graph2D interactive={false} grid={false} aspect={2} viewport={{ xMin: 0, xMax: 6.3, yMin: -1.5, yMax: 1.5 }} functions={[{ fn: Math.sin }]} />
}
```

## Props

### Graph2D

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `functions` | `GraphFunction[]` |  |  |
| `points` | `GraphPoint[]` |  |  |
| `viewport` | `GraphViewport` | `-10..10 on both axes` | Initial visible area. |
| `aspect` | `number` |  | Width / height. Default 16/10. |
| `interactive` | `boolean` |  | Drag to pan, scroll to zoom, hover to read values. Default true. |
| `grid` | `boolean` |  |  |

`*` = required. Style props and HTML attributes are accepted too.

## Accessibility

- Provide the same data as a table or equation in text for screen readers.

## Notes

- `CartesianCanvas` is an alias of `Graph2D`.

## See also

- Plot 2D: https://ui.indoku.org/docs/plot-2d
- Overview: https://ui.indoku.org/docs/chart
- Math: https://ui.indoku.org/docs/math
