Canvas & Drawing

Layers & Drawing Budgets

Each Canvas is one layer. Several canvases build a scene, and they share the script's 100 polylines between them.

Updated Publisher Alien_AlgorithmsPine Script v6

One Canvas, one layer

A Canvas owns the polylines it created, and each draw call replaces them. Drawing a field and then a shape batch on the same Canvas leaves only the shapes. Anything that must stay visible next to something else gets a Canvas of its own.

An astrology heads-up display with a zodiac wheel and an ephemeris panel drawn over a Bitcoin chart on TradingView
TradingView capture. The Astro HUD demo assembles a whole interface from filled geometry: 3,754 shapes in 85 polylines.

Stacking order

Drawings stack in the order they are created. Draw the background Canvas first and the foreground last. Inside one shape batch, colours are drawn in the order they first appear in the queue.

The shared budget

  • A script may hold 100 polylines. Every Canvas draws from that one pool, together with any polylines the script creates itself.
  • Each visible colour of a field, and each fill colour of a shape batch, needs at least one polyline.
  • A complex colour can need several, because one polyline holds 10,000 points.
PineCanvas does not coordinate canvases for you
Each Canvas only knows its own limit. Two canvases that are each allowed 100 polylines can ask for more than the script has, and TradingView then removes the oldest drawings. Divide the budget yourself.

drawingLimit

drawingLimit(count) caps the polylines one Canvas may own, from 1 to 100. A Canvas left at the default of 100 treats the whole pool as its own, and a render may use more than the bare minimum when its limit allows. Give each layer an explicit share, adding up to 100 or less.

A picture that cannot fit inside its Canvas's limit is refused with a runtime error that states how many drawings it needs. Raise that Canvas's share, or reduce the picture's colours and detail.

A two-layer pattern

A heatmap underneath, shapes on toppine
var pc.Canvas background = pc.heatmap().drawingLimit(60)
var pc.Canvas overlay = pc.newCanvas().drawingLimit(40)

if barstate.islast
    // Drawn first, so it sits underneath
    background.drawLookback(levels, 0, bottomPrice, topPrice)

    // Drawn second, so it sits on top
    overlay.rect(chart.point.from_time(leftTime, zoneTop), chart.point.from_time(rightTime, zoneBottom), color.new(color.white, 80))
    overlay.drawShapes()

The two canvases are independent. Each replaces only its own frame, and each can be restyled or cleared without touching the other.

Watch the counts

Polylines in usepine
plot(float(background.drawingCount()), "Background polylines", display = display.data_window)
plot(float(overlay.drawingCount()), "Overlay polylines", display = display.data_window)
plot(float(polyline.all.size()), "All polylines", display = display.data_window)

drawingCount() reports one Canvas. polyline.all.size() reports the whole script, which is the number that must stay at or below 100.

Backgrounds belong on their own Canvas

On a large picture, a smooth and fully opaque background is expensive. The large renderer works in tiles, and an opaque background has to be joined across every tile border, while transparent cells need no joining at all. Keep the detailed layer's background transparent and draw the backdrop on a separate, coarser Canvas underneath.

  • Detailed layer: full resolution, background cells left at -1 or na.
  • Backdrop: a small field with few colour levels, stretched over the same area with a wider lookback.

The library's cover scene is built this way: a coarse nebula, stars as a shape batch, and the high-resolution disk on top. Performance & Large Images has the details.

PineCanvas is a graphics library for Pine Script. TradingView drawing, memory, and execution limits still apply. © Alien_Algorithms.