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

📄 treevisualizer.java

📁 MacroWeka扩展了著名数据挖掘工具weka
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
      
      
    }
    else if (m_mouseState == 3) {
      //then zoom box being created
      //redraw the zoom box
      Graphics g = getGraphics();
      g.setColor(Color.black);
      g.setXORMode(Color.white);
      g.drawRect(m_oldMousePos.width, m_oldMousePos.height,
		 m_newMousePos.width - m_oldMousePos.width, 
		 m_newMousePos.height - m_oldMousePos.height);
      
      m_newMousePos.width = e.getX();
      m_newMousePos.height = e.getY();
      
      g.drawRect(m_oldMousePos.width, m_oldMousePos.height,
		 m_newMousePos.width - m_oldMousePos.width, 
		 m_newMousePos.height - m_oldMousePos.height);
      g.dispose();
    }
    
    
  }
  
  /**
   * Does nothing.
   *
   * @param e the mouse event.
   */
  public void mouseMoved(MouseEvent e) {
  }

  /**
   * Does nothing.
   *
   * @param e the mouse event.
   */
  public void mouseEntered(MouseEvent e) {
  }
  
  /**
   * Does nothing.
   * 
   * @param e the mouse event.
   */
  public void mouseExited(MouseEvent e) {
  }

  /**
   * Set the highlight for the node with the given id
   * @param id the id of the node to set the highlight for
   */
  public void setHighlight(String id) {
    //set the highlight for the node with the given id
    
    for (int noa = 0; noa < m_numNodes; noa++) {
      if (id.equals(m_nodes[noa].m_node.getRefer())) {
	//then highlight this node
	m_highlightNode = noa;
      }
    }
    //System.out.println("ahuh " + highlight_node + " " + 
    //nodes[0].node.getRefer());
    repaint();
    
  }
  
  /**
   * Updates the screen contents.
   *
   * @param g the drawing surface.
   */
  public void paintComponent(Graphics g) {
    //System.out.println(nodes[0].top + "this is seriously pissing me off");
    g.clearRect(0, 0, getSize().width, getSize().height);
    g.setClip(3, 7, getWidth() - 6, getHeight() - 10);
    painter(g);
    g.setClip(0, 0, getWidth(), getHeight());
    
  }

  /**
   * Draws the tree to the graphics context
   *
   * @param g the drawing surface.
   */
  private void painter(Graphics g) {
    //I have moved what would normally be in the paintComponent 
    //function to here 
    //for now so that if I do in fact need to do double 
    //buffering or the like it will be easier

    //this will go through the table of edges and draw the edge if it deems the
    //two nodes attached to it could cause it to cut the screen or be on it.
    
    //in the process flagging all nodes so that they can quickly be put to the
    //screen if they lie on it

    //I do it in this order because in some circumstances I have seen a line
    //cut through a node , to make things look better the line will
    //be drawn under the node


    //converting the screen edges to the node scale so that they 
    //can be positioned relative to the screen
    //note I give a buffer around the edges of the screen.
    
    //when seeing
    //if a node is on screen I only bother to check the nodes top centre 
    //if it has large enough size it may still fall onto the screen
    double left_clip = (double)(-m_viewPos.width - 50) / m_viewSize.width;
    double right_clip = (double)(getSize().width - m_viewPos.width + 50) / 
      m_viewSize.width;
    double top_clip = (double)(-m_viewPos.height - 50) / m_viewSize.height;
    double bottom_clip = (double)(getSize().height - m_viewPos.height + 50) / 
      m_viewSize.height;
  

    
    //  12 10  9           //the quadrants
    //  20 18 17
    //  36 34 33


    //first the edges must be rendered

    Edge e;
    Node r,s;
    double ncent,ntop;    

    int row = 0, col = 0, pq, cq;
    for (int noa = 0 ; noa < m_numNodes ; noa++) {
      r = m_nodes[noa].m_node;
      if (m_nodes[noa].m_change) {
	//then recalc row component of quadrant
	ntop = r.getTop();
	if (ntop < top_clip) {
	  row = 8;
	}
	else if (ntop > bottom_clip) {
	  row = 32;
	}
	else {
	  row = 16;
	}
      }
      
      //calc the column the node falls in for the quadrant
      ncent = r.getCenter();
      if (ncent < left_clip) {
	col = 4;
      }
      else if (ncent > right_clip) {
	col = 1;
      }
      else {
	col = 2;
      }
      
      m_nodes[noa].m_quad = row | col;
      
      if (m_nodes[noa].m_parent >= 0) {
	//this will draw the edge if it should be drawn 
	//It will do this by eliminating all edges that definitely won't enter
	//the screen and then draw the rest
	
	pq = m_nodes[m_edges[m_nodes[noa].m_parent].m_parent].m_quad;
	cq = m_nodes[noa].m_quad;
	
	//note that this will need to be altered if more than 1 parent exists
	if ((cq & 8) == 8) {
	  //then child exists above screen
	}
	else if ((pq & 32) == 32) {
	  //then parent exists below screen
	}
	else if ((cq & 4) == 4 && (pq & 4) == 4) {
	  //then both child and parent exist to the left of the screen
	}
	else if ((cq & 1) == 1 && (pq & 1) == 1) {
	  //then both child and parent exist to the right of the screen
	}
	else {
	  //then draw the line
	  drawLine(m_nodes[noa].m_parent, g);
	}
      }
      
      //now draw the nodes
    }
    
    for (int noa = 0 ;noa < m_numNodes; noa++) {
      if (m_nodes[noa].m_quad == 18) {
	//then the node is on the screen , draw it
	drawNode(noa, g);
      }
    }
    
    if (m_highlightNode >= 0 && m_highlightNode < m_numNodes) {
      //then draw outline
      if (m_nodes[m_highlightNode].m_quad == 18) {
	Color acol = m_nodes[m_highlightNode].m_node.getColor();
	g.setColor(new Color((acol.getRed() + 125) % 256, 
			     (acol.getGreen() + 125) % 256, 
			     (acol.getBlue() + 125) % 256));
	//g.setXORMode(Color.white);
	if (m_nodes[m_highlightNode].m_node.getShape() == 1) {
	  g.drawRect(m_nodes[m_highlightNode].m_center 
		     - m_nodes[m_highlightNode].m_side,
		     m_nodes[m_highlightNode].m_top, 
		     m_nodes[m_highlightNode].m_width, 
		     m_nodes[m_highlightNode].m_height);
	  
	  g.drawRect(m_nodes[m_highlightNode].m_center 
		     - m_nodes[m_highlightNode].m_side 
		     + 1, m_nodes[m_highlightNode].m_top + 1,
		     m_nodes[m_highlightNode].m_width - 2, 
		     m_nodes[m_highlightNode].m_height - 2);
	}
	else if (m_nodes[m_highlightNode].m_node.getShape() == 2) {
	  g.drawOval(m_nodes[m_highlightNode].m_center 
		     - m_nodes[m_highlightNode].m_side,
		     m_nodes[m_highlightNode].m_top, 
		     m_nodes[m_highlightNode].m_width, 
		     m_nodes[m_highlightNode].m_height);
	  
	  g.drawOval(m_nodes[m_highlightNode].m_center 
		     - m_nodes[m_highlightNode].m_side 
		     + 1, m_nodes[m_highlightNode].m_top + 1,
		     m_nodes[m_highlightNode].m_width - 2, 
		     m_nodes[m_highlightNode].m_height - 2);
	}
      }
    }
    
    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;
    }
  }
  
  /**
   * Determines the attributes of the node and draws it.
   *
   * @param n A subscript identifying the node in <i>nodes</i> array
   * @param g The drawing surface
   */
  private void drawNode(int n, Graphics g) {
    //this will draw a node and then print text on it
    
    g.setColor(m_nodes[n].m_node.getColor());
    g.setPaintMode();
    calcScreenCoords(n);
    int x = m_nodes[n].m_center - m_nodes[n].m_side;
    int y = m_nodes[n].m_top;
    if (m_nodes[n].m_node.getShape() == 1) {
      g.fill3DRect(x, y, m_nodes[n].m_width, m_nodes[n].m_height, true);
      drawText(x, y, n, false, g);
      
    }
    else if (m_nodes[n].m_node.getShape() == 2) {
      
      g.fillOval(x, y, m_nodes[n].m_width, m_nodes[n].m_height);
      drawText(x, y + (int)(m_nodes[n].m_height * .15), n, false, g);
    }
  }
  
  /**
   * Determines the attributes of the edge and draws it.
   *
   * @param e A subscript identifying the edge in <i>edges</i> array.
   * @param g The drawing surface.
   */
  private void drawLine(int e, Graphics g) {
    //this will draw a line taking in the edge number and then getting 
    //the nodes subscript for the parent and child entries
    
    //this will draw a line that has been broken in the middle 
    //for the edge text to be displayed 
    //if applicable
    
    //first convert both parent and child node coords to screen coords
    int p = m_edges[e].m_parent;
    int c = m_edges[e].m_child;
    calcScreenCoords(c);
    calcScreenCoords(p);
    
    g.setColor(Color.black);
    g.setPaintMode();
    
    if (m_currentFont.getSize() < 2) {
      //text to small to bother cutting the edge
      g.drawLine(m_nodes[p].m_center, m_nodes[p].m_top + m_nodes[p].m_height, 
		 m_nodes[c].m_center, m_nodes[c].m_top); 
      
    }
    else {
      //find where to cut the edge to insert text
      int e_width = m_nodes[c].m_center - m_nodes[p].m_center;
      int e_height = m_nodes[c].m_top - (m_nodes[p].m_top 
					 + m_nodes[p].m_height);
      int e_width2 = e_width / 2;
      int e_height2 = e_height / 2;
      int e_centerx = m_nodes[p].m_center + e_width2;
      int e_centery = m_nodes[p].m_top + m_nodes[p].m_height + e_height2;
      int e_offset = m_edges[e].m_tb;
      
      int tmp = (int)(((double)e_width / e_height) * 
		      (e_height2 - e_offset)) + m_nodes[p].m_center;
      //System.out.println(edges[e].m_height);
      
      //draw text now
      
      drawText(e_centerx - m_edges[e].m_side, e_centery - e_offset, e, true
	       , g);
      
      
      if (tmp > (e_centerx - m_edges[e].m_side) && tmp 
	  < (e_centerx + m_edges[e].m_side)) {
	//then cut line on top and bottom of text
	g.drawLine(m_nodes[p].m_center, m_nodes[p].m_top + m_nodes[p].m_height
		   , tmp, e_centery - e_offset);  //first segment
	g.drawLine(e_centerx * 2 - tmp, e_centery + e_offset, 
		   m_nodes[c].m_center, m_nodes[c].m_top);    //second segment
      }
      else {
	e_offset = m_edges[e].m_side;
	if (e_width < 0) {
	  e_offset *= -1;   //adjusting for direction which could otherwise 
	  //screw up the calculation
	}
	tmp = (int)(((double)e_height / e_width) * (e_width2 - e_offset)) + 
	  m_nodes[p].m_top + m_nodes[p].m_height;
	
	g.drawLine(m_nodes[p].m_center, m_nodes[p].m_top + m_nodes[p].m_height
		   , e_centerx - e_offset, tmp);   //first segment
	g.drawLine(e_centerx + e_offset, e_centery * 2 - tmp, 
		   m_nodes[c].m_center, m_nodes[c].m_top);  //second segment
	
      }
    }
    //System.out.println("here" + nodes[p].center);
  }

  /**
   * Draws the text for either an Edge or a Node.
   *
   * @param x1 the left side of the text area.
   * @param y1 the top of the text area.
   * @param s A subscript identifying either a Node or Edge.
   * @param e_or_n Distinguishes whether it is a node or edge.
   * @param g The drawing surface.
   */
  private void drawText(int x1, int y1, int s, boolean e_or_n, Graphics g) {
    //this function will take in the rectangle that the text should be 
    //drawn in as well as the subscript
    //for either the edge or node and a boolean variable to tell which

    g.setPaintMode();
    g.setColor(Color.black);
    String st;
    if (e_or_n) {
      //then paint for edge
      Edge e = m_edges[s].m_edge;
      for (int noa = 0;(st = e.getLine(noa)) != null; noa++) {
	g.drawString(st, (m_edges[s].m_width - m_fontSize.stringWidth(st)) / 2 
		     + x1,
		     y1 + (noa + 1) * m_fontSize.getHeight()); 
      }
    }
    else {
      //then paint for node
      Node e = m_nodes[s].m_node;
      for (int noa = 0;(st = e.getLine(noa)) != null; noa++) {
	g.drawString(st, (m_nodes[s].m_width - m_fontSize.stringWidth(st)) / 2 
		     + x1,
		     y1 + (noa + 1) * m_fontSize.getHeight()); 
      }
    }
  }
  
  /**
   * Converts the internal coordinates of the node found from <i>n</i>
   * and converts them to the actual screen coordinates.
   *
   * @param n A subscript identifying the Node.
   */
  private void calcScreenCoords(int n) {
    //this converts the coordinate system the Node uses into screen coordinates
    // System.out.println(n + " " + view_pos.height + " " + 
    //nodes[n].node.getCenter());
    if (m_nodes[n].m_top == 32000) {
      m_nodes[n].m_top = ((int)(m_nodes[n].m_node.getTop() 
				* m_viewSize.height)) + m_viewPos.height;
      m_nodes[n].m_center = ((int)(m_nodes[n].m_node.getCenter() 
				   * m_viewSize.width)) + m_viewPos.width;
    }
  }

  /**
   * This Calculates the minimum size of the tree which will prevent any text
   * overlapping and make it readable, and then set the size of the tree to 
   * this.
   */
  private void autoScale() {
    //this function will determine the smallest scale value that keeps the text

⌨️ 快捷键说明

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