2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
* Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
23
package weka.gui.treevisualizer;
28
import weka.core.Instances;
31
//this is a node structure that to be useful needs the Edge class as well
33
//note i have done an unintentional naughty thing
34
//getHeight() returns the pixel height of the node
35
//getHeight(Node,int) returns how many levels down the tree goes
36
//setHeight(int) is associated to the prior
39
* This class records all the data about a particular node for displaying.
41
* @author Malcolm Ware (mfw4@cs.waikato.ac.nz)
42
* @version $Revision: 1.4 $
46
/** The fill mode for the node (not in use). */
47
private int m_backstyle; //how the back color will fill
49
/** The shape of the node. */
52
/** The color of the node. */
53
private Color m_color;
55
/** the text for the node. */
56
private String m_label;
58
/** the text broken up into lines */
59
private Vector m_lines;
61
//the coord of the left side .note all coords are
62
//between 1-0 for scaling per Stuart's suggestion
63
/** The center of the node (between 0 and 1). */
64
private double m_center; //coord of the center . main x value used
66
/** The top of the node (between 0 and 1). */
67
private double m_top; //main y coord to go by
69
/** true if this nodes descendants are visible (not in use currently). */
70
private boolean m_cVisible; //whether it's descendants are visible
72
/** true if this node is visible (not currently in use). */
73
private boolean m_visible; //whether it's visible
75
/** true if this is the top of the tree. ie has no parent */
76
private boolean m_root; //whether it is anscestor to all i.e top of tree
78
/** An array containing references to all the parent edges
79
* (only 1 currently). */
80
private Vector m_parent; //the edge to its parent edges(or itself
83
/** An array containing references to all the child edges. */
84
private Vector m_children; //a vector list of edges to the nodes children
86
/** The ID string for this node (used for construction purposes) */
87
private String m_refer;
89
/** A String containing extra information about the node. */
90
private String m_data;
93
* An Instances variable generated from the data.
94
* Note that if this exists then the string shall be NULL to save space.
96
private Instances m_theData;
99
* This will setup all the values of the node except for its top and center.
101
* @param label The text for the node.
102
* @param refer The ID string for this node.
103
* @param backstyle The backstyle of this node.
104
* @param shape The shape of this node.
105
* @param color The color of this node.
107
public Node(String label,String refer,int backstyle,int shape,
108
Color color,String d) {
110
m_backstyle = backstyle;
121
m_parent = new Vector(1,1);
122
m_children = new Vector(20,10);
123
m_lines = new Vector(4,2);
130
* This will return the Instances object related to this node.
131
* If it has not been allocated then that will be done also.
133
* @return The Instances object.
135
public Instances getInstances() {
136
if (m_theData == null && m_data != null) {
138
m_theData = new Instances(new StringReader(m_data));
139
} catch(Exception e) {
140
System.out.println("Error : " + e);
148
* Get If this node's childs are visible.
150
* @return True if the childs are visible.
152
public boolean getCVisible() {
157
* Recursively goes through the tree and sets all the children and the
160
* @param r The current node to set visible.
162
private void childVis(Node r) {
165
if (r.getCVisible()) {
166
for (int noa = 0;(e = r.getChild(noa)) != null;noa++) {
167
childVis(e.getTarget());
173
* Sets all the children of this node either to visible or invisible
175
* @param v True if the children are to be visible
177
public void setCVisible(boolean v) {
188
* Recursively goes through the tree and sets all the children to invisible,
189
* Not the parent though.
191
* @param r The current node from whom the children are gonna be set
194
private void childInv(Node r) {
197
for (int noa = 0;(e = r.getChild(noa)) != null;noa++) {
212
* Get the value of refer.
214
* @return Value of refer.
216
public String getRefer() {
222
* Set the value of refer.
224
* @param v Value to assign to refer.
226
public void setRefer(String v) {
234
* Get the value of shape.
236
* @return Value of shape.
238
public int getShape() {
244
* Set the value of shape.
246
* @param v Value to assign to shape.
248
public void setShape(int v) {
255
* Get the value of color.
257
* @return Value of color.
259
public Color getColor() {
265
* Set the value of color.
267
* @param v Value to assign to color.
269
public void setColor(Color v) {
276
* Get the value of label.
278
* @return Value of label.
280
public String getLabel() {
286
* This Will break the node's text up into lines.
289
private void breakupLabel() {
291
for (noa = 0;noa < m_label.length();noa++) {
292
if (m_label.charAt(noa) == '\n') {
293
m_lines.addElement(m_label.substring(prev,noa));
297
m_lines.addElement(m_label.substring(prev,noa));
302
* This will return the width and height of the rectangle that the text
305
* @param f The size info for the Font.
306
* @return A Dimension containing the size of the text.
308
public Dimension stringSize(FontMetrics f) {
309
Dimension d = new Dimension();
313
while ((s = getLine(noa)) != null) {
315
old = f.stringWidth(s);
321
d.height = noa * f.getHeight();
327
* Returns the text String for the specfied line.
329
* @param n The line wanted.
330
* @return The String corresponding to that line.
332
public String getLine(int n) {
333
if (n < m_lines.size()) {
334
return (String)m_lines.elementAt(n);
351
* Get the value of center.
353
* @return Value of center.
355
public double getCenter() {
361
* Set the value of center.
363
* @param v Value to assign to center.
365
public void setCenter(double v) {
371
* Will increase or decrease the postion of center.
373
* @param v The amount to increase or decrease center by.
375
public void adjustCenter(double v) {
381
* Get the value of top.
383
* @return Value of top.
385
public double getTop() {
391
* Set the value of top.
393
* @param v Value to assign to top.
395
public void setTop(double v) {
405
* Get the value of visible.
407
* @return Value of visible.
409
public boolean getVisible() {
415
* Set the value of visible.
417
* @param v Value to assign to visible.
419
private void setVisible(boolean v) {
428
* Get the value of root.
430
* @return True if has no parents.
432
public boolean getRoot() {
438
* Set the value of root.
440
* @param v Value to assign to root.
442
public void setRoot(boolean v) {
450
* Get the parent edge.
452
* @param i The parent number to get.
453
* @return The parent edge or NULL if it doesn't exist.
455
public Edge getParent(int i) {
457
if (i < m_parent.size()) {
458
return (Edge)m_parent.elementAt(i);
467
* Set the value of parent.
469
* @param v Value to assign to parent.
471
public void setParent(Edge v) {
473
m_parent.addElement(v);
479
* Get the Edge for the child number 'i'.
481
* @param i The child number to get.
482
* @return The child Edge or NULL if it doesn't exist.
484
public Edge getChild(int i) {
486
if (i < m_children.size()) {
487
return (Edge)m_children.elementAt(i);
495
* Set the value of children.
497
* @param v Value to assign to children.
499
public void addChild(Edge v) {
500
m_children.addElement(v);
505
* Recursively finds the number of visible groups of siblings there are.
507
* @param r The current Node upto.
508
* @param n The current number of groups there are.
509
* @return The number of groups found so far.
511
public static int getGCount(Node r,int n) {
514
if (r.getChild(0) != null && r.getCVisible()) {
516
for (int noa = 0;(e = r.getChild(noa)) != null;noa++) {
517
n = getGCount(e.getTarget(),n);
524
* Recursively finds the total number of groups of siblings there are.
526
* @param r The current Node upto.
527
* @param n The current number of groups there are.
528
* @return The number of groups found so far.
530
public static int getTotalGCount(Node r,int n) {
533
if (r.getChild(0) != null) {
535
for (int noa = 0;(e = r.getChild(noa)) != null;noa++) {
536
n = getTotalGCount(e.getTarget(),n);
547
* Recursively finds the number of visible nodes there are (this may
548
* accidentally count some of the invis nodes).
550
* @param r The current Node upto.
551
* @param n The current number nodes there are.
552
* @return The number of nodes found so far.
554
public static int getCount(Node r,int n) {
557
for (int noa = 0;(e = r.getChild(noa)) != null && r.getCVisible();noa++) {
558
n = getCount(e.getTarget(),n);
565
* Recursively finds the total number of nodes there are.
567
* @param r The current Node upto.
568
* @param n The current number nodes there are.
569
* @return The number of nodes found so far.
571
public static int getTotalCount(Node r,int n) {
574
for (int noa = 0;(e = r.getChild(noa)) != null;noa++) {
575
n = getTotalCount(e.getTarget(),n);
582
* Recursively finds the number of visible levels there are.
584
* @param r The current Node upto.
585
* @param l The curent level.
586
* @return The max number of levels found so far.
588
public static int getHeight(Node r,int l) {
590
int lev = l,temp = 0;
593
for (int noa = 0;(e = r.getChild(noa)) != null && r.getCVisible();noa++) {
594
temp = getHeight(e.getTarget(),l);
607
* Recursively finds the total number of levels there are.
609
* @param r The current Node upto.
610
* @param l The curent level.
611
* @return The max number of levels found so far.
613
public static int getTotalHeight(Node r,int l) {
615
int lev = l,temp = 0;
618
for (int noa = 0;(e = r.getChild(noa)) != null;noa++) {
619
temp = getTotalHeight(e.getTarget(),l);