Every kScript (legacy) construct beside the Indicator form that replaces it, grouped by lifetime: a value on every bar, a snapshot of the finished run, or an object that keeps its identity while you move it. From kScript covers the numeric core of a port; this page carries the rest: plots and style words, text and tables, profiles and panels, drawing objects and their mutation, pane anchors, frame snapshots, sources, and the constructs with no home yet.
The same AssemblyScript module compiles once and runs on your machine and in
the chart tab; source: "series" inputs require the daemon.
In code-first packages, declarations in src/indicator.ts produce the sheet
at wrun/metadata.json. Import declarations from ./sdk/declare, read named
in_* accessors in state(), and write out_* values followed by emitRow()
in finalize(). Numeric outputs remain metrics, including data-only outputs.
The current line declaration is output("close", line, overlay). There is
no out.line declaration in this SDK; out.inset is available. A table cell
marked sheet only has no equivalent code-first declaration today.
Time series, shapes and backgrounds
Declare the presentation once, then write one numeric value per ready bar.
| kScript | Sheet field | Code-first call | Difference |
|---|---|---|---|
plot(value, plotType=...) | outputs[].plot and .panel | output(name, line, overlay) or the matching plot identifier | Kind is fixed in the declaration; overlay draws on price, lower in the script pane. The browser places the whole package by its first drawn output (or the sheet overlay override): numeric outputs of one package cannot split across panes. |
plotLine(value, ...) | outputs[]: { plot: "line", color, width, line_style, opacity } | output(name, line, overlay, options) | One number per bar; no smooth or glow output option. |
plotLine(value, fill=true) | ranges[]: { upper, lower } over two outputs | range(upperName, lowerName, options) | The browser draws a filled band between two declared outputs; a single plot: "area" output renders as an unfilled line today (no overlay area renderer). |
plotBar(value, ...) | outputs[].plot: "bar" | output(name, bar, lower) | One scalar per bar; a [low, high] span becomes a box() instead. |
plotHistogram(value, base=...) | outputs[].plot: "histogram" | output(name, histogram, lower) | Baseline is zero; emit distance from a baseline or use box() for an absolute span. |
plotCandle([o,h,l,c], ...) | boxes[] body plus segments[] wick | box(name, { top, bottom, ... }) and segment(name, { yFrom, yTo, ... }) | No four-output OHLC binding, even though plot: "candle" is accepted. |
plotShape(value, shape, ...) | renderers[]: { kind: "shape", output, shape, where? } | render.shape(name, { output, shape, where }) | One mark per ready bar; where is a finite, nonzero gate. |
plot(plotType="point") | renderers[]: { kind: "shape", output, shape } | render.shape(name, { output, shape: "circle" }) | One mark per ready bar at the output value; a plot: "scatter" output renders as a connected line today. Use panel.scatter for numeric x/y pairs. |
hline(value, ...) | outputs[].plot: "line" | output(name, line, lower) and out_<name>(value) on every ready bar | No separate horizontal-line primitive; an extended line handle also works. |
plotBgColor(color, forceOnChart?) | renderers[]: { kind: "bgcolor", where, color?, color_by?, colors? } | render.bgcolor(name, { where, color, color_by, colors }) | Per-bar background tint; a gate selects the bar. No forceOnChart option on this renderer. |
barcolor(color) | No candle-recolor field | No direct call; render.bgcolor(...) is the nearest tint | Background tint does not recolor candle bodies. |
plotBatches(count, fn) | No batched plot field; handles, levels[] or panels[] serve different lifetimes | Loop over handle calls, or declare plot.levels(...) / panel.*(...) | Handles keep a bounded live set; frames replace a snapshot, not a history of batches. |
plotPie(value, price, radius, ...) | No per-bar pie field; panels[].kind: "pie" is a snapshot alternative | panel.pie({ name, title, x: "category", place, frame }) | A panel pie has up to 24 slices and no bar-time/price/radius placement. |
A compact plotBar / plotLine strip | outputs[]: { plot: "inset", inset: { dock, height_px?, shape? } } | out.inset(name, { dock: "bottom", height_px: 28, shape: "histogram" }) | Keeps every ready row in a pane strip; 16..120 px tall, top or bottom, histogram/area/line. |
render.shape supports circle, cross, triangle_up, triangle_down,
diamond, arrow_up, arrow_down, flag and square. kScript's character
marks use text instead. For above/below-bar marks, compute the y output;
for fixed pane placement, use anchored handles.
Style words
| kScript | Sheet field | Code-first call or option | Difference |
|---|---|---|---|
colors + per-bar colorIndex; colorGradient(...) / palette(...) used to choose a color | outputs[].color_by + .colors | output(name, line, overlay, { color_by: "tone", colors: [...] }) | Emit the palette index as another numeric output; there is no built-in gradient/palette helper. |
Per-bar width | outputs[].width_by + .widths | output(name, line, overlay, { width_by: "weight", widths: [...] }) | A ladder of 1..10 widths, each 0.5..20; no arbitrary per-bar width field. |
lineStyle, constant opacity | outputs[].line_style, .opacity | output(name, line, overlay, { line_style: "dashed", opacity: 0.6 }) | Static series style; handle setters can change individual objects. |
label, desc, forceOnChart | Output name, description, panel | output(name, line, overlay, { description }) | Placement belongs to each output; there is no script-wide plot call. |
| Redraw-only style inputs | params[].style: { output, property } | Sheet only | A style parameter changes presentation without reaching the module; compute parameters remain numeric. |
zOrder, set_zorder | Handle zOrder after mutation; widget z | Handle .zorder(n); draw.card, draw.feed, draw.meter option z | Numeric plots and declared coordinate drawings have no general zOrder option. |
Palette and width indexes are floored; a finite out-of-range index selects entry zero. A non-finite width index keeps the static width. A non-finite background color index selects no tint. Names of palette and gate outputs must differ from the output they control.
Text, labels and tables
String slots carry text per bar; the renderer decides which rows remain visible.
| kScript | Sheet field | Code-first call | Difference |
|---|---|---|---|
plotText(text, price, ...) | string_slots[] plus renderers[]: { kind: "text", y, text, color?, size? } | string(slot, { max_bytes }); render.text(name, { y, text: slot, color, size }) | One mark for each ready row with a present slot; even a present empty string is a write. |
plotPriceLabel(price, text, ...) | Text renderer with style: "price_label" | Sheet only for style; render.text declares plain text | wrun-3 or later; no tooltip, URL/SVG icon or pill-position options. |
plotLabel(text, position, x, y, ...) | renderers[]: { kind: "label", text, position }, or handles.label.anchor and handles.label.align | Sheet only for renderer position; handles.label({ text: slot, anchor: "top_left", align: "left" }) for movable pixel placement | Renderer keeps the latest nonempty text; a handle copies text when drawn, supports pixel offsets, and align picks which text edge sits on x. |
plotTable(data, position, ...) | renderers[]: { kind: "table", rows, cols, cells, position } | render.table(name, { rows, cols, cells, position }) | Snapshot from the latest ready row with every cell slot present; up to 32 rows and 8 columns, within the shared 64-slot limit. |
table.new(...), setCell(...) | panels[]: { kind: "table", frame, series, ... } or the table renderer above | panel.table({ name, title, x: "category", place, series, frame }) | Write the whole frame instead of mutating cells; styled cells support text, color, an inline bar and spark. |
plotStatRow(value, title, format, polarity, priority) | renderers[]: { kind: "stats_row", output, title?, format?, polarity? } | render.stats_row(name, { output, title, format, polarity }) | Per-bar strip values, including NaN gaps; no priority option. |
A small plotTable / plotTiles status card | drawings[]: { kind: "card", title, rows, anchor?, offset?, z?, state_by? } | draw.card(name, { title, rows, anchor, offset, z, state_by }) | Up to 8 cards with 12 rows each; latest complete ready row wins, with an incomplete-row fallback. |
| A chart inside a table cell / card row | Panel cell spark: [values...]; card row spark: { output, window } | panel.table(...) frame cell; draw.card(...) row spark | Frame sparks contain 1..64 finite numbers; card sparks select the last 2..64 ready output values. |
A text renderer's size is 6..64 integer pixels. At most 64 string slots
share the sheet, each with max_bytes of 1..4096. Write through generated
str_<slot>() or the reusable sb_* builder and str_<slot>_sb().
Omitting a string write is different from writing an empty string.
Profiles, panels and compact widgets
Frames carry the whole snapshot, including category or numeric axes independent of bar time.
| kScript builtin or idiom | Sheet field | Code-first call | Difference |
|---|---|---|---|
plotBatches of plotBar, plotShape, plotRange or plotPriceLabel used as a docked profile | levels[]: { name, frame, dock, width_frac?, poc?, labels?, color? } | plot.levels({ name, frame, dock: "right", width_frac: 0.12 }) | One docked snapshot, up to 512 strictly monotonic prices; width fraction 0.05..0.5. |
plotCurve(..., style="bars") | panels[].kind: "bars" | panel.bars({ name, title, x, place, series, frame, orientation?, stacked? }) | Up to 8 series and 2000 rows; keys are categories, integer indexes or epoch seconds. |
plotCurve(..., style="line") | panels[].kind: "line" | panel.line({ name, title, x, place, series, frame, stacked? }) | Snapshot lines over category/index/time keys; arbitrary fractional x uses scatter. |
plotCurve / plotShape used for numeric x/y points | panels[].kind: "scatter" | panel.scatter({ name, title, x: "index", place, frame }) | [key, x, y, size?, color?, label?]; x/y are finite numbers and each point may carry style. |
plotCurve(..., style="bars") used for a distribution | panels[].kind: "histogram" | panel.histogram({ name, title, x: "category", place, frame, bins?, orientation? }) | Supply [binLabel, nonnegativeCount] rows; bins is 2..200, not automatic binning of raw samples. |
plotPie(...) shown as one summary | panels[].kind: "pie" | panel.pie({ name, title, x: "category", place, frame, hole? }) | Snapshot slices [name, nonnegativeValue, color?]; at most 24, hole 0..0.8. |
plotMatrix(...); heatmaps made from colored plotCandle cells | panels[].kind: "heatmap" | panel.heatmap({ name, title, x: "category", place, frame }) | Up to 2000 [xKey, yKey, valueOrNull] cells; no separate summary/highlight fields. |
plotTable(...), table.new(...) as a side data table | panels[].kind: "table" | panel.table({ name, title, x: "category", place: "side", series, frame }) | At most 32 rows and 8 columns; row cells match series exactly, with no extra key cell. |
plotTiles(...) | panels[].kind: "tiles" | panel.tiles({ name, title, x: "category", place, frame }) | At most 24 [label, value, caption?, color?, spark?] tiles; no columns/accent/format declaration. |
plotMiniChartGrid(...) | No OHLC mini-grid field; panels[].kind: "line" or a card spark provides a simpler view | panel.line(...) or draw.card(...) | Panels use below/side, not arbitrary viewport grid geometry; no candle-grid binding. |
plotTable / plotPriceLabel used for an order ladder | drawings[]: { kind: "ladder", frame, side, divider? } | draw.ladder({ name, frame, side: "right", divider? }) | One snapshot with 1..64 [price, value, fraction, color?] rows; fraction is 0..1. |
plotText / table.new used as a recent-events feed | drawings[]: { kind: "feed", frame, anchor?, offset?, z? } | draw.feed({ name, frame, anchor, offset, z }) | Snapshot of 1..50 [epochMilliseconds, text, color?] lines; text 1..80 characters. |
plotShape / plotTable used as a progress gauge | drawings[]: { kind: "meter", label, fraction: { output }, ramp, text?, ... } | draw.meter({ name, label, fraction: { output }, ramp, text, anchor, offset, z }) | Latest ready numeric output, not a frame; produce 0..1 and choose 2..5 ramp colors. |
Every panel binds a declared frame and uses place: "below" or "side".
At most eight panels and four level profiles share a sheet. Bars, line and
table require 1..8 series entries; the other panel kinds forbid series.
Histogram and heatmap require x: "category".
Panel table cells accept a number, a string of at most 64 characters, or
{ text?, color?, bar?, spark? }. A cell bar is a fraction in 0..1.
Cards, feeds and meters default to anchor: "top_right", offset: [0, 0]
and z: 0; offsets are integers in -200..200. Ladder placement uses side.
Drawing objects and mutation
Declare each handle kind once, create objects with distinct ids, and reuse those ids to move or delete them.
| kScript | Sheet field | Code-first declaration and runtime call | Difference |
|---|---|---|---|
line.new(x1,y1,x2,y2,opts) | handles.line | handles.line({ panel: "overlay" }); draw.line(id).set(x1,y1,x2,y2) | Chart x uses epoch seconds, not kScript milliseconds; extension past the loaded range is allowed. |
box.new(left,top,right,bottom,opts) | handles.box | handles.box({ color, borderColor, opacity }); draw.box(id).set(left,top,right,bottom) | Persistent object; boxes[] / box(...) instead produces one declarative shape per bar. |
label.new(time,price,text,opts) | handles.label plus string_slots[] | handles.label({ text: "note", size: 12, align: "left" }); draw.label(id).set(x,y).text(str_note_sb) | Text is copied from the slot write on that call; position alone does not create the label. align (left, center, right) is the text edge on x; omitted centres. |
polyline.new(points,opts) | handles.polyline | handles.polyline({ color, width }); draw.polyline(id).setPoints(points,count) | Reuse a StaticArray<f64> of x/y pairs; 1..256 points per handle. |
linefill.new(line1,line2,opts) | No linefill handle kind | No direct call; box(...) slices or box handles approximate a fill | No object that tracks a fill between two moving line ids. |
table.new(position,rows,cols,opts) | No table handle kind | render.table(...), panel.table(...) or draw.card(...) | Replace a selected table/card snapshot; no set_position() or table-handle deletion. |
plotRange(time1,price1,time2,price2,...) | boxes[], or drawings[].kind: "box", or handles.box | box(name, { top, bottom, from, to }), draw.box(name, {...}), or a box handle | Per-bar boxes use offsets within ±500 bars and clamp to loaded data; handles use absolute coordinates. |
Last-bar line.new, box.new, label.new, polyline.new without ongoing identity | drawings[] with the corresponding kind | draw.line, draw.box, draw.label, draw.polyline from ./sdk/declare | Declared coordinates name outputs; only the last ready row selects the object, with up to 64 polyline points. |
The two draw imports have different jobs: ./sdk/declare declares a
run-level drawing, while ./gen/draw operates on handles. Alias one when
using both. Allocate each generated handle object once at module scope or
in init(), and call its geometry/style methods in finalize().
| kScript mutation | Generated handle method | Rule |
|---|---|---|
Line set_xy, set_xy1, set_xy2 | .set(...), .setXy1(...), .setXy2(...) | Create with .set(...) before a partial setter. |
Line/polyline set_color, set_width, set_style | .color(rgba(...)), .width(n), .style(LineStyle.Dashed) | Width 0.5..20; line styles solid, dashed, dotted. |
Line set_extend | .extend(Extend.Right) | None, Left, Right or Both. |
Box set_bounds, set_lefttop, set_rightbottom | .set(...), .setLeftTop(...), .setRightBottom(...) | Geometry updates keep the same id. |
Box set_bgcolor, set_border_color, set_border_width | .fill(rgba(...)), .color(rgba(...)), .border(n) | Border width 0..10; no box border-style setter. |
Label set_xy, set_text, set_color, set_bgcolor, set_size | .set(x,y).text(sender), .text(sender), .color(...), .fill(...), .size(n) | Send text on every position/text update; size 6..64 integer pixels. |
Label set_textalign | .align(ALIGN_LEFT), .align(ALIGN_RIGHT); ALIGN_DEFAULT restores centred text | The text edge that sits on x; (x, y) stays the point. Labels only. |
Line/box/label set_opacity, set_zorder | .opacity(n), .zorder(n) | Opacity 0..1; z-order is an integer. |
Polyline set_points | .setPoints(points,count) | Re-emits the entire point list under the same id. |
Line/box/label/polyline delete() | .delete() | Frees the shared id; a missing id is harmless. |
All four kinds share one nonnegative id space. Caps are 500 live handles per kind, 1500 total, and 4096 draw calls per row. Delete expired objects explicitly. A cap breach refuses the run; the host never silently drops drawings. Declarative caps are 16 boxes, 16 segments, 32 renderers and 64 drawings, including cards, ladders, feeds and meters.
Pane anchors
handles.line|box|label|polyline({ anchor: "top_left" }) sets the default
for new handles. After creation, .anchor(ANCHOR_TOP_LEFT) changes it;
import the constant from ./gen/draw. .anchor(ANCHOR_CHART) restores
chart coordinates even when a default anchor is declared. A label adds
align (left, center, right): the text edge that sits on x, with
(x, y) staying the point; handles.label({ align: "left" }) is the
default, .align(ALIGN_RIGHT) changes a live label, and
.align(ALIGN_DEFAULT) restores centred text.
| Anchor | x coordinate | y coordinate |
|---|---|---|
Absent / ANCHOR_CHART | Epoch seconds | Price |
Nine pane spots, top_left through bottom_right | CSS pixels from left, centre or right | CSS pixels from top, middle or bottom |
top, bottom | Epoch seconds | CSS pixels from that edge |
left, right | CSS pixels from that edge | Price |
Left/top offsets point right/down; right/bottom offsets point left/up. Centre offsets are signed, and negative offsets are legal. Coordinates start at the pane's content rectangle and clip to that pane. A pane anchor keeps a HUD in place while the chart pans; it is not a timestamp offset.
Frame snapshots
Declare frame(name) once and call generated writeFrame(slot, json) in finalize() to replace that run's snapshot.
| Sheet or operation | Code-first word | Lifetime and bound |
|---|---|---|
frames: [{ name, max_bytes? }] | frame("profile"), optionally { max_bytes } | Up to 8 slots, each at most 96 KiB (98304 UTF-8 bytes). |
| Write the slot | writeFrame(FRAME_PROFILE, json) from ./gen/frames | Finalize only; newest write replaces the previous bytes across the entire run, not just the current bar. |
| Level profile frame | plot.levels({ frame: "profile", ... }) | { prices, values, colors? }, matching array lengths, 1..512 monotonic prices; null values are gaps. |
| Panel frame | panel.*({ frame: "summary", ... }) | { rows }, with the selected panel kind's tuple grammar; empty rows are legal. |
| Unwritten / invalid frame | No extra declaration | Unwritten consumers are absent; invalid written JSON or payload refuses selection with wrun_frame_invalid. |
Frames and per-row strings share a 2 MiB wrun-4 transport budget. Expanded
render selections have a separate 2 MiB cap, including panels, handles and
sparks. Frames are snapshots, so writing on every bar does not create a
history of frames. Accumulate what the snapshot needs in bounded guest
memory, then write it, commonly under bar.isLast().
Example: a docked profile and side bars
These declarations share a close output but bind two independent frames. The fixed payloads show the exact accepted shapes; computed aggregates use the same shapes.
import { frame, input, line, ohlcv, output, overlay, panel, plot } from "./sdk/declare";
import { in_close } from "./gen/inputs";
import { emitRow, out_close } from "./gen/outputs";
import { FRAME_PROFILE, FRAME_SIDES, writeFrame } from "./gen/frames";
import { bar } from "./gen/draw";
input("close", ohlcv.close);
output("close", line, overlay);
const profile = frame("profile");
const sides = frame("sides");
plot.levels({ name: "volume_levels", frame: profile, dock: "right", poc: true });
panel.bars({
name: "side_totals", title: "Volume by side", x: "category", place: "side",
series: [{ name: "Volume", color: "#38bdf8" }], frame: sides,
});
let closeValue: f64 = NaN;
export function init(): void {}
export function state(): i32 { closeValue = in_close(); return 1; }
export function finalize(): void {
out_close(closeValue);
if (bar.isLast()) {
writeFrame(FRAME_PROFILE, '{"prices":[100,101,102],"values":[8,21,13]}');
writeFrame(FRAME_SIDES, '{"rows":[["Buy",26],["Sell",16]]}');
}
emitRow();
}
export function reset(): void { closeValue = NaN; }The extractor selects wrun-4, resolves frame handles to names in the sheet,
and generates FRAME_* indexes. Frame declaration names, output names,
string-slot names and visual names must not collide.
Example: a box and label HUD
Both handles use pane pixels and retain their ids while the last close changes.
import { handles, input, none, ohlcv, output, overlay, string } from "./sdk/declare";
import { in_close } from "./gen/inputs";
import { emitRow, out_last_close } from "./gen/outputs";
import { sb_clear, sb_f64, sb_text, str_caption_sb } from "./gen/strings";
import { ALIGN_LEFT, ANCHOR_TOP_LEFT, bar, draw } from "./gen/draw";
input("close", ohlcv.close);
output("last_close", none, overlay);
string("caption", { max_bytes: 48 });
handles.box({ color: "#111827", borderColor: "#38bdf8", opacity: 1 });
handles.label({ text: "caption", color: "#ffffff", size: 12 });
const background = draw.box(0);
const caption = draw.label(1);
let closeValue: f64 = NaN;
export function init(): void {}
export function state(): i32 { closeValue = in_close(); return 1; }
export function finalize(): void {
out_last_close(closeValue);
if (bar.isLast()) {
background.set(12, 12, 200, 46).anchor(ANCHOR_TOP_LEFT);
sb_clear(); sb_text("Close "); sb_f64(closeValue, 2);
caption.set(20, 22).text(str_caption_sb).anchor(ANCHOR_TOP_LEFT).align(ALIGN_LEFT);
}
emitRow();
}
export function reset(): void { closeValue = NaN; }This sheet needs wrun-3, not a frame. Anchors are also available under wrun-4.
The label's .text(...) creates it before .anchor(...) and .align(...)
mutate it; ALIGN_LEFT starts the caption at x = 20 instead of centring it there.
Sources and the bar grid
Keep a market input at index zero; all other inputs align to its grid.
| kScript source or idiom | Sheet field | Code-first call | Difference |
|---|---|---|---|
source("ohlcv", ...) | inputSources.close: { source: "ohlcv", field: "close" } | input("close", ohlcv.close) | One field per named input; input zero supplies the primary grid. |
source("volume_profile", ...) | Source volume_profile; input cellType: "array", max_cells | input("profile", volume_profile.cells, { max_cells: 512 }) | Tuples are [low, high, buy, sell]; cap counts tuples, not f64 cells. |
source("orderbook", ...) | Source book, block_size, optional max_depth; celled input | input("book", book.cells, { max_cells: 128, block_size: 1 }) | Tuples are [price, abs(size), side], +1 bid / -1 ask; exact join to primary bars. |
source("trades", ...) raw tape | No raw tape source | input(name, trades.volume, { side: "BUY" }) for aggregates | The trades source means side-split period aggregates, not individual trade prints. |
source("trade_volume_by_size", ...) | Celled trade_volume_by_size vocabulary | input(name, trade_volume_by_size.cells, { max_cells }) | Declares successfully but this daemon refuses the unavailable data lane. |
Other-symbol source / request and higher-timeframe htf | inputSources[name].symbol, .exchange, .interval | input(name, ohlcv.close, { symbol, exchange, interval }) | Pins are daemon behavior; coarser direct feeds align as of candle close. Chart inputs use the chart market/grid. |
| Watch values or installed non-market readings, with no legacy builtin | inputSources[name]: { source: "series", ref, missing } | Sheet only; read generated in_<name>() | Daemon only, never primary; no series.* code-first source namespace. |
For source: "series", ref is watch/<slug>/<key> or an installed
@scope/name. missing is carry (default) or nan, never zero.
Readings bucket to the primary interval; the last reading in each bucket
wins. Carry uses the latest bucket at or before the bar; nan requires a
reading in that bar's own bucket. A series input has no field, selector,
params or interval pin and cannot densify the grid.
Example: a watch series sheet
Use a metadata-first workspace for this sheet. The generated
in_watch_flow() reads the watch value in state(); out_flow(value) writes
the plotted value in finalize() before emitRow().
{
"id": "watch-flow",
"name": "Watch flow",
"inputSources": {
"close": { "source": "ohlcv", "field": "close" },
"watch_flow": { "source": "series", "ref": "watch/flow/imbalance", "missing": "carry" }
},
"inputs": [{ "index": 0, "name": "close" }, { "index": 1, "name": "watch_flow" }],
"outputs": [{ "index": 0, "name": "flow", "plot": "line", "panel": "lower" }]
}Series inputs are ABI-neutral; the sheet above uses the wrun-1 default.
Add abi_version: "wrun-4" when the same module also declares frames.
No home yet
These legacy behaviors need a deliberate substitute; an accepted sheet field alone does not provide every legacy visual.
| kScript builtin or behavior | Missing Indicator word | Nearest workaround |
|---|---|---|
plotLine(..., fillGradient=...), gradient lines, momentum_fill, smooth, glow | No continuous gradient, smoothed-line or glow output option | Use stepped color_by/colors, or several bounded box/line layers. |
linefill.new(...) and its setters; gradient clouds | No linefill handle that tracks two moving line ids; no gradient fill | ranges[] (range(upperName, lowerName, options)) draws a flat filled band between two numeric outputs, with edge width, line style and palette; a fill between two line handles needs per-bar box() slices. |
Per-bar plotPie(...) and plot(plotType="pie") | No pie at each bar's time and price | Summarize the current values with panel.pie; it replaces one frame. |
plotCandle(...) OHLC binding; OHLC tick bars in plotMiniChartGrid | No four-output candle binding or OHLC mini-grid | Body boxes plus wick segments on the chart; panel.line or card sparks for compact history. |
plotMiniChartGrid grid, moving averages, badges and volume strips | No candle-panel grid or automatic MA/badge composition | Several bounded panels, a card with sparks, or anchored handles. |
barcolor(...) | No candle body recolor channel | render.bgcolor for a regime tint, or draw your own candle bodies. |
hline(...); plotHistogram(..., base=...) with a nonzero baseline | No dedicated hline or adjustable histogram baseline | Emit a constant line; subtract the baseline for zero-centred columns, or use absolute-price boxes. |
Arbitrary plotBatches per-bar payload arrays | No batched output channel | Bounded handle loops for retained objects; plot.levels, panels or ladders for snapshots. |
plotShape(shape="char"), special location/size behavior | No character-shape, relative-bar-location or size-output option on the shape renderer | render.text for characters, computed y for above/below bars, anchored label handles for pane placement. |
plotPriceLabel / label.new icons; set_icon, set_glow, set_tooltip; plot/table tooltips | No URL/SVG/image, glow or tooltip fields on these Indicator visuals | Text labels, captions or additional card/table rows. |
plotText / plotLabel font family, weight; rich table spans and headers | No matching typography, colspan/rowspan or header-style vocabulary (label handles do take align: left, center, right) | Use panel cells for basic text/color/bar/spark content, or anchored, aligned labels and boxes for explicit layout. |
Box set_border_style, table set_position / delete, line/label stickyRight | No matching object setters | Use styled line handles for borders, rebuild a frame for table content, or edge anchors for pixel-x/price-y placement. |
plotCurve marker "spot", markers and arbitrary fractional line x; plotMatrix summary/highlight; plotTiles columns/accent/format | No exact panel options for those legacy features | Scatter for fractional x; extra rows/series, formatted tile strings, and explicit colors for the annotations. |
requestBars(...) independent OHLC arrays; ltf(...) lower-timeframe arrays; unsupported registered source(...) classes | No general nested-bars or arbitrary source adapter | Use supported scalar/celled inputs, or prepare a daemon series and render an appropriate snapshot. |
String, symbol, color, select or other nonnumeric compute input(...) | No nonnumeric compute parameter channel | Numeric parameters, sheet-only style bindings, or metadata source pins. |
print(...) / log(...) console output | No guest console import | Emit a numeric diagnostic output or a bounded text/card row. |
The contracts behind this map live on their published pages: Plotting for outputs, renderers and declared drawings, Drawing objects for handles and their setters, Drawing primitives for pane anchors, frames, panels and the compact widgets, Data sources for the source classes, and the Limits reference for every cap. The ABI contracts a sheet names are on Script definition.