Chart Time and Price Range 
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © kurtsmock

//@version=5
indicator("Chart Range", overlay=true, max_bars_back = 4000)
import PineCoders/VisibleChart/4 as t
bCol = input.color(color.black, "Border Color")
tCol = input.color(color.black, "Text Color")
pos  = input.string("Top Right",  "Position",     options=["Top Right","Top Left","Top Center","Bottom Right","Bottom Left","Bottom Center","Middle Right","Middle Left","Middle Center"])
size = input.string("Small",      "Size",         options=["Tiny","Small","Normal","Large","Huge","Auto"])
o_pos = switch pos
    "Top Right"     => position.top_right
    "Top Left"      => position.top_left      
    "Top Center"    => position.top_center
    "Bottom Right"  => position.bottom_right
    "Bottom Left"   => position.bottom_left
    "Bottom Center" => position.bottom_center
    "Middle Right"  => position.middle_right
    "Middle Left"   => position.middle_left
    "Middle Center" => position.middle_center
    => position.top_right
o_size = switch size
    "Tiny"      => size.tiny
    "Small"     => size.small
    "Normal"    => size.normal
    "Large"     => size.large
    "Huge"      => size.huge
    "Auto"      => size.auto
// Chart Time Span
leftBarTime() => 
    var int result = na
    if time == chart.left_visible_bar_time
        result := time
    result
timeSpan = (time - leftBarTime()) / 1000
inSec    = (timeSpan % 60), inMin = 0, inHrs = 0, inDys = 0
timeUnit = ""
if timeSpan >= 60
    inMin := math.floor(timeSpan / 60)
    if inMin >= 60
        inHrs := math.floor(inMin / 60)
        inMin := inMin - (60 * inHrs)
    if inHrs > 23
        inDys := math.floor(timeSpan / 86400)
        inHrs := (((timeSpan % 86400) / 60) / 60)
    if timeframe.isdwm
        inSec := 0
        inMin := 0
        inHrs := 0
timeUnit := inDys >= 1 ? str.tostring(inDys) + (inDys == 1 ? " Day. " : " Days. ") : ""
timeUnit := timeUnit + (inHrs > 0 or (inDys > 0 and inMin > 0) ? str.format("{0,number,integer}",inHrs) + (inHrs == 1 ? " Hour. " : " Hours. ") : "")
timeUnit := timeUnit + (inMin > 0 ? str.format("{0,number,integer}",inMin) + " Minutes. ": "")
timeUnit := timeUnit + (inSec > 0 and (timeSpan % 60 != 0) ? str.format("{0,number,integer}", inSec) + " Seconds." : "")
// Chart Range
// Credit for Function: PineCoders: VisibleChart https://www.tradingview.com/script/j7vCseM2-VisibleChart/
leftBarIndex() => 
    var int result = na
    if time == chart.left_visible_bar_time
        result := bar_index
    result
startBar = bar_index - t.leftBarIndex()
lowPrice = ta.lowest(nz(math.max(1,startBar),1))
highPrice  = ta.highest(nz(math.max(1,startBar),1))
rngPts = (highPrice - lowPrice)
rngTck = (highPrice - lowPrice)/syminfo.mintick
// Display
t = table.new(o_pos, 3,1,frame_color = bCol, frame_width = 1, border_color = bCol, border_width = 1)
cellWidth = o_size == size.small ? 3 : 0
table.cell(t, 0,0, str.tostring(rngPts) + " Pts",   width=cellWidth, text_size=o_size, text_color=tCol)
table.cell(t, 1,0, str.tostring(rngTck) + " Ticks", width=cellWidth, text_size=o_size, text_color=tCol)
timeWidth = o_size == size.small ? timeframe.isdwm ? 3 : 7 : 0
table.cell(t, 2,0, timeUnit,                        width=timeWidth, text_size=o_size, text_color=tCol)