/* ------------------------------------------------------------------------- */
/* */
/* 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