All Downloads are FREE. Search and download functionalities are using the official Maven repository.

weka.gui.treevisualizer.Node Maven / Gradle / Ivy

Go to download

The Waikato Environment for Knowledge Analysis (WEKA), a machine learning workbench. This version represents the developer version, the "bleeding edge" of development, you could say. New functionality gets added to this version.

There is a newer version: 3.9.6
Show newest version
/*
 *   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;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy