# Inputs and visuals

> Expose clear settings, organise them, and choose the right plot for each output.

Inputs are the settings traders see when they click the gear on a script's legend
row. Give them clear labels and sensible ranges; defaults should produce a useful
chart without any configuration.

```flowscope
script "MA spread"

input (
  fastLength = input.int(12, title: "Fast length", min: 1, max: 200)
  slowLength = input.int(26, title: "Slow length", min: 2, max: 400)
  bullishColor = input.color(color.green, title: "Bullish")
  bearishColor = input.color(color.red, title: "Bearish", sameLine: true)
)

data chart = subscribe(data.ohlcv)

plot spread = plot.histogram(title: "MA spread")

on chart.close {
  let fast = ta.ema(chart.close, fastLength)
  let slow = ta.ema(chart.close, slowLength)
  let value: float? = fast == null || slow == null ? null : (fast ?? 0.0) - (slow ?? 0.0)
  spread.plot(value, color: (value ?? 0.0) >= 0.0 ? bullishColor : bearishColor)
}
```

A vertical histogram without `on:` gets its own pane automatically, named after the
script. Other plots go on the price pane unless you declare a `pane` and pass `on:`.

## Input kinds

| Constructor | Value | Notes |
|---|---|---|
| `input.int(default, min:, max:)` | `int` | A number field. |
| `input.float(default, min:, max:)` | `float` | A number field. |
| `input.bool(default)` | `bool` | A switch. |
| `input.color(default)` | `color` | A colour picker. |
| `input.select(default, options: [...])` | `string` | A dropdown of text options. |
| `input.timeframe(default)` | `timeframe` | A timeframe. |
| `input.exchange(default)`, `input.exchanges(default)` | `string`, `string[]` | Exchange pickers. |

Every input takes `title:`, `description:` (a tooltip), `key:` (keeps saved settings
when you rename the binding), `sameLine:` and `when:` (show the input only when a
condition on other inputs holds). Changing an input re-runs the script over the
loaded history.

On a chart, the settings dialog edits number, switch, colour and dropdown inputs;
timeframe and exchange inputs keep their defaults there.

## Organise long settings

Layout rows are written without a binding:

```flowscope
script "Organised settings"

input (
  input.section(title: "Trend")
  trendLength = input.int(50, title: "Length", min: 2)
  showTrend = input.bool(true, title: "Show", sameLine: true)
  input.section(title: "Signals")
  signalStyle = input.select("Markers", title: "Style", options: ["Markers", "Background"])
)

data chart = subscribe(data.ohlcv)

plot (
  trend = plot.line(title: "Trend", color: color.blue)
  marks = plot.marker(title: "Above trend", shape: shape.circle, color: color.teal, size: 6.0)
  bg = plot.bg(title: "Above trend", color: #26A69A18)
)

on chart.close {
  let avg = ta.sma(chart.close, trendLength)
  trend.plot(showTrend ? avg : null)
  let above = (chart.close ?? 0.0) > (avg ?? 0.0)
  if above && signalStyle == "Markers" {
    marks.plot(chart.high)
  }
  if above && signalStyle == "Background" {
    bg.plot()
  }
}
```

For a visibility switch, keep the plot declared and feed it `null` when hidden, as
`trend` does above, so the script's outputs stay the same.

## Choose the plot

| Plot | Use it for |
|---|---|
| `plot.line` | Averages, bands, oscillators. `style:` `linestyle.dotted`, `dashed` or `step`; `area: true` shades below. |
| `plot.histogram` | Signed quantities such as delta, from zero, coloured per bar. |
| `plot.candle`, `plot.bar` | OHLC of another series, such as a higher timeframe or a synthetic index. |
| `plot.point` | Sparse values as dots. |
| `plot.marker` | Events at a price, with a `shape:`. |
| `plot.arrow` | Up or down events; the value's sign is the direction. |
| `plot.label` | Short text at a price. |
| `plot.bg` | Tint the bars where a condition holds. |
| `plot.cells` | Rows of cells inside each bar: footprints, per-bar profiles, ladders. |
| `fill.between` | Shade between two lines. |

Free-form drawings (lines, boxes, labels anchored to the pane) are entity pools; see
[repainting](/docs/scripting/guides/repainting#drawing-at-the-live-edge) for the
pattern of drawing at the live edge.

## Cells inside a bar

`plot.cells` draws rows of cells inside each bar: a price band, a width, colours and
a number. It keeps them for far more bars than box entities can. This is a bid x ask
footprint on rows of 25, with the chart's candles as a thin strip beside it:

```flowscope
script "Footprint cells"

data (
  chart = subscribe(data.ohlcv)
  vol = subscribe(data.volume)
)

plot footprint = plot.cells(
  title: "Bid x Ask",
  columns: 2,
  candles: cellcandles.side,
  format: cellformat.fixed,
  decimals: 2,
)

on chart.update {
  let rows = vol.bucketsByStep(25.0)
  if rows != null {
    footprint.clear(time: rows.time)
    for row in rows {
      footprint.cell(row.from, row.to, weight: row.sell, value: row.sell, color: #e0443a80, column: 0,
        align: align.right, time: rows.time)
      footprint.cell(row.from, row.to, weight: row.buy, value: row.buy, color: #2fa66a80, column: 1,
        time: rows.time)
    }
  }
}
```

- **Columns.** A bar has 1 to 4 columns side by side; `column:` picks one, `align:`
  the edge a cell's width grows from.
- **Width.** `weight:` is compared as the plot's `scale:` says: with the largest
  weight on its own bar (`cellscale.bar`, the default), with the largest on the
  visible bars (`cellscale.view`), or taken as the width itself from 0 to 1
  (`cellscale.unit`). Without a weight the cell fills its column.
- **Numbers.** `value:` is written in the cell when it fits. `format:`, `decimals:`,
  `sign:` and `grouping:` choose `3.21K`, `3214.56`, `+3,215` or `15.3%`; a bar too
  narrow for that is written with fewer digits.
- **Candles.** `candles:` leaves the chart's candles as they are
  (`cellcandles.overlay`), draws them as a thin strip at the left of each bar
  (`cellcandles.side`) or hides them (`cellcandles.hidden`).
- **Steps.** The first `cell` or `clear` for a bar in a handler call discards what
  the bar held before, so a script redraws a bar by writing it again. Call `clear`
  where a bar may end up with no cells.

`bucketsByStep` puts the rows on whole multiples of the step, so the same price is
the same row on every bar. A bar holds up to 1024 cells per plot.
