// parent vector from depth vector p:{r:@[;;|;]\[(!0)@&1+|/x;x;!#x];(!#x)^'r@'x-1} // parent children lookup (excludes self-parenting) cp:{^'[;?x]@=x} / join the values of x in z with y. cxn:{r+y*r<{(y|z)&z':|\|(!#x)=/:x)*+1_s1,,0 sh0 cxn[1 4;5;t]} // horizontal tree rendering sh1:{,/'(" ";"┬";"│";"├";"┐";"┬";"─")x} t1:{t:spr[x]@+/(0N;t)*~:\=':t:t@\:!|/#'t:|'(y@)\'(!#y)^y t0:cxn[3 4;6;0^cls[y]@t] (sh1 0^+t0;+t)} sh2:{,/'(" ";"┬";"│";"┌";"┐";"┬";"─";"│";"┴";"┼")x} / center adjust horizontal position ctr:{$[^(!x)?z; y 1~c:#x@z; @[y;z;:;@[y:o[x]/[y;x@z];*x@z]] @[y;z;:;(-c)!+/@[y:o[x]/[y;x@z];x@z]]]} / center labels ctl0:{<>((#c)#!2)@&c:,/+(((-':i)-(0,-1_x@i))+(-1_+/1(-|0,|1_)\0,-2!_-0.5+x@i);x@i:&1&x)} ctl:{ m:(~&/^:)''x d:,/'(~&//'^:)#'x (d@'ctl0'm*#''x)@\:!#*x} pad:{p:x#/:" ",0N;p,/:'y,\:'p} / mark where node splits to children frk:{[i;t;r;y;p]shp[t]#@[0^r[cls[y]];;:;].1(7+0 1 0N 2@-2+3^r[cls[y]]@)\1+i@?y@p} t2:{t:spr[x]@+/(0N;t)*~:\=':t:t@\:!|/#'t:|'(y@)\'(!#y)^y (h;d):&~^t p:(~^:)#,/t h:ctr[cp@y]/[h@