<pre>
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 = 0;x=start_xaxis;
int y = 0;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;
}
}
}
</pre>