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

📄 graphvisualizer.java

📁 一个数据挖掘软件ALPHAMINERR的整个过程的JAVA版源代码
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
    *  Reads a graph description in DOT format from a string
    *
    *********************************************************
    */
    public void readDOT(Reader input) {
	DotParser dp = new DotParser(input, m_nodes, m_edges);
	graphID = dp.parse();

	setAppropriateNodeSize();
	if(m_le!=null) { 
	    m_le.setNodeSize(paddedNodeWidth, nodeHeight);
	    jBtLayout.setEnabled(false);
	    layoutGraph();
	}
    }


    /**
     * The panel which contains the actual  graph.
     *
     */
    private class GraphPanel extends JPanel {
	//Image buf;
	public GraphPanel() {
	    this.addMouseListener( new GraphVisualizerMouseListener() );
	    this.addMouseMotionListener( new GraphVisualizerMouseMotionListener() );
	    this.setToolTipText("");
	}
	
	public String getToolTipText(MouseEvent me) {
	   int x, y, nx, ny;
	   Rectangle r;
	   GraphNode n; 
	   Dimension d = m_gp.getPreferredSize();
	   //System.out.println("Preferred Size: "+this.getPreferredSize()+" Actual Size: "+this.getSize());
	   x=y=nx=ny=0;
	   
	   if(d.width < m_gp.getWidth())
	       nx = (int)((nx + m_gp.getWidth()/2 - d.width/2)/scale);
	   if(d.height < m_gp.getHeight())
	       ny = (int)((ny + m_gp.getHeight()/2 - d.height/2)/scale);
	   
	   r=new Rectangle(0, 0, (int)(paddedNodeWidth*scale), (int)(nodeHeight*scale));
	   x += me.getX(); y += me.getY();
	   
	   int i;
	   for(i=0; i<m_nodes.size(); i++) {
	       n = (GraphNode) m_nodes.elementAt(i);
	       if(n.nodeType!=NORMAL)
		   return null;
	       r.x = (int)((nx+n.x)*scale); r.y = (int)((ny+n.y)*scale);
	       if(r.contains(x,y)) {
		   if(n.probs==null)
		       return n.lbl;
		   else
		       return n.lbl+" (click to view the probability dist. table)";
	       }
	   }
	   return null;
	}

	
	public void paintComponent(Graphics gr) {
	    Graphics2D g = (Graphics2D)gr;
	    RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, 
						   RenderingHints.VALUE_ANTIALIAS_ON);
	    rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
	    g.setRenderingHints(rh);
	    g.scale(scale, scale);
	    Rectangle r = g.getClipBounds();
	    g.clearRect(r.x,r.y,r.width,r.height);
	    //g.setColor(this.getBackground());
	    //g.fillRect(0, 0, width+5, height+5);
	    int x=0, y=0;
	    Dimension d = this.getPreferredSize();
	    //System.out.println("Preferred Size: "+this.getPreferredSize()+" Actual Size: "+this.getSize());
	    
	    //initializing x & y to display the graph in the middle
	    //if the display area is larger than the graph
	    if(d.width < this.getWidth())
	    	x = (int)((x + this.getWidth()/2 - d.width/2)/scale);
	    if(d.height < this.getHeight())
		y = (int)((y + this.getHeight()/2 - d.height/2)/scale);
	    
	    for(int index=0; index<m_nodes.size(); index++) {
		GraphNode n = (GraphNode) m_nodes.elementAt(index);
		if( n.nodeType==NORMAL) { 
		    g.setColor( this.getBackground().darker().darker() );
		    g.fillOval(x+n.x+paddedNodeWidth-nodeWidth-(paddedNodeWidth-nodeWidth)/2, y+n.y, 
			       nodeWidth, nodeHeight);
		    
		    g.setColor(Color.white);
		    //g.setColor(Color.black);
		    //System.out.println("drawing "+((GraphNode)m_nodes.elementAt(index)).ID+" at "+
		    //		       " x: "+(x+n.x+paddedNodeWidth/2-fm.stringWidth( ((GraphNode)m_nodes.elementAt(index)).ID )/2)+
		    //		       " y: "+(y+n.y+nodeHeight/2+fm.getHeight()/2-2) );


		    //Draw the node's label if it can fit inside the node's current
		    // width otherwise display its ID or otherwise just display its
		    // idx in the FastVector (to distinguish it from others)
		    // if any can fit in node's current width
		    if(fm.stringWidth(n.lbl)<=nodeWidth) 
			g.drawString( n.lbl, 
				      x+n.x+paddedNodeWidth/2
				      -fm.stringWidth( n.lbl )/2, 
				      y+n.y+nodeHeight/2+fm.getHeight()/2-2 );
		    else if(fm.stringWidth(n.ID)<=nodeWidth) 
			g.drawString( n.ID, 
				      x+n.x+paddedNodeWidth/2
				      -fm.stringWidth( n.ID )/2, 
				      y+n.y+nodeHeight/2+fm.getHeight()/2-2 );
		    else if(fm.stringWidth( Integer.toString(index) )<=nodeWidth)
			g.drawString( Integer.toString(index), 
				      x+n.x+paddedNodeWidth/2
				      -fm.stringWidth( Integer.toString(index) )/2, 
				      y+n.y+nodeHeight/2+fm.getHeight()/2-2 );
				
		    g.setColor(Color.black);
		}
		else {
		    //g.draw( new java.awt.geom.QuadCurve2D.Double(n.x+paddedNodeWidth/2, n.y,
		    //					n.x+paddedNodeWidth-nodeSize
		    //                                      -(paddedNodeWidth-nodeSize)/2, n.y+nodeHeight/2,
		    //					n.x+paddedNodeWidth/2, n.y+nodeHeight) ); 
		    g.drawLine(x+n.x+paddedNodeWidth/2, y+n.y, x+n.x+paddedNodeWidth/2, y+n.y+nodeHeight);

		}
		
		GraphNode n2; 
		int x1, y1, x2, y2;
		//System.out.println("Drawing edges of "+n.lbl);
		
		//Drawing all the edges coming out from the node, including reversed and double ones
		if(n.edges!=null)    
		    for(int k=0; k<n.edges.length; k++) {
			if(n.edges[k][1]>0) {
			    n2 = (GraphNode) m_nodes.elementAt(n.edges[k][0]); //m_nodes.elementAt(k);
			    //System.out.println("  -->to "+n2.lbl);
			    x1=n.x+paddedNodeWidth/2; y1=n.y+nodeHeight;
			    x2=n2.x+paddedNodeWidth/2; y2=n2.y;
			    g.drawLine(x+x1, y+y1, x+x2, y+y2);
			    if(n.edges[k][1]==DIRECTED) {
				if(n2.nodeType==n2.NORMAL)
				    drawArrow(g, x+x1, y+y1, x+x2, y+y2);
			    }
			    else if(n.edges[k][1]==REVERSED) {
				if(n.nodeType==NORMAL)
				    drawArrow(g, x+x2, y+y2, x+x1, y+y1);
			    }
			    else if(n.edges[k][1]==DOUBLE) {
				if(n.nodeType==NORMAL) 
				    drawArrow(g, x+x2, y+y2, x+x1, y+y1);
				if(n2.nodeType==NORMAL)
				    drawArrow(g, x+x1, y+y1, x+x2, y+y2);
			    }
			}
		    }
	    }
	}

	/**
	   This method draws an arrow on a line from (x1,y1)
	   to (x2,y2). The arrow head is seated on (x2,y2) and 
	   is in the direction of the line.
	   If the arrow is needed to be drawn in the opposite
	   direction then simply swap the order of (x1, y1)
	   and (x2, y2) when calling this function.
	 */
	protected void drawArrow(Graphics g, int x1, int y1, int x2, int y2) { 
	    
	    if(x1==x2) {
		if(y1<y2) {
		    g.drawLine(x2, y2, x2+4, y2-8);
		    g.drawLine(x2, y2, x2-4, y2-8);
		}
		else {
		    g.drawLine(x2, y2, x2+4, y2+8);
		    g.drawLine(x2, y2, x2-4, y2+8);
		}
	    }
	    else {
		//theta=line's angle from base, beta=angle of arrow's side from line
		double hyp=0, base=0, perp=0, theta, beta;
		int x3=0, y3=0;
		
		if(x2<x1) {
		    base = x1-x2; hyp = Math.sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
		    theta = Math.acos( base/hyp );
		}
		else { //x1>x2 as we already checked x1==x2 before
		    base = x1-x2; hyp = Math.sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
		    theta = Math.acos( base/hyp );			    
		}
		beta = 30*Math.PI/180;
		//System.out.println("Original base "+base+" perp "+perp+" hyp "+hyp+"\ntheta "+theta+" beta "+beta);
		
		hyp = 8; 
		base = Math.cos(theta-beta)*hyp;
		perp = Math.sin(theta-beta)*hyp;
		
		x3 = (int)(x2+base); 
		if(y1<y2)
		    y3 = (int)(y2-perp);
		else
		    y3 = (int)(y2+perp);
		
		//System.out.println("Drawing 1 from "+x2+","+y2+" to "+x3+","+y3+" x1,y1 is "+x1+","+y1+" base "+base+
		//		       " perp "+perp+" cos(theta-beta) "+Math.cos(theta-beta));
		g.drawLine(x2, y2, x3, y3);
		
		base = Math.cos(theta+beta)*hyp;
		perp = Math.sin(theta+beta)*hyp;
		
		x3 = (int)(x2+base); 
		if(y1<y2)
		    y3 = (int)(y2-perp);
		else
		    y3 = (int)(y2+perp);
		//System.out.println("Drawing 2 from "+x2+","+y2+" to "+x3+","+y3+" x1,y1 is "+x1+","+y1+" base "+base+
		//		       " perp "+perp);
		g.drawLine(x2, y2, x3, y3);
	    }
	}

	/**
	   This method highlights a given node and all its children 
	   and the edges coming out of it.
	 */
	public void highLight(GraphNode n) {
	    Graphics2D g = (Graphics2D) this.getGraphics();
	    RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
	    rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
	    g.setRenderingHints(rh);
	    g.setPaintMode();
	    g.scale(scale, scale);
	    int x=0, y=0;
	    Dimension d = this.getPreferredSize();
	    //System.out.println("Preferred Size: "+this.getPreferredSize()+" Actual Size: "+this.getSize());
	    
	    //initializing x & y to display the graph in the middle
	    //if the display area is larger than the graph
	    if(d.width < this.getWidth())
		x = (int)((x + this.getWidth()/2 - d.width/2)/scale);
	    if(d.height < this.getHeight())
		y = (int)((y + this.getHeight()/2 - d.height/2)/scale);
	    
	    //if the node is of type NORMAL only then highlight
	    if(n.nodeType==NORMAL) { 

		g.setXORMode(Color.green); //g.setColor(Color.green);

		g.fillOval(x+n.x+paddedNodeWidth-nodeWidth-(paddedNodeWidth-nodeWidth)/2, y+n.y, nodeWidth, nodeHeight);
		g.setXORMode(Color.red);
		
		//Draw the node's label if it can fit inside the node's current
		// width otherwise display its ID or otherwise just display its
		// idx in the FastVector (to distinguish it from others)
		// if any can fit in node's current width
		if(fm.stringWidth(n.lbl)<=nodeWidth) 
		    g.drawString( n.lbl, 
				  x+n.x+paddedNodeWidth/2
				  -fm.stringWidth( n.lbl )/2, 
				  y+n.y+nodeHeight/2+fm.getHeight()/2-2 );
		else if(fm.stringWidth(n.ID)<=nodeWidth) 
		    g.drawString( n.ID, 
				  x+n.x+paddedNodeWidth/2
				  -fm.stringWidth( n.ID )/2, 
				  y+n.y+nodeHeight/2+fm.getHeight()/2-2 );
		else if(fm.stringWidth( Integer.toString(m_nodes.indexOf(n)) )<=nodeWidth)
		    g.drawString( Integer.toString(m_nodes.indexOf(n)), 
				  x+n.x+paddedNodeWidth/2
				  -fm.stringWidth( Integer.toString(m_nodes.indexOf(n)) )/2, 
				  y+n.y+nodeHeight/2+fm.getHeight()/2-2 );

		g.setXORMode(Color.green); 
	
		
		GraphNode n2; 
		int x1, y1, x2, y2;
		//System.out.println("Drawing edges of "+n.lbl);
		if(n.edges!=null) 
		    for(int k=0; k<n.edges.length; k++) {   //Drawing all the edges from and upward ones coming to the node
			if(n.edges[k][1]==DIRECTED || n.edges[k][1]==DOUBLE) {
			    n2 = (GraphNode) m_nodes.elementAt(n.edges[k][0]); //m_nodes.elementAt(k);
			    //System.out.println("  -->to "+n2.lbl);
			    x1=n.x+paddedNodeWidth/2; y1=n.y+nodeHeight;
			    x2=n2.x+paddedNodeWidth/2; y2=n2.y;
			    g.drawLine(x+x1, y+y1, x+x2, y+y2);
			    if(n.edges[k][1]==DIRECTED) {
				if(n2.nodeType==n2.NORMAL) //!n2.dummy)
				    drawArrow(g, x+x1, y+y1, x+x2, y+y2);
			    }
			    else if(n.edges[k][1]==DOUBLE) {
				if(n.nodeType==NORMAL) //!n.dummy)
				    drawArrow(g, x+x2, y+y2, x+x1, y+y1);
				if(n2.nodeType==NORMAL) //!n2.dummy)
				    drawArrow(g, x+x1, y+y1, x+x2, y+y2);
			    }
			    if(n2.nodeType==NORMAL)
				g.fillOval(x+n2.x+paddedNodeWidth-nodeWidth-(paddedNodeWidth-nodeWidth)/2, y+n2.y, nodeWidth, nodeHeight);

			    //If n2 is not of NORMAL type
			    // then carry on drawing all the edges and add all the 
			    // dummy nodes encountered in a Vector until no
			    // more dummy nodes are found and all the child nodes(node n2)
			    // are of type normal
			    java.util.Vector t = new java.util.Vector();
			    while(n2.nodeType!=NORMAL || t.size()>0) { //n2.dummy==true) {
				//System.out.println("in while processing "+n2.ID);
				if(t.size()>0)
				    { n2 = (GraphNode)t.elementAt(0); 
				    t.removeElementAt(0); }
				if(n2.nodeType!=NORMAL) {
				    g.drawLine(x+n2.x+paddedNodeWidth/2, y+n2.y, x+n2.x+paddedNodeWidth/2, y+n2.y+nodeHeight);		    
				    x1=n2.x+paddedNodeWidth/2; y1=n2.y+nodeHeight;
				    //System.out.println("Drawing from "+n2.lbl);
				    for(int m=0; m<n2.edges.length; m++) {
					//System.out.println(" to "+n2.lbl+", "+graphMatrix[tmpIndex][m]);
					if(n2.edges[m][1]>0) {
					    GraphNode n3 = (GraphNode) m_nodes.elementAt(n2.edges[m][0]); //m_nodes.elementAt(m);
					    g.drawLine(x+x1, y+y1, x+n3.x+paddedNodeWidth/2, y+n3.y);
					    
					    if(n3.nodeType==NORMAL){ //!n2.dummy)
						g.fillOval(x+n3.x+paddedNodeWidth-nodeWidth-(paddedNodeWidth-nodeWidth)/2, y+n3.y, nodeWidth, nodeHeight);
						drawArrow(g, x+x1, y+y1, x+n3.x+paddedNodeWidth/2, y+n3.y);
					    }
					    //if(n3.nodeType!=n3.NORMAL)
					    t.addElement(n3);
					    //break;
					}
				    }
				}
			    }
			}
			else if(n.edges[k][1]==-REVERSED || n.edges[k][1]==-DOUBLE) {
			    //Drawing all the reversed and double edges which are going
			    //upwards in the drawing.
			    n2 = (GraphNode) m_nodes.elementAt(n.edges[k][0]); //m_nodes.elementAt(k);
			    //System.out.println("  -->to "+n2.lbl);
			    x1=n.x+paddedNodeWidth/2; y1=n.y;

⌨️ 快捷键说明

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