weka.gui.treevisualizer.Node Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weka-stable Show documentation
Show all versions of weka-stable Show documentation
The Waikato Environment for Knowledge Analysis (WEKA), a machine
learning workbench. This is the stable version. Apart from bugfixes, this version
does not receive any other updates.
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* Node.java
* Copyright (C) 1999-2012 University of Waikato, Hamilton, New Zealand
*
*/
package weka.gui.treevisualizer;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.io.StringReader;
import java.util.Vector;
import weka.core.Instances;
//this is a node structure that to be useful needs the Edge class as well
//note i have done an unintentional naughty thing
//getHeight() returns the pixel height of the node
//getHeight(Node,int) returns how many levels down the tree goes
//setHeight(int) is associated to the prior
/**
* This class records all the data about a particular node for displaying.
*
* @author Malcolm Ware ([email protected])
* @version $Revision: 10222 $
*/
public class Node {
/** The fill mode for the node (not in use). */
// private int m_backstyle; //how the back color will fill NOT USED
/** The shape of the node. */
private int m_shape;
/** The color of the node. */
private Color m_color;
/** the text for the node. */
private final String m_label;
/** the text broken up into lines */
private final Vector m_lines;
// the coord of the left side .note all coords are
// between 1-0 for scaling per Stuart's suggestion
/** The center of the node (between 0 and 1). */
private double m_center; // coord of the center . main x value used
/** The top of the node (between 0 and 1). */
private double m_top; // main y coord to go by
/** true if this nodes descendants are visible (not in use currently). */
private boolean m_cVisible; // whether it's descendants are visible
/** true if this node is visible (not currently in use). */
private boolean m_visible; // whether it's visible
/** true if this is the top of the tree. ie has no parent */
private boolean m_root; // whether it is anscestor to all i.e top of tree
/**
* An array containing references to all the parent edges (only 1 currently).
*/
private final Vector m_parent; // the edge to its parent edges(or itself
// if true root)
/** An array containing references to all the child edges. */
private final Vector m_children; // a vector list of edges to the nodes
// children
/** The ID string for this node (used for construction purposes) */
private String m_refer;
/** A String containing extra information about the node. */
private String m_data;
/**
* An Instances variable generated from the data. Note that if this exists
* then the string shall be NULL to save space.
*/
private Instances m_theData;
/**
* This will setup all the values of the node except for its top and center.
*
* @param label The text for the node.
* @param refer The ID string for this node.
* @param backstyle The backstyle of this node.
* @param shape The shape of this node.
* @param color The color of this node.
*/
public Node(String label, String refer, int backstyle, int shape,
Color color, String d) {
m_label = label;
// m_backstyle = backstyle; NOT USED
m_shape = shape;
m_color = color;
m_refer = refer;
m_center = 0;
m_top = 0;
m_cVisible = true;
m_visible = true;
m_root = false;
m_parent = new Vector(1, 1);
m_children = new Vector(20, 10);
m_lines = new Vector(4, 2);
breakupLabel();
m_data = d;
m_theData = null;
}
/**
* This will return the Instances object related to this node. If it has not
* been allocated then that will be done also.
*
* @return The Instances object.
*/
public Instances getInstances() {
if (m_theData == null && m_data != null) {
try {
m_theData = new Instances(new StringReader(m_data));
} catch (Exception e) {
System.out.println("Error : " + e);
}
m_data = null;
}
return m_theData;
}
/**
* Get If this node's childs are visible.
*
* @return True if the childs are visible.
*/
public boolean getCVisible() {
return m_cVisible;
}
/**
* Recursively goes through the tree and sets all the children and the parent
* to visible.
*
* @param r The current node to set visible.
*/
private void childVis(Node r) {
Edge e;
r.setVisible(true);
if (r.getCVisible()) {
for (int noa = 0; (e = r.getChild(noa)) != null; noa++) {
childVis(e.getTarget());
}
}
}
/**
* Sets all the children of this node either to visible or invisible
*
* @param v True if the children are to be visible
*/
public void setCVisible(boolean v) {
m_cVisible = v;
if (v) {
childVis(this);
} else if (!v) {
childInv(this);
}
}
/**
* Recursively goes through the tree and sets all the children to invisible,
* Not the parent though.
*
* @param r The current node from whom the children are gonna be set
* invisible.
*/
private void childInv(Node r) {
Edge e;
Node s;
for (int noa = 0; (e = r.getChild(noa)) != null; noa++) {
s = e.getTarget();
s.setVisible(false);
childInv(s);
}
}
/**
* Get the value of refer.
*
* @return Value of refer.
*/
public String getRefer() {
return m_refer;
}
/**
* Set the value of refer.
*
* @param v Value to assign to refer.
*/
public void setRefer(String v) {
m_refer = v;
}
/**
* Get the value of shape.
*
* @return Value of shape.
*/
public int getShape() {
return m_shape;
}
/**
* Set the value of shape.
*
* @param v Value to assign to shape.
*/
public void setShape(int v) {
m_shape = v;
}
/**
* Get the value of color.
*
* @return Value of color.
*/
public Color getColor() {
return m_color;
}
/**
* Set the value of color.
*
* @param v Value to assign to color.
*/
public void setColor(Color v) {
m_color = v;
}
/**
* Get the value of label.
*
* @return Value of label.
*/
public String getLabel() {
return m_label;
}
/**
* This Will break the node's text up into lines.
*
*/
private void breakupLabel() {
int prev = 0, noa;
for (noa = 0; noa < m_label.length(); noa++) {
if (m_label.charAt(noa) == '\n') {
m_lines.addElement(m_label.substring(prev, noa));
prev = noa + 1;
}
}
m_lines.addElement(m_label.substring(prev, noa));
}
/**
* This will return the width and height of the rectangle that the text will
* fit into.
*
* @param f The size info for the Font.
* @return A Dimension containing the size of the text.
*/
public Dimension stringSize(FontMetrics f) {
Dimension d = new Dimension();
int old = 0;
String s;
int noa = 0;
while ((s = getLine(noa)) != null) {
noa++;
old = f.stringWidth(s);
if (old > d.width) {
d.width = old;
}
}
d.height = noa * f.getHeight();
return d;
}
/**
* Returns the text String for the specfied line.
*
* @param n The line wanted.
* @return The String corresponding to that line.
*/
public String getLine(int n) {
if (n < m_lines.size()) {
return m_lines.elementAt(n);
} else {
return null;
}
}
/**
* Get the value of center.
*
* @return Value of center.
*/
public double getCenter() {
return m_center;
}
/**
* Set the value of center.
*
* @param v Value to assign to center.
*/
public void setCenter(double v) {
m_center = v;
}
/**
* Will increase or decrease the postion of center.
*
* @param v The amount to increase or decrease center by.
*/
public void adjustCenter(double v) {
m_center += v;
}
/**
* Get the value of top.
*
* @return Value of top.
*/
public double getTop() {
return m_top;
}
/**
* Set the value of top.
*
* @param v Value to assign to top.
*/
public void setTop(double v) {
m_top = v;
}
/**
* Get the value of visible.
*
* @return Value of visible.
*/
public boolean getVisible() {
return m_visible;
}
/**
* Set the value of visible.
*
* @param v Value to assign to visible.
*/
private void setVisible(boolean v) {
m_visible = v;
}
/**
* Get the value of root.
*
* @return True if has no parents.
*/
public boolean getRoot() {
return m_root;
}
/**
* Set the value of root.
*
* @param v Value to assign to root.
*/
public void setRoot(boolean v) {
m_root = v;
}
/**
* Get the parent edge.
*
* @param i The parent number to get.
* @return The parent edge or NULL if it doesn't exist.
*/
public Edge getParent(int i) {
if (i < m_parent.size()) {
return m_parent.elementAt(i);
} else {
return null;
}
}
/**
* Set the value of parent.
*
* @param v Value to assign to parent.
*/
public void setParent(Edge v) {
m_parent.addElement(v);
}
/**
* Get the Edge for the child number 'i'.
*
* @param i The child number to get.
* @return The child Edge or NULL if it doesn't exist.
*/
public Edge getChild(int i) {
if (i < m_children.size()) {
return m_children.elementAt(i);
} else {
return null;
}
}
/**
* Set the value of children.
*
* @param v Value to assign to children.
*/
public void addChild(Edge v) {
m_children.addElement(v);
}
/**
* Recursively finds the number of visible groups of siblings there are.
*
* @param r The current Node upto.
* @param n The current number of groups there are.
* @return The number of groups found so far.
*/
public static int getGCount(Node r, int n) {
Edge e;
if (r.getChild(0) != null && r.getCVisible()) {
n++;
for (int noa = 0; (e = r.getChild(noa)) != null; noa++) {
n = getGCount(e.getTarget(), n);
}
}
return n;
}
/**
* Recursively finds the total number of groups of siblings there are.
*
* @param r The current Node upto.
* @param n The current number of groups there are.
* @return The number of groups found so far.
*/
public static int getTotalGCount(Node r, int n) {
Edge e;
if (r.getChild(0) != null) {
n++;
for (int noa = 0; (e = r.getChild(noa)) != null; noa++) {
n = getTotalGCount(e.getTarget(), n);
}
}
return n;
}
/**
* Recursively finds the number of visible nodes there are (this may
* accidentally count some of the invis nodes).
*
* @param r The current Node upto.
* @param n The current number nodes there are.
* @return The number of nodes found so far.
*/
public static int getCount(Node r, int n) {
Edge e;
n++;
for (int noa = 0; (e = r.getChild(noa)) != null && r.getCVisible(); noa++) {
n = getCount(e.getTarget(), n);
}
return n;
}
/**
* Recursively finds the total number of nodes there are.
*
* @param r The current Node upto.
* @param n The current number nodes there are.
* @return The number of nodes found so far.
*/
public static int getTotalCount(Node r, int n) {
Edge e;
n++;
for (int noa = 0; (e = r.getChild(noa)) != null; noa++) {
n = getTotalCount(e.getTarget(), n);
}
return n;
}
/**
* Recursively finds the number of visible levels there are.
*
* @param r The current Node upto.
* @param l The curent level.
* @return The max number of levels found so far.
*/
public static int getHeight(Node r, int l) {
l++;
int lev = l, temp = 0;
Edge e;
for (int noa = 0; (e = r.getChild(noa)) != null && r.getCVisible(); noa++) {
temp = getHeight(e.getTarget(), l);
if (temp > lev) {
lev = temp;
}
}
return lev;
}
/**
* Recursively finds the total number of levels there are.
*
* @param r The current Node upto.
* @param l The curent level.
* @return The max number of levels found so far.
*/
public static int getTotalHeight(Node r, int l) {
l++;
int lev = l, temp = 0;
Edge e;
for (int noa = 0; (e = r.getChild(noa)) != null; noa++) {
temp = getTotalHeight(e.getTarget(), l);
if (temp > lev) {
lev = temp;
}
}
return lev;
}
}