⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 treevisualizer.java

📁 MacroWeka扩展了著名数据挖掘工具weka
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    //from overlapping
    //it will leave the view centered
    
    int dist;
    Node ln,rn;
    Dimension temp = new Dimension(10, 10);
    
    if (m_numNodes <= 1) {
      return;
    }
    
    //calc height needed by first node
    dist = (m_nodes[0].m_height + 40) * m_numLevels;
    if (dist > temp.height) {
      temp.height = dist;
    }
    
    for (int noa = 0;noa < m_numNodes - 1;noa++) {
      calcScreenCoords(noa);  
      calcScreenCoords(noa+1);
      if (m_nodes[noa+1].m_change) {
	//then on a new level so don't check width this time round
      }
      else {
	
	dist = m_nodes[noa+1].m_center - m_nodes[noa].m_center; 
	//the distance between the node centers, along horiz
	if (dist <= 0) {
	  dist = 1;
	}
	dist = ((6 + m_nodes[noa].m_side + m_nodes[noa+1].m_side) 
		* m_viewSize.width) / dist; //calc optimal size for width
	
	if (dist > temp.width) {
	  
	  temp.width = dist;
	}
      }
      //now calc.. minimun hieght needed by nodes
      
      dist = (m_nodes[noa+1].m_height + 40) * m_numLevels;
      if (dist > temp.height) {
	
	temp.height = dist;
      }
    }
    
    int y1, y2, xa, xb;
    
    y1 = m_nodes[m_edges[0].m_parent].m_top;
    y2 = m_nodes[m_edges[0].m_child].m_top;
    
    dist = y2 - y1;
    if (dist <= 0) {
      dist = 1;
    }
    dist = ((60 + m_edges[0].m_height + m_nodes[m_edges[0].m_parent].m_height) 
	    * m_viewSize.height) / dist;
    if (dist > temp.height) {
      
      temp.height = dist;
    }
    
    for (int noa = 0;noa < m_numNodes - 2; noa++) {
      //check the edges now
      if (m_nodes[m_edges[noa+1].m_child].m_change) {
	//then edge is on a different level , so skip this one
      }
      else {
	//calc the width requirements of this pair of edges
	
	xa = m_nodes[m_edges[noa].m_child].m_center 
	  - m_nodes[m_edges[noa].m_parent].m_center;
	xa /= 2;
	xa += m_nodes[m_edges[noa].m_parent].m_center;
	
	xb = m_nodes[m_edges[noa+1].m_child].m_center - 
	  m_nodes[m_edges[noa+1].m_parent].m_center;
	xb /= 2;
	xb += m_nodes[m_edges[noa+1].m_parent].m_center;
	
	dist = xb - xa;
	if (dist <= 0) {
	  dist = 1;
	}
	dist = ((12 + m_edges[noa].m_side + m_edges[noa+1].m_side) 
		* m_viewSize.width) 
	  / dist;
	if (dist > temp.width) {
	  
	  temp.width = dist;
	}
      }
      //now calc height need by the edges
      y1 = m_nodes[m_edges[noa+1].m_parent].m_top;
      y2 = m_nodes[m_edges[noa+1].m_child].m_top;
      
      dist = y2 - y1;
      if (dist <= 0) {
	
	dist = 1;
      }
      dist = ((60 + m_edges[noa+1].m_height 
	       + m_nodes[m_edges[noa+1].m_parent].m_height) 
	      * m_viewSize.height) / dist;
      
      if (dist > temp.height) {
	
	temp.height = dist;
      }
    }

    Dimension e = getSize();
    
    Dimension np = new Dimension();
    np.width = (int)(e.width / 2 -  (((double)e.width / 2) - m_viewPos.width) /
		     ((double)m_viewSize.width) * (double)temp.width);
    np.height = (int)(e.height / 2 -  (((double)e.height / 2) - 
				       m_viewPos.height) /       
		      ((double)m_viewSize.height) * (double)temp.height);
    //animate_scaling(c_size,c_pos,25);
    
    for (int noa = 0;noa < m_numNodes;noa++) {
      //this resets the coords so that next time a refresh occurs they don't 
      //accidentally get used
      //I will use 32000 to signify that they are invalid, even if this 
      //coordinate occurs it doesn't
      //matter as it is only for the sake of the caching
      
      m_nodes[noa].m_top = 32000;
      
    }
    animateScaling(np, temp, 10);
  }

  /**
   * This will increment the size and position of the tree towards the 
   * desired size and position
   * a little (depending on the value of <i>frames</i>) everytime it is called.
   *
   * @param n_pos The final position of the tree wanted.
   * @param n_size The final size of the tree wanted.
   * @param frames The number of frames that shall occur before the final 
   * size and pos is reached.
   */
  private void animateScaling(Dimension n_pos,Dimension n_size,int frames) {
    //this function will take new size and position coords , and incrementally
    //scale the view to these
    //since I will be tying it in with the framelimiter I will simply call 
    //this function and increment it once
    //I will have to use a global variable since I am doing it proportionally

    if (frames == 0) {
      System.out.println("the timer didn't end in time");
      m_scaling = 0;
    }
    else {
      if (m_scaling == 0) {
	//new animate session
	//start timer and set scaling
	m_frameLimiter.start();
	m_nViewPos.width = n_pos.width;
	m_nViewPos.height = n_pos.height;
	m_nViewSize.width = n_size.width;
	m_nViewSize.height = n_size.height;
	
	m_scaling = frames;
      }
      
      int s_w = (n_size.width - m_viewSize.width) / frames;
      int s_h = (n_size.height - m_viewSize.height) / frames;
      int p_w = (n_pos.width - m_viewPos.width) / frames;
      int p_h = (n_pos.height - m_viewPos.height) / frames;
      
      m_viewSize.width += s_w;
      m_viewSize.height += s_h;
      
      m_viewPos.width += p_w;
      m_viewPos.height += p_h;
      
      repaint();
      
      m_scaling--;
      if (m_scaling == 0) {
	//all done 
	m_frameLimiter.stop();
      }
    }
  }
  
  /**
   * This will change the font size for displaying the tree to the one 
   * specified.
   *
   * @param s The new pointsize of the font.
   */
  private void changeFontSize(int s) {
    //this will set up the new font that shall be used
    //it will also recalculate the size of the nodes as these will change as 
    //a result of 
    //the new font size
    setFont(m_currentFont = new Font("A Name", 0, s));             

    m_fontSize = getFontMetrics(getFont());
    
    Dimension d;

    for (int noa = 0; noa < m_numNodes; noa++) {
      //this will set the size info for each node and edge
      
      d = m_nodes[noa].m_node.stringSize(m_fontSize);
      
      if (m_nodes[noa].m_node.getShape() == 1) {
	m_nodes[noa].m_height = d.height + 10;
	m_nodes[noa].m_width = d.width + 8;
	m_nodes[noa].m_side = m_nodes[noa].m_width / 2;
      }
      else if (m_nodes[noa].m_node.getShape() == 2) {
	m_nodes[noa].m_height = (int)((d.height + 2) * 1.6);
	m_nodes[noa].m_width = (int)((d.width + 2) * 1.6);
	m_nodes[noa].m_side = m_nodes[noa].m_width / 2;
      }
      
      if (noa < m_numNodes - 1) {
	//this will do the same for edges
	
	d = m_edges[noa].m_edge.stringSize(m_fontSize);
	
	m_edges[noa].m_height =  d.height + 8;
	m_edges[noa].m_width = d.width + 8;
	m_edges[noa].m_side = m_edges[noa].m_width / 2;
	m_edges[noa].m_tb = m_edges[noa].m_height / 2;
      }
    }
  }

  /**
   * This will fill two arrays with the Nodes and Edges from the tree
   * into a particular order.
   *
   * @param t The top Node of the tree.
   * @param l An array that has already been allocated, to be filled.
   * @param k An array that has already been allocated, to be filled.
   */
  private void arrayFill(Node t, NodeInfo[] l, EdgeInfo[] k) {
    
    //this will take the top node and the array to fill
    //it will go through the tree structure and and fill the array with the 
    //nodes 
    //from top to bottom left to right
    
    //note I do not believe this function will be able to deal with multiple 
    //parents

    if (t == null || l == null) {
      System.exit(1);      //this is just a preliminary safety check 
      //(i shouldn' need it)
    }
    
    Edge e;
    Node r,s;
    l[0] = new NodeInfo();
    l[0].m_node = t;
    l[0].m_parent = -1;
    l[0].m_change = true;
    
    int floater;       //this will point at a node that has previously been 
    //put in the list 
    //all of the children that this node has shall be put in the list , 
    //once this is done the floater shall point at the next node in the list
    //this will allow the nodes to be put into order from closest to top node
    //to furtherest from top node

    int free_space = 1; //the next empty array position

    double height = t.getTop(); //this will be used to determine if the node 
    //has a 
    //new height compared to the
    //previous one

    for (floater = 0;floater < free_space;floater++) {
      r = l[floater].m_node;
      for (int noa = 0;(e = r.getChild(noa)) != null;noa++) {
	//this loop pulls out each child of r
	
	//e points to a child edge, getTarget will return that edges child node
	s = e.getTarget();
	l[free_space] = new NodeInfo();
	l[free_space].m_node = s;
	l[free_space].m_parent = free_space - 1;
	
	k[free_space - 1] = new EdgeInfo();
	k[free_space - 1].m_edge = e;
	k[free_space - 1].m_parent = floater;
	k[free_space - 1].m_child = free_space;     //note although it's child 
	//will always have a subscript
	//of 1 more , I may not nessecarily have access to that
	//and it will need the subscr.. for multiple parents
	
	//determine if level of node has changed from previous one
	if (height != s.getTop()) {
	  l[free_space].m_change = true;
	  height = s.getTop();
	}
	else {
	  l[free_space].m_change = false;
	}
	free_space++;
      }
    }
  }

  /**
   * Internal Class for containing display information about a Node. 
   */
  private class NodeInfo {
    //this class contains a pointer to the node itself along with extra 
    //information
    //about the node used by the Displayer class

    /** The y pos of the node on screen. */
    int m_top = 32000;           //the main node coords calculated out

    /** The x pos of the node on screen. */
    int m_center;        // these coords will probably change each refresh 

    //and are the positioning coords
    //which the rest of the offsets use
    
    /** The offset to get to the left or right of the node. */
    int m_side;          //these are the screen offset for the dimensions of 

    //the node relative to the nodes 
    //internal top and center values (after they have been converted to 
    //screen coords
    /** The width of the node. */
    int m_width;

    /** The height of the node. */
    int m_height;

    /** True if the node is at the start (left) of a new level (not sibling 
     * group). */
    boolean m_change;    //this is quickly used to identify whether the node 
    //has chenged height from the
    //previous one to help speed up the calculation of what row it lies in

    /** The subscript number of the Nodes parent. */
    int m_parent;     //this is the index of the nodes parent edge in an array

    /** The rough position of the node relative to the screen. */
    int m_quad;       //what of nine quadrants is it in

    /*
      12 10  9
      20 18 17          //18 being the screen
      36 34 33          //this arrangement uses 6 bits, each bit represents a 
      row or column
    */

    /** The Node itself. */
    Node m_node;
  }

  /**
   * Internal Class for containing display information about an Edge. 
   */
  private class EdgeInfo {
    //this class contains a pointer to the edge along with all the other
    //extra info about the edge
    
    /** The parent subscript (for a Node). */
    int m_parent;            //array indexs for its two connections

    /** The child subscript (for a Node). */
    int m_child;
    

    /** The distance from the center of the text to either side. */
    int m_side;            //these are used to describe the dimensions of the 
    //text

    /** The distance from the center of the text to top or bottom. */
    int m_tb;              //tb stands for top , bottom, this is simply the 
    //distance from the middle to top bottom

    /** The width of the text. */
    int m_width;

    /** The height of the text. */
    int m_height;

    /** The Edge itself. */
    Edge m_edge;
  }

  /**
   * Main method for testing this class.
   * @param args first argument should be the name of a file that contains
   * a tree discription in dot format.
   */
  public static void main(String[] args)
  {
    try
      {
	//put in the random data generator right here
	// this call with import java.lang gives me between 0 and 1 Math.random
	TreeBuild builder = new TreeBuild();
	Node top = null;
	NodePlace arra

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -