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

📄 graphvisualizer.java

📁 MacroWeka扩展了著名数据挖掘工具weka
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
    }
  }
  
  
  /**
   * The panel which contains the actual  graph.
   *
   */
  private class GraphPanel extends PrintablePanel {
    //Image buf;
    public GraphPanel() {
      super();
      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)
          //Drawing all the edges from and upward ones coming to the node
          for(int k=0; k<n.edges.length; k++) {
            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;
              x2=n2.x+paddedNodeWidth/2; y2=n2.y+nodeHeight;
              g.drawLine(x+x1, y+y1, x+x2, y+y2);
              

⌨️ 快捷键说明

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