Rolling Sources
ValueScroll and PaletteScroll keep a moving window of columns. One new column arrives per bar, and the oldest is overwritten in place.
When to use a scroll
Use a rolling source when a picture grows by one column each bar: an oscillator map, a volatility strip, a state history. A field would need its whole content shifted left on every bar. A scroll overwrites its oldest column instead and never moves the rest.
Create and push
var pc.ValueScroll history = pc.valueScroll(5, 150) // rows, capacity
if barstate.isconfirmed
history.push(array.from(rsi5, rsi8, rsi13, rsi21, rsi34))valueScroll(rows, capacity)andpaletteScroll(rows, capacity)take from 2 to 99,999 rows and columns of capacity.push(column)takes exactlyrowsvalues, bottom row first, and returns the scroll.- A value scroll takes an
array<float>in whichnais transparent. A palette scroll takes anarray<int>in which-1is transparent.
push() inside barstate.isconfirmed keeps one column per completed bar. Pushing on every realtime tick would add a column per tick.The moving window
A scroll shows only the columns it has been given. Until it is full, it is as wide as the number of pushes. Once capacity is reached, each new column overwrites the oldest.
| Field | Meaning |
|---|---|
rows | Cells in every pushed column. |
capacity | The most columns the scroll keeps. |
written | Columns pushed so far, stopping at capacity. This is the current width. |
Draw a scroll
if barstate.islast
heat.drawLookback(history, 0.0, 5.0) // source, bottom, top- A scroll is drawn with
drawLookback(scroll, bottom, top, rightOffset = 0). It ends at the current bar, uses one bar per column, and puts the newest column on the right. - At least two columns must have been pushed. Before that the call does nothing and leaves any existing drawings as they are.
rightOffsetshifts the right edge by a number of bars, forward when positive.
A rolling heatmap
//@version=6
indicator("PineCanvas - Rolling RSI Heatmap", overlay = false,
max_polylines_count = 100)
import Alien_Algorithms/PineCanvas/1 as pc
// Make sure to update to the latest library version
// Stateful series calculations must run on every bar.
float rsi5 = ta.rsi(close, 5)
float rsi8 = ta.rsi(close, 8)
float rsi13 = ta.rsi(close, 13)
float rsi21 = ta.rsi(close, 21)
float rsi34 = ta.rsi(close, 34)
var pc.ValueScroll history = pc.valueScroll(5, 150)
var pc.Canvas heat = pc.heatmap(
pc.gradient(#602060, #305bb4, #31b6ad, #f4d24c, #f07735))
.colorLevels(32)
.valueRange(0.0, 100.0)
.opacity(25, 100)
if barstate.isconfirmed
history.push(array.from(rsi5, rsi8, rsi13, rsi21, rsi34))
if barstate.islast
heat.drawLookback(history, 0.0, 5.0)The fixed valueRange(0, 100) keeps a colour tied to an RSI value, so the map does not re-colour itself as the window moves.
A state strip
//@version=6
indicator("PineCanvas - Trend State Strip", overlay = false, max_polylines_count = 100)
import Alien_Algorithms/PineCanvas/1 as pc
// Stateful series calculations must run on every bar.
float ema20 = ta.ema(close, 20)
float ema50 = ta.ema(close, 50)
float ema200 = ta.ema(close, 200)
var pc.PaletteScroll states = pc.paletteScroll(3, 200)
var pc.Canvas strip = pc.newCanvas(array.from(color.red, color.teal))
if barstate.isconfirmed
states.push(array.from(close >= ema200 ? 1 : 0, close >= ema50 ? 1 : 0, close >= ema20 ? 1 : 0))
if barstate.islast
strip.drawLookback(states, 0.0, 3.0)Each column holds three palette indices: red when price closed below an average, teal when it closed above. The slowest average is the bottom row because the pushed array is read bottom row first.
Scaling a rolling value source
Automatic scaling can look at the whole window, at each column, or at each row. For rows that have different natural ranges, autoScale(pc.ScaleMode.eachRow) lets each one use the full gradient. Canvas & Styling describes the modes.
autoScale() the range is recalculated from the columns currently held, so colours can shift as old extremes leave the window. Use valueRange() when a colour must keep one meaning.Next: a scroll is the simplest heatmap source. For a heatmap anchored to price levels, see Heatmaps on Price.