1

我正在寻找绘制边缘和节点的框架。我想创建一个可视化图表,它应该是可拖动的。

我试过http://code.google.com/p/gwt-diagrams但这个项目失败了。

你的建议是什么?

4

2 回答 2

2
import java.awt.Color;    
import java.awt.Font;    
import java.awt.FontMetrics;    
import java.awt.Graphics2D;    
import java.awt.image.BufferedImage;    
import java.io.File;    
import java.io.FileOutputStream;    
import java.util.ArrayList;    
import java.util.HashSet;    
import java.util.Hashtable;    
import java.util.Iterator;
import java.util.LinkedList;    
import com.sun.image.codec.jpeg.JPEGCodec;    
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/****
 *
 *
 * A program that takes a comma seperated tree values and converts it into an image
 * Ex: root-child1,root-child2,child1-children1,child2-children2...
 *
 *
 * */    

public class DrawGraph {    
 private Hashtable listparent         = new Hashtable();
 private Hashtable keyerrors    = new Hashtable();
 private Hashtable nodetree     = new Hashtable();
 private Hashtable connectNodes    = new Hashtable();
 private LinkedList rowsLinkedList   = new LinkedList();
 private static int start_xaxis    = 0;
 private static int start_yaxis    = 40;
 private static int xaxis     = 800;
 private static int yaxis     = 600;
 private static int end_xaxis    = 0;
 private static int maxy     = 0;
 private static int rectx     = 0;
 private static int recty     = 0;
 private int rows     = 0;
 private static String root;
 private static Graphics2D g;
 private static int bigx = 0;
 private int bigy = 0;

 private Hashtable _listparent         = new Hashtable();
 private Hashtable _keyerrors     = new Hashtable();
 private Hashtable _nodetree     = new Hashtable();
 private Hashtable _connectNodes    = new Hashtable();
 private LinkedList _rowsLinkedList   = new LinkedList();
 private static int _start_xaxis    = 0;
 private static int _start_yaxis    = 40;
 private static int _xaxis     = 1000;
 private static int _yaxis     = 800;
 private static int _end_xaxis    = 0;
 private static int _maxy     = 0;
 private static int _rectx     = 0;
 private static int _recty     = 0;
 private int _rows     = 0;
 private static String _root;    
 private static Graphics2D _g;

 public static void main(String args[]) {
  if (args.length == 0) {
   System.out.println("USAGE:  ");
   System.out.println("DrawGraph <queryString> <imagelocation>  ");    
  }
  DrawGraph myn = new DrawGraph();
  args[0]= "root(1/2)-child1,root-child2,child1-children1,child2-children2(test1/test2)";
  args[1]="c:/test.jpeg";
  myquery=args[0];
  myoutput = args[1];
  myn.initialize(args[0], args[1]);
 }

 private static String myquery  = new String();
 private static String myoutput = new String();

 public String getErrors(String qstring) {    
  StringBuffer sb = new StringBuffer();
  String[] namevalues = qstring.split(",");
  for (int i = 0; i < namevalues.length; i++) {
   String _key   = namevalues[i].split("-")[0];
   String _children = namevalues[i].split("-")[1];

   String[] errors  = _key.split("\\(");
   String[] errorsc  = _children.split("\\(");

   String mykey    = errors[0];
   String mychildrenkey = errorsc[0];

   LinkedList lk   = new LinkedList();
   if (null != listparent.get(mychildrenkey)) {
    lk = (LinkedList) listparent.get(mychildrenkey);    
   }

   lk.add(mykey);
   listparent.put(mychildrenkey, lk);

   if (i == 0)
    root = mykey;
   LinkedList _chil = new LinkedList();

   try {
    _chil = (LinkedList) nodetree.get(mykey);
    if (null == _chil) {
     _chil = new LinkedList();    
    }
   } catch (Exception ee) {    
   }
   _chil.add(errorsc[0]);
   nodetree.put(mykey, _chil);

   sb.append(mykey + "-" + _children + ",");

   LinkedList l = new LinkedList();
   if (null != keyerrors.get(mykey))
    l = (LinkedList) keyerrors.get(mykey);
   if (errors.length > 1) {
    String[] ers = errors[1].split("/");
    for (int j = 0; j < ers.length; j++)
     l.add(ers[j]);
   }

   keyerrors.put(mykey, l);

   LinkedList lc = new LinkedList();
   if (null != keyerrors.get(mychildrenkey))
    lc = (LinkedList) keyerrors.get(mychildrenkey);
   if (errorsc.length > 1) {    
    String[] ersc = errorsc[1].split("/");
    for (int j = 0; j < ersc.length; j++) {
     lc.add(ersc[j]);
    }
   }
   keyerrors.put(mychildrenkey, lc);    
  }    
  return (sb.toString());    
 }

 public void initialize(String queryString, String outputfile) {    
  getErrors(queryString);
  rowsLinkedList.add(root);
  String[] str = { root };
  drawTree(str);
  createImage(root, outputfile);        
 }

 public void reinitialize(String queryString, String outputfile,int _xaxis,int _yaxis) {
  listparent         = new Hashtable();
  keyerrors    = new Hashtable();
  nodetree     = new Hashtable();
  connectNodes    = new Hashtable();
  rowsLinkedList   = new LinkedList();

  System.out.println(_xaxis);
  getErrors(queryString);
  rowsLinkedList.add(root);
  String[] str = { root };
  drawTree(str);
  createImage(_xaxis,_yaxis,root, outputfile);        
 }    

 public void drawTree(String[] node) {
  String[] a = getGreatChildren(node);
  if (a.length > 0)
   drawTree(a);    
 }    

 public String[] getGreatChildren(String[] children) {
  StringBuffer sb = new StringBuffer();
  LinkedList ll = new LinkedList();
  for (int i = 0; i < children.length; i++) {   
   if (null != getChildren(children[i])) {
    LinkedList temp = getChildren(children[i]);
    Iterator itr = temp.iterator();
    while (itr.hasNext()) {
     String chld = itr.next().toString();
     sb.append(chld);
     sb.append(",");
     ll.add(chld);
    }    
   }
  }
  rows++;
  if (sb.toString().length() > 0)
   rowsLinkedList.add(rows, sb.toString());
  return convertLinkedListtoStringArray(ll);
 }

 public LinkedList getChildren(String node) {    
  LinkedList l = new LinkedList();
  try {
   l = (LinkedList) nodetree.get(node);
   return l;
  } catch (Exception ee) {
  }

  return null;
 }

 public String[] convertLinkedListtoStringArray(LinkedList l) {    
  String[] strnodes = null;
  int size = l.size();
  strnodes = new String[size];
  Object[] objectArray = l.toArray();
  new ArrayList();
  for (int i = 0; i < size; i++) {    
   strnodes[i] = objectArray[i].toString();   
  }    
  return strnodes;
 }

 private String[] removeDuplicates(String[] l) {    
  Hashtable h = new Hashtable();

  for (int i = 0; i < l.length; i++) {    
   h.put(l[i], l[i]);    
  }

  java.util.Enumeration enk = h.keys();
  LinkedList ll = new LinkedList();

  while (enk.hasMoreElements()) {
   String _as = enk.nextElement().toString();
   ll.add(_as);    
  }       
  return convertLinkedListtoStringArray(ll);    
 }

 private void tmpinitialize(){    
  _listparent          = new Hashtable(listparent);
  _keyerrors        = new Hashtable(keyerrors);
  _nodetree     = new Hashtable(nodetree);
  _connectNodes    = connectNodes;
  _rowsLinkedList   = rowsLinkedList;
  _start_xaxis    = start_xaxis;
  _start_yaxis    = start_yaxis;
  _xaxis     = xaxis;
  _yaxis     = yaxis;
  _end_xaxis    = end_xaxis;
  _maxy     = maxy;
  _rectx     = rectx;
  _recty     = recty;
  _rows     = rows;
  _root    = root;            
 }

 private void reset(){    
  _listparent          = listparent;
  _keyerrors        = keyerrors;
  _nodetree     = nodetree;
  _connectNodes    = connectNodes;
  _rowsLinkedList   = rowsLinkedList;
  _start_xaxis    = start_xaxis;
  _start_yaxis    = start_yaxis;
  _xaxis     = xaxis;
  _yaxis     = yaxis;
  _end_xaxis    = end_xaxis;
  _maxy     = maxy;
  _rectx     = rectx;
  _recty     = recty;
  _rows     = rows;
  _root    = root;        
 }

 public void calculateXY(){   
  tmpinitialize();

  Hashtable _allh = new Hashtable();
  int _noofrows = _rowsLinkedList.size();
  int _mxy = start_yaxis;
  for (int i = 0; i < _noofrows; i++) {        
   String[] _tmpnodes = removeDuplicates(((String) _rowsLinkedList
     .get(i)).split(","));

   int _parts = calculateXY(_tmpnodes.length);

   start_yaxis = _mxy + 60;
   end_xaxis = 0;
   int _tmpy = start_yaxis;
   int _tmpx = 0;
   for (int j = 0; j < _tmpnodes.length; j++) {    
    try {
     if (j+1 == 1)   {
      start_xaxis = _parts * (j + 1) - 20;
     }
     else {
      start_xaxis = _tmpx+ _parts;// * (j + 1) - 50;    
     }    

     _tmpx = start_xaxis;    
     start_yaxis = _tmpy;

     if (null == _allh.get(_tmpnodes[j]))
      drawNode(_tmpnodes[j]);
     _allh.put(_tmpnodes[j], _tmpnodes[j]);
     if (start_yaxis >= _mxy)
      _mxy = start_yaxis;
    } catch (Exception e) {
     e.printStackTrace();
    }    
   }    
  }        
 }

 public void createImage(String startNode, String outputfile) {    
  BufferedImage image = new BufferedImage(xaxis, yaxis, BufferedImage.TYPE_INT_RGB);
  g = (Graphics2D) image.createGraphics();
  g.setColor(Color.white);
  g.fillRoundRect(0, 0, xaxis, yaxis, 0, 0);
  g.setColor(Color.white);
  Font f = new Font("SansSerif", Font.BOLD, 20);
  g.setFont(f);

  Hashtable allh = new Hashtable();
  int noofrows = rowsLinkedList.size();
  int mxy = start_yaxis;
  for (int i = 0; i < noofrows; i++) {        
   String[] tmpnodes = removeDuplicates(((String) rowsLinkedList.get(i)).split(","));

   int parts = calculateXY(tmpnodes.length);

   start_yaxis = mxy + 60;
   end_xaxis = 0;
   int tmpy = start_yaxis;
   int tmpx = 0;
   int stringwidth=0;
   for (int j = 0; j < tmpnodes.length; j++) {    
    try {
     if (j+1 == 1)   {
      start_xaxis = parts * (j + 1) - 20;
     }
     else {
      start_xaxis = tmpx+ parts;// * (j + 1) - 50;    
     }    

     tmpx = start_xaxis;    
     start_yaxis = tmpy;

     if (null == allh.get(tmpnodes[j]))
      drawNode(tmpnodes[j]);
     allh.put(tmpnodes[j], tmpnodes[j]);
     if (start_yaxis >= mxy)
      mxy = start_yaxis;
     FontMetrics ff = g.getFontMetrics();
     stringwidth += (start_xaxis+ff.stringWidth(tmpnodes[j]));    
    } catch (Exception e) {
     e.printStackTrace();
    }    
   }
   if (stringwidth >= bigx) bigx = stringwidth;
   System.out.println("Row "+i+" "+stringwidth);
  }

   xaxis = bigx;
   yaxis = mxy+40;

   System.out.println(xaxis);
   start_xaxis    = 0;
   start_yaxis    = 40;    
   end_xaxis    = 0;
   maxy     = 0;
   rectx     = 0;
   recty     = 0;
   rows     = 0;

   reinitialize(myquery, myoutput,bigx,mxy+40);    
 }

 public void createImage(int _xaxis,int _yaxis,String startNode, String outputfile) {    
  BufferedImage image = new BufferedImage(_xaxis, _yaxis, BufferedImage.TYPE_INT_RGB);
  g = (Graphics2D) image.createGraphics();
  g.setColor(Color.white);
  g.fillRoundRect(0, 0, xaxis, yaxis, 0, 0);
  g.setColor(Color.white);
  Font f = new Font("SansSerif", Font.BOLD, 20);
  g.setFont(f);

  Hashtable allh = new Hashtable();
  int noofrows = rowsLinkedList.size();
  int mxy      = start_yaxis;

  for (int i = 0; i < noofrows; i++) {        
   String[] tmpnodes = removeDuplicates(((String) rowsLinkedList.get(i)).split(","));

   int parts = calculateXY(tmpnodes.length);

   start_yaxis = mxy + 60;
   end_xaxis = 0;
   int tmpy = start_yaxis;
   int tmpx = 0;
   for (int j = 0; j < tmpnodes.length; j++) {    
    try {
     if (j+1 == 1)   {
      start_xaxis = parts * (j + 1) - 20;
     }
     else {
      start_xaxis = tmpx+ parts;// * (j + 1) - 50;   
     }    

     tmpx = start_xaxis;    
     start_yaxis = tmpy;

     if (null == allh.get(tmpnodes[j]))
      drawNode(tmpnodes[j]);
     allh.put(tmpnodes[j], tmpnodes[j]);
     if (start_yaxis >= mxy)
      mxy = start_yaxis;    
    } catch (Exception e) {
     e.printStackTrace();
    }    
   }    
  }

  try {    
   FileOutputStream jpegout = new FileOutputStream(
     new File(outputfile));
   JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(jpegout);
   encoder.encode(image);    
  } catch (Exception ee) {
   ee.printStackTrace();
  }    
 }    

 private int getMaxFm(String node){    
  int maxfm = 0;
  FontMetrics fm  = g.getFontMetrics();;
  maxfm   = fm.stringWidth(node)+10;

  LinkedList errorslist  = (LinkedList)keyerrors.get(node);
  Iterator itr  = errorslist.iterator();
  while (itr.hasNext()){    
   String eacherror = itr.next().toString();

   int tmpfm = fm.stringWidth(eacherror)+10;
   if (tmpfm >= maxfm) maxfm = tmpfm;
  }        
  return maxfm;
 }

 private int calculateXY(int nodecount) {    
  try {    
   return xaxis / (nodecount + 1);
  } catch (Exception e) {    
   e.printStackTrace();
  }
  return 0;
 }    

 public void drawNode(String node) {        
  Font f = new Font("SansSerif", Font.BOLD | Font.BOLD, 20);
  g.setFont(f);
  recty = 0;
  maxy = 0;
  FontMetrics fm = g.getFontMetrics();
  int w = fm.stringWidth(node) + 10;
  int h = fm.getHeight() + 4;
  int x = start_xaxis;
  int y = start_yaxis;    

  int startrect_xaxis = x - w / 2;
  if (startrect_xaxis < end_xaxis) {
    x = end_xaxis + w / 2 + 10;
    startrect_xaxis = x - w / 2;    
  }
  int startnode_xaxis = x - (w - 10) / 2;
  int startnode_yaxis = (y - (h - 4) / 2) + fm.getAscent();   
  int startrect_yaxis = y - h / 2;
  int xrectlength = w - 1;
  int yrectlength = h - 1;   
  int end_yaxis = startrect_yaxis + yrectlength + 1;
  end_xaxis = startrect_xaxis + xrectlength + 1;
  g.setColor(Color.white);
  g.fillRect(startrect_xaxis, startrect_yaxis, w, h);
  g.setColor(Color.BLACK);

  g.drawString(node, startnode_xaxis, startnode_yaxis);
  recty = yrectlength;
  if (null != keyerrors.get(node)) {
   rectx = 0;
   f = new Font("SansSerif", Font.PLAIN, 20);
   g.setFont(f);
   drawNodeErrors(node, startnode_xaxis, end_yaxis);
   if (rectx <= xrectlength)
    rectx = xrectlength;
   g.setColor(Color.black);
   calculateEdges(node, startrect_xaxis, startrect_yaxis, rectx,recty + 2);
   g.setColor(Color.GRAY);
   g.drawRoundRect(startrect_xaxis, startrect_yaxis, rectx, recty + 2,15,15);
   start_yaxis = startrect_yaxis + recty;   
  } else {
   g.setColor(Color.black);
   calculateEdges(node, startrect_xaxis, startrect_yaxis, xrectlength, yrectlength);
   g.setColor(Color.GRAY);
   g.drawRoundRect(startrect_xaxis, startrect_yaxis, xrectlength,yrectlength,15,15);
  }

  int bb = startrect_xaxis + xrectlength;
  if (bb >= bigx) {bigx = bb;}    
 }

 public void drawNodeErrors(String node, int startnode_xaxis, int end_yaxis) {
  Iterator itr = ((LinkedList) keyerrors.get(node)).iterator();
  while (itr.hasNext()) {
   int startrect_xaxis = 0;
   int x = 0;
   int y = 0;
   int xrectlength = 0;
   node = itr.next().toString().replaceAll("\\)", "");
   FontMetrics fm = g.getFontMetrics();
   int w = fm.stringWidth(node) + 10;
   int h = fm.getHeight() + 4;
   x = start_xaxis;
   start_yaxis = start_yaxis + 20;
   y = start_yaxis;

   startrect_xaxis = x - w / 2;
   if (startrect_xaxis < end_xaxis) {
    x = end_xaxis + w / 2 + 10;
    startrect_xaxis = x - w / 2;    
   }
   int startnode_yaxis = (y - (h - 4) / 2) + fm.getAscent();
   xrectlength = w - 1;
   g.setColor(Color.RED);
   g.drawString(node, startnode_xaxis, startnode_yaxis);
   recty += fm.getAscent();

   if (xrectlength >= rectx)
    rectx = xrectlength;
   if (recty >= maxy)
    maxy = recty;    
  }
 }

 private void calculateEdges(String node, int startxaxis, int startyaxis,
   int xlength, int ylength) {

  int x1 = startxaxis + xlength / 2;
  int y1 = startyaxis;

  int x2 = x1;
  int y2 = startyaxis + ylength;

  middle m = new middle();
  m.setX1(x1);
  m.setY1(y1);
  m.setX2(x2);
  m.setY2(y2);
  m.setStartxaxis(startxaxis);

  connectNodes.put(node, m);
  try {    
   String[] myparent = convertLinkedListtoStringArray((LinkedList) listparent.get(node));
   for (int j = 0; j < myparent.length; j++) {
    middle par = (middle) connectNodes.get(myparent[j]);

    int p[] = par.getBottom();
    int c[] = m.getTop();

    g.setColor(Color.black);
    int parentrectlength = p[0] - par.getStartxaxis();
    int parentendxaxis = par.getStartxaxis()
      + (parentrectlength * 2);
    if (c[0] > par.getStartxaxis() && c[0] < parentendxaxis) {    
     drawArrow(g,c[0],p[1],c[0],c[1]);
     drawMArrow(g,c[0],c[1],c[0],p[1]);    
    }
    else {
     drawArrow(g,p[0],p[1],c[0],c[1]);
     drawMArrow(g,c[0],c[1],p[0],p[1]);   
    }
   }   
  }    
  catch (Exception ee) {    
  }   
 }

 private void drawArrow(Graphics2D g, int x, int y, int xx, int yy)
 {
     float arrowWidth = 6.0f ;
     float theta = 0.423f ;
     int[] xPoints = new int[ 3 ] ;
     int[] yPoints = new int[ 3 ] ;
     float[] vecLine = new float[ 2 ] ;
     float[] vecLeft = new float[ 2 ] ;
     float fLength;
     float th;
     float ta;
     float baseX, baseY ;

     xPoints[ 0 ] = xx ;
     yPoints[ 0 ] = yy ;   

     vecLine[ 0 ] = (float)xPoints[ 0 ] - x ;
     vecLine[ 1 ] = (float)yPoints[ 0 ] - y ;    

     vecLeft[ 0 ] = -vecLine[ 1 ] ;
     vecLeft[ 1 ] = vecLine[ 0 ] ;   

     fLength = (float)Math.sqrt( vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1] ) ;
     th = arrowWidth / ( 2.0f * fLength ) ;
     ta = arrowWidth / ( 2.0f * ( (float)Math.tan( theta ) / 2.0f ) * fLength ) ;    

     baseX = ( (float)xPoints[ 0 ] - ta * vecLine[0]);
     baseY = ( (float)yPoints[ 0 ] - ta * vecLine[1]);    

     xPoints[ 1 ] = (int)( baseX + th * vecLeft[0] );
     yPoints[ 1 ] = (int)( baseY + th * vecLeft[1] );
     xPoints[ 2 ] = (int)( baseX - th * vecLeft[0] );
     yPoints[ 2 ] = (int)( baseY - th * vecLeft[1] );

     g.drawLine( x, y, (int)baseX, (int)baseY ) ;
     g.fillPolygon( xPoints, yPoints, 3 ) ;    
 }

 private void drawMArrow(Graphics2D g, int x, int y, int xx, int yy)
 {
     float arrowWidth = 6.0f ;
     float theta = 0.423f ;
     int[] xPoints = new int[ 3 ] ;
     int[] yPoints = new int[ 3 ] ;
     float[] vecLine = new float[ 2 ] ;
     float[] vecLeft = new float[ 2 ] ;
     float fLength;
     float th;
     float ta;
     float baseX, baseY ;

     xPoints[ 0 ] = xx ;
     yPoints[ 0 ] = yy ;

     vecLine[ 0 ] = (float)xPoints[ 0 ] - x ;
     vecLine[ 1 ] = (float)yPoints[ 0 ] - y ;    

     vecLeft[ 0 ] = -vecLine[ 1 ] ;
     vecLeft[ 1 ] = vecLine[ 0 ] ;    

     fLength = (float)Math.sqrt( vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1] ) ;
     th = arrowWidth / ( 2.0f * fLength ) ;
     ta = arrowWidth / ( 2.0f * ( (float)Math.tan( theta ) / 2.0f ) * fLength ) ;    

     baseX = ( (float)xPoints[ 0 ] - ta * vecLine[0]);
     baseY = ( (float)yPoints[ 0 ] - ta * vecLine[1]);

     xPoints[ 1 ] = (int)( baseX + th * vecLeft[0] );
     yPoints[ 1 ] = (int)( baseY + th * vecLeft[1] );
     xPoints[ 2 ] = (int)( baseX - th * vecLeft[0] );
     yPoints[ 2 ] = (int)( baseY - th * vecLeft[1] );

     g.fillPolygon( xPoints, yPoints, 3 ) ;    
 }

 class middle {    
  int x1;
  int y1;
  int x2;
  int y2;
  int startxaxis;

  public int getStartxaxis() {
   return startxaxis;
  }

  public void setStartxaxis(int startxaxis) {
   this.startxaxis = startxaxis;
  }

  public int getX1() {
   return x1;
  }

  public void setX1(int x1) {
   this.x1 = x1;
  }

  public int getY1() {
   return y1;
  }

  public void setY1(int y1) {
   this.y1 = y1;
  }

  public int getX2() {
   return x2;
  }

  public void setX2(int x2) {
   this.x2 = x2;
  }

  public int getY2() {
   return y2;
  }

  public void setY2(int y2) {
   this.y2 = y2;
  }

  public int[] getTop() {   
   int t[] = new int[2];
   t[0] = this.x1;
   t[1] = this.y1;

   return t;
  }

  public int[] getBottom() {   
   int t[] = new int[2];
   t[0] = this.x2;
   t[1] = this.y2;

   return t;
  }    
 }
}
于 2011-01-31T03:28:12.347 回答
1

你试过gwt-graph吗?

于 2010-04-08T07:18:29.667 回答