Surfaces
Pick where a script draws: on the price pane, in its own pane, or as the chart type.
surface picks where a script draws:
| Surface | Where | Frame | Price scale |
|---|---|---|---|
{ kind: "ChartOverlay", layer? } | the price pane, over or under the candles | ChartFrame | the price pane's |
{ kind: "ChartPane", weight? } | its own pane below the price pane | ChartFrame | its own, autoscaled from g.keepVisible and g.priceValue |
{ kind: "Canvas", weight? } | its own pane below the price pane | CanvasFrame | none |
{ kind: "ChartSeries" } | the price pane, as the chart type | ChartFrame | the price pane's, autoscaled from g.priceValue |
ChartOverlay,ChartPaneandCanvasare indicators: added from the indicator list. See Create an indicator.ChartSeriesis a chart type: picked in the chart type menu, the chart draws no candles. See Create a chart type.weightis the pane's initial height relative to the price pane's 1,0.3when omitted. The user can resize it by dragging the separator, the new size is saved.layer("bottom","normal","top") is the overlay's paint layer. See Layers.
Chart surfaces
ChartOverlay, ChartPane and ChartSeries share the chart's time axis and crosshair. Their frame converts time and price to pane px (timeToX, priceToY), pointer events carry time and price, and they can add price and time axis labels.
Price scale
A price scale fits only what scripts report to it, from the next frame:
ChartPaneandChartSeries: callg.priceValue(time, value)indrawfor every visible point, not just the last one, or the line runs out of the pane.g.keepVisible(0, 0)keeps a zero line in view.ChartOverlay: the candles set the scale. A level far from price stays off-screen unless the script callsg.keepVisible(low, high)for it.
Canvas
A free pixel surface for things without a time axis: histograms, tables, gauges. No timeToX or priceToY, pointer events carry x and y only, g.layer just draws, and no axis labels or autoscale. The script draws its own axes. See Trade size distribution.
Canvas gets every click, chart surfaces only clicks on a hit, so an empty chart still pans.
Writing for one surface
TypeScript narrows the frame by the surface: with surface: { kind: "Canvas" }, draw gets a CanvasFrame and frame.priceToY is a type error. A helper that takes a frame can accept ChartFrame and check frame.kind.