Pine Script UI & Tables

Pine Script Tables: How to Build On-Chart Dashboards and Information Panels

In Pine Script, tables display structured on-chart dashboards and statistical HUD panels that remain fixed to the chart window. A table is initialized using table.new() with a designated position and cell grid dimensions. Cells are populated or updated using table.cell(), and cleared using table.clear(). To optimize execution performance, table updates should be executed only on the final bar using barstate.islast.

Build On-Chart Tables with AI

Core table functions and positioning options in Pine Script v6

Tables float on top of the chart canvas and do not scale or shift with price or time axes, making them ideal for multi-timeframe screeners, account metrics, and risk status cards.

Function / ConstantTypeRoleExample setting
table.new()ConstructorAllocates table dimensions, outer borders, and grid backgroundtable.new(position.top_right, 2, 4, bgcolor = color.black)
position.top_rightPosition constantPins table to upper right corner of the chart viewStandard position for non-intrusive indicator HUDs
table.cell()MutatorWrites text, background color, text size, and tooltips into a celltable.cell(t, 0, 1, "RSI: " + str.tostring(rsi), bgcolor = color.green)
table.clear()MaintenanceClears text and backgrounds across a range of cell coordinatestable.clear(t, 0, 0, 1, 3) before refreshing state

Complete Pine Script v6 script: Multi-metric live dashboard

The following script builds an on-chart information dashboard displaying trend status, RSI values, and ATR volatility in the top-right corner of the chart window.

Pine Script v6: On-chart multi-indicator dashboard using tablespinescript
//@version=6
indicator("TradingView Status Dashboard [v6]", overlay = true)

// Input configuration
string tablePos = input.string("Top Right", "Table Position", 
                               options = ["Top Right", "Top Left", "Bottom Right", "Bottom Left"])

// Resolve position constant
var string posConstant = position.top_right
if barstate.isfirst
    posConstant := tablePos == "Top Left" ? position.top_left :
                   tablePos == "Bottom Right" ? position.bottom_right :
                   tablePos == "Bottom Left" ? position.bottom_left : position.top_right

// Technical indicators
float ema20 = ta.ema(close, 20)
float ema50 = ta.ema(close, 50)
float rsiVal = ta.rsi(close, 14)
float atrVal = ta.atr(14)

// Indicator states
bool isUptrend = ema20 > ema50
string trendText = isUptrend ? "BULLISH" : "BEARISH"
color trendColor = isUptrend ? color.green : color.red
color rsiColor = rsiVal > 70 ? color.orange : rsiVal < 30 ? color.purple : color.slate

// Create table instance once
var table dashboard = table.new(position.top_right, 2, 4, 
                                bgcolor = color.new(color.black, 20), 
                                border_color = color.gray, 
                                border_width = 1)

// Update cell data only on the latest bar for speed
if barstate.islast
    // Header row
    table.cell(dashboard, 0, 0, "Metric", text_color = color.white, bgcolor = color.navy, text_size = size.small)
    table.cell(dashboard, 1, 0, "Current Value", text_color = color.white, bgcolor = color.navy, text_size = size.small)
    
    // Trend status row
    table.cell(dashboard, 0, 1, "EMA Trend", text_color = color.white, text_size = size.small)
    table.cell(dashboard, 1, 1, trendText, text_color = color.white, bgcolor = trendColor, text_size = size.small)
    
    // RSI row
    table.cell(dashboard, 0, 2, "RSI (14)", text_color = color.white, text_size = size.small)
    table.cell(dashboard, 1, 2, str.tostring(rsiVal, "#.#"), text_color = color.white, bgcolor = rsiColor, text_size = size.small)
    
    // Volatility row
    table.cell(dashboard, 0, 3, "ATR (14)", text_color = color.white, text_size = size.small)
    table.cell(dashboard, 1, 3, str.tostring(atrVal, format.mintick), text_color = color.white, text_size = size.small)

How to use table.clear effectively

The table.clear() function resets cells within a specified column and row boundary without having to recreate the entire table container:

  • Syntax parameters: table.clear(table_id, start_column, start_row, end_column, end_row). If end coordinates are omitted, it clears to the boundary of the table.
  • Dynamic cell count management: When listing active open orders or alerts that vary in quantity, call table.clear() at the start of the bar before re-populating active rows.
  • Clearing styles: table.clear() resets text strings and backgrounds back to transparent default styling.
  • Prevent flicker: When updating existing static tables, updating table.cell() directly in place is generally faster than clearing and rewriting every tick.

Performance rules for Pine Script tables

Follow these guidelines to prevent chart lag when drawing dashboard panels:

  • Always use barstate.islast: Running table operations on thousands of historical bars consumes memory and slows script loading without providing visual benefit.
  • Declare with var: Never call table.new() unconditionally on every bar. Always declare tables with var table myTable = table.new(...) so only one instance is allocated.
  • Keep cell counts moderate: TradingView limits scripts to a maximum of 500 cells per table. Aim for compact 2x4 or 3x5 grids for responsive layout on mobile charts.
  • Text size selection: Use size.small or size.tiny to ensure labels fit cleanly on lower resolution displays and mobile devices.
Where Pineify fits

Pine Script AI Coding Agent

Generate customized TradingView HUD tables, multi-indicator scoreboards, and alert dashboards in Pine Script v6 with Pineify AI.

Also useful: Visual Pine Editor. Assemble technical indicators and visual signals with automated formatting and on-chart plots.

Build On-Chart Tables with AI

Frequently asked questions

On-chart dashboard tables display calculated values and visual markers for informational analysis. Verify performance metrics in simulated environments before placing live capital at risk.

Sources and verification