Boxes_Plot
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © peacefulLizard50262

//@version=5
library("Boxes_Plot")

grad(src)=>
    color out = switch int(src)
        0  => color.new(#1500FF , 20)
        1  => color.new(#1709F6 , 20)
        2  => color.new(#1912ED , 20)
        3  => color.new(#1B1AE5 , 20)
        4  => color.new(#1D23DC , 20)
        5  => color.new(#1F2CD3 , 20)
        6  => color.new(#2135CA , 20)
        7  => color.new(#233EC1 , 20)
        8  => color.new(#2446B9 , 20)
        9  => color.new(#264FB0 , 20)
        10 => color.new(#2858A7 , 20)
        11 => color.new(#2A619E , 20)
        12 => color.new(#2C6A95 , 20)
        13 => color.new(#2E728D , 20)
        14 => color.new(#307B84 , 20)
        15 => color.new(#32847B , 20)
        16 => color.new(#348D72 , 20)
        17 => color.new(#36956A , 20)
        18 => color.new(#389E61 , 20)
        19 => color.new(#3AA758 , 20)
        20 => color.new(#3CB04F , 20)
        21 => color.new(#3EB946 , 20)
        22 => color.new(#3FC13E , 20)
        23 => color.new(#41CA35 , 20)
        24 => color.new(#43D32C , 20)
        25 => color.new(#45DC23 , 20)
        26 => color.new(#47E51A , 20)
        27 => color.new(#49ED12 , 20)
        28 => color.new(#4BF609 , 20)
        29 => color.new(#4DFF00 , 20)
        30 => color.new(#53FF00 , 20)
        31 => color.new(#59FF00 , 20)
        32 => color.new(#5FFE00 , 20)
        33 => color.new(#65FE00 , 20)
        34 => color.new(#6BFE00 , 20)
        35 => color.new(#71FE00 , 20)
        36 => color.new(#77FD00 , 20)
        37 => color.new(#7DFD00 , 20)
        38 => color.new(#82FD00 , 20)
        39 => color.new(#88FD00 , 20)
        40 => color.new(#8EFC00 , 20)
        41 => color.new(#94FC00 , 20)
        42 => color.new(#9AFC00 , 20)
        43 => color.new(#A0FB00 , 20)
        44 => color.new(#A6FB00 , 20)
        45 => color.new(#ACFB00 , 20)
        46 => color.new(#B2FB00 , 20)
        47 => color.new(#B8FA00 , 20)
        48 => color.new(#BEFA00 , 20)
        49 => color.new(#C4FA00 , 20)
        50 => color.new(#CAF900 , 20)
        51 => color.new(#D0F900 , 20)
        52 => color.new(#D5F900 , 20)
        53 => color.new(#DBF900 , 20)
        54 => color.new(#E1F800 , 20)
        55 => color.new(#E7F800 , 20)
        56 => color.new(#EDF800 , 20)
        57 => color.new(#F3F800 , 20)
        58 => color.new(#F9F700 , 20)
        59 => color.new(#FFF700 , 20)
        60 => color.new(#FFEE00 , 20)
        61 => color.new(#FFE600 , 20)
        62 => color.new(#FFDE00 , 20)
        63 => color.new(#FFD500 , 20)
        64 => color.new(#FFCD00 , 20)
        65 => color.new(#FFC500 , 20)
        66 => color.new(#FFBD00 , 20)
        67 => color.new(#FFB500 , 20)
        68 => color.new(#FFAC00 , 20)
        69 => color.new(#FFA400 , 20)
        70 => color.new(#FF9C00 , 20)
        71 => color.new(#FF9400 , 20)
        72 => color.new(#FF8C00 , 20)
        73 => color.new(#FF8300 , 20)
        74 => color.new(#FF7B00 , 20)
        75 => color.new(#FF7300 , 20)
        76 => color.new(#FF6B00 , 20)
        77 => color.new(#FF6200 , 20)
        78 => color.new(#FF5A00 , 20)
        79 => color.new(#FF5200 , 20)
        80 => color.new(#FF4A00 , 20)
        81 => color.new(#FF4200 , 20)
        82 => color.new(#FF3900 , 20)
        83 => color.new(#FF3100 , 20)
        84 => color.new(#FF2900 , 20)
        85 => color.new(#FF2100 , 20)
        86 => color.new(#FF1900 , 20)
        87 => color.new(#FF1000 , 20)
        88 => color.new(#FF0800 , 20)
        89 => color.new(#FF0000 , 20)
        90 => color.new(#F60000 , 20)
        91 => color.new(#DF0505 , 20)
        92 => color.new(#C90909 , 20)
        93 => color.new(#B20E0E , 20)
        94 => color.new(#9B1313 , 20)
        95 => color.new(#851717 , 20)
        96 => color.new(#6E1C1C , 20)
        97 => color.new(#572121 , 20)
        98 => color.new(#412525 , 20)
        99 => color.new(#2A2A2A , 20)
        100 => color.new(#1A1818 , 20)
        => color.white

// A function to plot colored boxes representing the values of multiple indicators
// @param source - an array of floating-point values representing the indicator values to display
// @param name - an array of strings representing the names of the indicators
// @param boxes_per_row - the number of boxes to display per row
// @param offset - an optional integer to offset the boxes horizontally (default: 0)
// @param scale - an optional floating-point value to scale the size of the boxes (default: 1)
export boxes_plot(float[] source, string[] name, int boxes_per_row, int offset = 0, float scale = 1)=>
    left = chart.left_visible_bar_time
    right = chart.right_visible_bar_time
    screen_size = math.abs(right - left)
    unit = int((time - time[1])/2)

    boxes = array.new<box>(array.size(source)) 
    multiplier = int(screen_size/unit/(boxes_per_row*2)/scale) 
    offset_x = boxes_per_row * multiplier * unit * (offset + 1)

    if barstate.islast
        var row = 0
        var col = 0
        if array.size(source) == array.size(name)
            for i = 0 to array.size(source) - 1
                xPos = (time + col * multiplier * unit - offset_x) 
                yPos = row * multiplier/2
                value = array.get(source, i)
                colour = grad(value)
                
                array.push(boxes, box.new(xPos, yPos, xPos + multiplier * unit, yPos - multiplier/2, colour, bgcolor = colour, text = array.get(name, i), text_color = color.white, xloc = xloc.bar_time))
                
                col +=  1
                if col >= boxes_per_row
                    col := 0
                    row -= 1
                if row >= boxes_per_row
                    row := 0
        else
            for i = 0 to array.size(source) - 1
                xPos = (time + col * multiplier * unit - offset_x) 
                yPos = row * multiplier/2
                value = array.get(source, i)
                colour = grad(value)
                
                array.push(boxes, box.new(xPos, yPos, xPos + multiplier * unit, yPos - multiplier/2, colour, bgcolor = colour, xloc = xloc.bar_time))
                
                col +=  1
                if col >= boxes_per_row
                    col := 0
                    row -= 1
                if row >= boxes_per_row
                    row := 0
    if barstate.isconfirmed
        for i = 0 to array.size(boxes) - 1
            box.delete(array.get(boxes, i))

// Example usage:

rsi = ta.rsi(close, 14)
stoch = ta.stoch(close, high, low, 14)

data_1 = array.from(rsi, stoch)
data_names_1 = array.from("RSI", "STOCH")

boxes_plot(data_1, data_names_1, 1, 0, 1)
boxes_plot(data_1, data_names_1, 2, 1, 1)