Automatically Align and Resize Layout Objects

 

 

Automatically align and resize graphs and textboxes in layouts so that they match others in their class. Their class is defined as other objects of the same type that are near them in a given dimension (x or y) on the layout. Suppose you had a layout with 6 graphs arranged 3 rows x 2 columns and 6 textboxes "A" through "F" near each one. You don't want to fill the entire layout by tiling them using the Tile command; instead you want the behavior that you would get if you manually selected the two graphs in the first row, selected "Align Top Edges" and "Make Same Width and Height" form the Layout Menu, then repeated this for each of the other rows, and then repeated it for columns using "Align Left Edges', and then repeated it again for the 6 textboxes. This is tedious, and this function is meant to achieve this in one stroke. Note that this only works when your layout objects are roughly in the right positions; it is meant to clean them up with small adjustments, not to move them all the way across the layout.

 

 

function NiceLayout(rows,cols[,win])
    variable rows,cols // Desired number of rows and columns.  
    string win // Optional layout window name.  
   
    win=selectstring(!paramisdefault(win),winname(0,4),win)
    variable i=0,j,k,d
    string types="Graph;Textbox"
    make /free/t/n=(itemsinlist(types)) items=""
   
    // Make lists of the various items in the layout.  
    do
        string info=LayoutInfo(win,num2str(i))
        string type=stringbykey("TYPE",info)
        string name=stringbykey("NAME",info)
        variable typeNum=whichlistitem(type,types)
        if(typeNum>=0)
            items[typeNum]+=name+";"
        endif
        i+=1
    while(strlen(info))
   
    // Go through these lists.  
    for(i=0;i<itemsinlist(types);i+=1)
        type=stringfromlist(i,types)
        make /free/n=(1,itemsinlist(items[i]),1) yy=numberbykey("TOP",layoutinfo(win,stringfromlist(q,items[i])))
        string dimensions="xx;yy"
        for(d=0;d<itemsinlist(dimensions);d+=1)
            string dimension=stringfromlist(d,dimensions)
            strswitch(dimension)
                case "xx":
                    string lefttop="LEFT"
                    string widthheight="WIDTH"
                    variable classes=cols+1
                    break
                case "yy":
                    lefttop="TOP"
                    widthheight="HEIGHT"
                    classes=rows+1
                    break
            endswitch
            make /free/n=(1,itemsinlist(items[i]),1) locs=numberbykey(lefttop,layoutinfo(win,stringfromlist(q,items[i])))  
            variable minDispersion=Inf
            make /free/I/n=(itemsinlist(items[i])) membership=0
           
                        // Try clustering 100 times and take the best cluster assignments.  
                        for(j=0;j<100;j+=1)
                KMeans /CAN /NCLS=(classes) /OUT=2 /SEED=(abs(enoise(1000))) locs
                wave w_kmmembers,W_KMDispersion
                if(sum(w_kmdispersion)<minDispersion)
                    membership=w_kmmembers
                    minDispersion=sum(w_kmdispersion)
                endif
            endfor
            for(j=0;j<=wavemax(w_kmmembers);j+=1)
                extract /free/indx membership,members,membership==j
                variable leftTopNum=0, widthHeightNum=0
                for(k=0;k<numpnts(members);k+=1)
                    leftTopNum+=numberbykey(leftTop,layoutinfo(win,stringfromlist(members[k],items[i])))
                    widthHeightNum+=numberbykey(widthHeight,layoutinfo(win,stringfromlist(members[k],items[i])))
                endfor
                leftTopNum/=numpnts(members)
                widthHeightNum/=numpnts(members)
                for(k=0;k<numpnts(members);k+=1)
                    name=stringfromlist(members[k],items[i])
                    strswitch(dimension)
                        case "xx":
                            modifylayout /w=$win left($name)=leftTopNum, width($name)=widthHeightNum
                            break
                        case "yy":
                            modifylayout /w=$win top($name)=leftTopNum, height($name)=widthHeightNum
                            break
                    endswitch
                endfor
            endfor
        endfor
    endfor
end

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More