/* ------------------------------------------------------------------------- */ /* */ /* CANVAS FOR P-TREE WINDOW */ /* */ /* Frans Coenen */ /* */ /* 27 June 2003 */ /* */ /* Department of Computer Science */ /* The University of Liverpool */ /* */ /* ------------------------------------------------------------------------- */ /** Draws P-tree to a windpw.

Operates using a 2-D grid caklled LocalPtree of P-tree node elements. */ import java.awt.*; // Java extension packages import javax.swing.*; // Other packages //import lucsKDD_ARM.*; public class PtreeCanvas extends JPanel { private class LocalPtree { /** The itemset represented by the node */ short[] itemSet = null; /** The support value. */ int support = 0; /** The linkage: 0) no arcs, 1) horizontal arc, 2) vertical arc, 3) horizontal and vertical arcs, 4) vertical link passing through element. */ int linkage = 0; /* Constructors */ /** Default constructor. */ private LocalPtree() { } /** Three argument constructor. */ private LocalPtree(short[] set, int supp, int link) { itemSet = set; support = supp; linkage = link; } } LocalPtree[][] nodeArray; /* FIELDS */ static final int NODE_WIDTH = 60; static final int NODE_HEIGHT = 13; static final int ARC_WIDTH = 10; static final int ARC_HEIGHT = 10; static final int GAP_WIDTH = 28; static final int GAP_HEIGHT = 20; static final int SPACING_W = NODE_WIDTH+GAP_WIDTH; static final int SPACING_H = NODE_HEIGHT+GAP_HEIGHT; static final int BORDER = 20; private PtreeNodeTop[] startPtreeRef = null; /* CONSTRUCTOR */ public PtreeCanvas(int numXnodes, int numYnodes, PtreeNodeTop[] startRef) { super(); startPtreeRef=startRef; // Initialise node array nodeArray=new LocalPtree[numXnodes][numYnodes]; for (int rowIndex=0;rowIndex Proceeds by looping through 2-D node array and identifying all nodes where the itemset cvalue is not set to "null" --- these are then drawn in the window. Note: some elements in the node array will have a linkage of '4' indicating that a vertical line passes through the element, but a node value of "null". Thes elements are used when placing nodes in the node array, however they plays no part in the drawing of the P-tree. @param g The graphics context. */ public void paintComponent(Graphics g) { // Make the panel opaque super.paintComponent(g); // Loop through node array row by row for(int rowIndex=0;rowIndex The grid is as follws given the P-tree: 1 -- 2-- 3 | | | 3 | 2 -- 3 | 3 This will be presented as: +---+---+---+ | 1 | 2 | 3 | +---+---+---+ | | 2 | | +---+---+---+ | 2 | 3 | | +---+---+---+ | 3 | | | +---+---+---+ */ private void populateArray() { int numNodes = startPtreeRef.length-2; int colIndex=-1; boolean start=true; // Determine maximum column index in top level for(int index=startPtreeRef.length-1;index>0;index--) { if (startPtreeRef[index]!=null) colIndex++; } // Loop through sibling nodes in top level of P-tree starting with // last node and placing nodes in top level of node array (second // index 0). for(int index=startPtreeRef.length-1;index>0;index--) { // Test whether node exists in top level array. if (startPtreeRef[index]!=null) { short[] oneItemSet = new short[1]; oneItemSet[0] = (short) index; // Add label and support to appropriate intersection in node // array nodeArray[0][colIndex].itemSet = oneItemSet; nodeArray[0][colIndex].support = startPtreeRef[index].support; // Add nature of lionkage: 0) no arcs, 1) horizontal arc, 2) // vertical arc, 3) horizontal and vertical arcs. If last // sibling (first node arrived at when processing array in // reverse) then linkage is 2 (vertical link only) or 0 (none). if (start) { // Vertical link if (startPtreeRef[index].childRef!=null) { nodeArray[0][colIndex].linkage=2; // Process child array. populateArray(1,colIndex,startPtreeRef[index].childRef); } // No links else nodeArray[0][colIndex].linkage=0; } // Further siblings else { // Vertival and horizontal links if (startPtreeRef[index].childRef!=null) { nodeArray[0][colIndex].linkage=3; // Process chikd array populateArray(1,colIndex,startPtreeRef[index].childRef); } // Horizontal link only else nodeArray[0][colIndex].linkage=1; } // Dine last node start=false; colIndex--; } } } /* POPULATE ARRAY */ /** commences process of populating rest of node array with contents of P-tree child branches. @param colIndex the current X index. @param colIndex the current Y index. @param treeRef the current position in the P-tree. */ private void populateArray(int rowIndex, int colIndex, PtreeNode treeRef) { // Count number of nodes in level int numNodes=0; PtreeNode linkRef = treeRef; while (linkRef.siblingRef!=null) { numNodes++; linkRef= linkRef.siblingRef; } // Check For room rowIndex = checkForSpace(rowIndex,colIndex,numNodes); // Add popArray(rowIndex,colIndex,treeRef); } /* POP ARRAY */ /** Add P-tree node to node array and process sibling and child branches. @param rowIndex the current row index. @param colIndex the current column index. @param treeRef the current position in the P-tree. */ private void popArray(int rowIndex, int colIndex, PtreeNode treeRef) { // Add node to node array nodeArray[rowIndex][colIndex].itemSet = treeRef.itemSet; nodeArray[rowIndex][colIndex].support = treeRef.support; // Add linkage if (treeRef.siblingRef!=null) { populateArray(rowIndex,colIndex+1,treeRef.siblingRef); if (treeRef.childRef!=null) { nodeArray[rowIndex][colIndex].linkage=3; populateArray(rowIndex+1,colIndex,treeRef.childRef); } else nodeArray[rowIndex][colIndex].linkage=1; } else { if (treeRef.childRef!=null) { nodeArray[rowIndex][colIndex].linkage=2; populateArray(rowIndex+1,colIndex,treeRef.childRef); } else nodeArray[rowIndex][colIndex].linkage=0; } } /* CHECK FOR SPACE */ /** Checks if there is sufficient space in the node array , if so returns current Y coordinate, otherwise increments y coordinate and trys again. @param rowIndex the curent row coordinate. @param startColIndex the current column coordinate @param numSupportedNodes the number ofnodes to be fitted into the array. @return the revise row coordinate. */ private int checkForSpace(int rowIndex, int startColIndex, int numNodes) { //System.out.println("#rowIndex = " + rowIndex + //", startColIndex = " + startColIndex + ", numNodes = " + numNodes); //System.out.println("nodeArray.length = " + nodeArray.length + //", nodeArray[0].length = " + nodeArray[0].length); // Loop through siblings for (int index=startColIndex;index<=startColIndex+numNodes;index++) { // If slot occupied by another node, or slot not occupied but // used by vertical arc from some other node then increment Y // and repeat. //System.out.println("index = " + index); if ((nodeArray[rowIndex][index].itemSet!=null) || (nodeArray[rowIndex][index].linkage==4)) { // Set current slot to "occupied by vertical arc" nodeArray[rowIndex][startColIndex].linkage=4; // Increment row index and repeat return(checkForSpace(rowIndex+1,startColIndex,numNodes)); } } // If all OK return row index return(rowIndex); } /* ----------------------------------------------------- */ /* */ /* OUTPUT (DIAGNOSTIC PUPOSES ONLY) */ /* */ /* ----------------------------------------------------- */ /* OUTPUT NODE ARRAY */ /** Outputs node array. */ private void outputNodeArray() { for (int rowIndex=0;rowIndex