import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Paint; import java.awt.Shape; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.sql.ResultSet; import java.sql.Statement; import java.util.Hashtable; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.JTextField; import org.apache.commons.collections.Predicate; import edu.uci.ics.jung.graph.DirectedEdge; import edu.uci.ics.jung.graph.Edge; import edu.uci.ics.jung.graph.Graph; import edu.uci.ics.jung.graph.Vertex; import edu.uci.ics.jung.graph.decorators.AbstractVertexShapeFunction; import edu.uci.ics.jung.graph.decorators.DefaultToolTipFunction; import edu.uci.ics.jung.graph.decorators.EdgePaintFunction; import edu.uci.ics.jung.graph.decorators.NumberEdgeValue; import edu.uci.ics.jung.graph.decorators.NumberVertexValue; import edu.uci.ics.jung.graph.decorators.StringLabeller; import edu.uci.ics.jung.graph.decorators.UserDatumNumberEdgeValue; import edu.uci.ics.jung.graph.decorators.UserDatumNumberVertexValue; import edu.uci.ics.jung.graph.decorators.VertexAspectRatioFunction; import edu.uci.ics.jung.graph.decorators.VertexPaintFunction; import edu.uci.ics.jung.graph.decorators.VertexSizeFunction; import edu.uci.ics.jung.graph.impl.DirectedSparseEdge; import edu.uci.ics.jung.graph.impl.SparseGraph; import edu.uci.ics.jung.graph.impl.SparseVertex; import edu.uci.ics.jung.utils.UserData; import edu.uci.ics.jung.visualization.FRLayout; import edu.uci.ics.jung.visualization.GraphZoomScrollPane; import edu.uci.ics.jung.visualization.LayoutMutable; import edu.uci.ics.jung.visualization.MultiPickedState; import edu.uci.ics.jung.visualization.PickedState; import edu.uci.ics.jung.visualization.PluggableRenderer; import edu.uci.ics.jung.visualization.ShapePickSupport; import edu.uci.ics.jung.visualization.SpringLayout; import edu.uci.ics.jung.visualization.VisualizationViewer; import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse; public class UMLSGraphGen implements ActionListener { Graph umlsGraph; Hashtable vertexMap; private static final Object DEMOKEY = "DEMOKEY"; ConnMgr connMgr; DefaultModalGraphMouse gm; JTextField jtfNumEdges; JTextField jtfStartRow; JButton btnAddEdges; JLabel lblLinks; JCheckBox chkVSmall; StringLabeller slabeller; int gstart_row; int total_links; Hashtable hREL; VisualizationViewer vv; protected VertexDisplayPredicate show_vertex; JFrame jf ; private LayoutMutable layout = null; protected final static Object VOLTAGE_KEY = "voltages"; protected final static Object TRANSPARENCY = "transparency"; protected NumberEdgeValue edge_weight = new UserDatumNumberEdgeValue("edge_weight"); protected NumberVertexValue voltages = new UserDatumNumberVertexValue(VOLTAGE_KEY); protected NumberVertexValue transparency = new UserDatumNumberVertexValue(TRANSPARENCY); VertexShapeSizeAspect vssa; public UMLSGraphGen(){ try { connMgr = new ConnMgr(1,1,ConnMgr.MYSQL); hREL = new Hashtable(); hREL.put("CHD", ""); hREL.put("PAR", ""); hREL.put("RN", ""); hREL.put("RB", ""); vertexMap = new Hashtable(); umlsGraph = new SparseGraph(); final PickedState ps = new MultiPickedState(); PluggableRenderer pr = new PluggableRenderer(); slabeller = StringLabeller.getLabeller(umlsGraph); vssa = new VertexShapeSizeAspect(voltages); show_vertex = new VertexDisplayPredicate(false); //pr.setVertexPaintFunction(new PickableVertexPaintFunction(pr, Color.lightGray, Color.white, Color.yellow)); pr.setVertexPaintFunction(new VertexPaintFunction() { public Paint getFillPaint(Vertex v) { Color k = (Color) v.getUserDatum(DEMOKEY); if (k != null) return k; return Color.white; } public Paint getDrawPaint(Vertex v) { if(ps.isPicked(v)) { return Color.cyan; } else { return Color.BLACK; } } }); pr.setEdgePaintFunction(new EdgePaintFunction() { public Paint getDrawPaint(Edge e) { Color k = (Color) e.getUserDatum(DEMOKEY); if (k != null) return k; return Color.blue; } public Paint getFillPaint(Edge e) { return null; } }); addGraphEdges(gstart_row,5); pr.setVertexStringer(slabeller); pr.setVertexShapeFunction(vssa); pr.setVertexIncludePredicate(show_vertex); layout = new SpringLayout(umlsGraph); vv = new VisualizationViewer(layout, pr); vv.getModel().setRelaxerThreadSleepTime(500); vv.setPickSupport(new ShapePickSupport()); vv.setGraphMouse(new DefaultModalGraphMouse()); vv.setToolTipFunction(new VoltageTips()); jf = new JFrame(); JRootPane rp = jf.getRootPane(); rp.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); GraphZoomScrollPane scrollPane = new GraphZoomScrollPane(vv); gm = new DefaultModalGraphMouse(); vv.setGraphMouse(gm); gm.setZoomAtMouse(true); jf.getContentPane().add(scrollPane, BorderLayout.CENTER); JPanel pnlBottom = new JPanel(); pnlBottom.add(new JLabel("No. of Links Displayed:")); pnlBottom.add(lblLinks=new JLabel("5")); pnlBottom.add(new JLabel("Start Row:")); pnlBottom.add(jtfStartRow=new JTextField(15)); jtfStartRow.setText(""+gstart_row); pnlBottom.add(new JLabel("Add Next Edges")); jtfNumEdges = new JTextField(15); pnlBottom.add(jtfNumEdges); btnAddEdges = new JButton("ADD"); pnlBottom.add(btnAddEdges); btnAddEdges.addActionListener(this); JComboBox modeBox = gm.getModeComboBox(); JPanel modePanel = new JPanel(new BorderLayout()); modePanel.setBorder(BorderFactory.createTitledBorder("Mouse Mode")); modePanel.add(modeBox); pnlBottom.add(modePanel); chkVSmall = new JCheckBox("filter vertices of degree < " + VertexDisplayPredicate.MIN_DEGREE); chkVSmall.addActionListener(this); pnlBottom.add(chkVSmall); jf.getContentPane().add(pnlBottom, BorderLayout.SOUTH); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.pack(); jf.setVisible(true); }catch(Exception e) { e.printStackTrace(); } } /*iterate through K MRREL edges and color them based on hierarchial or lateral edges*/ public void addGraphEdges(int start_row, int num_rows){ try{ String qry = "select * from MRREL limit "+start_row+","+num_rows; gstart_row = start_row+num_rows; total_links +=num_rows; Statement stmt = connMgr.getDirecStmt(); ResultSet rs = stmt.executeQuery(qry); while(rs.next()){ String cui1 = rs.getString("CUI1"); String cui2 = rs.getString("CUI2"); String rel = rs.getString("REL"); Vertex vcui1 = null; Vertex vcui2 = null; if((vcui1=(Vertex)vertexMap.get(cui1))==null){ vcui1 = umlsGraph.addVertex(new SparseVertex()); vcui1.setUserDatum("CUI", cui1, UserData.REMOVE); // vcui1.setUserDatum(DEMOKEY, "NAME"+indx, UserData.REMOVE); vertexMap.put(cui1,vcui1); int cnt = getNodeSABCount(cui1); colorConceptNode(vcui1,cnt); slabeller.setLabel(vcui1, cui1); } if((vcui2=(Vertex)vertexMap.get(cui2))==null){ vcui2 = umlsGraph.addVertex(new SparseVertex()); vcui2.setUserDatum("CUI", cui2, UserData.REMOVE); vertexMap.put(cui2,vcui2); int cnt = getNodeSABCount(cui2); colorConceptNode(vcui2,cnt); slabeller.setLabel(vcui2, cui2); } if(hREL.get(rel)!=null){ DirectedEdge de = new DirectedSparseEdge(vcui1, vcui2); de.setUserDatum(DEMOKEY, Color.RED, UserData.REMOVE); //hierarchial are BLUe umlsGraph.addEdge(de); }else{ DirectedEdge de = new DirectedSparseEdge(vcui1, vcui2); de.setUserDatum(DEMOKEY, Color.BLUE, UserData.REMOVE); umlsGraph.addEdge(de); } } }catch(Exception e) { e.printStackTrace(); } } public void actionPerformed(ActionEvent ae){ if(ae.getSource() == btnAddEdges){ // jf.validate(); addGraphEdges(Integer.parseInt(jtfStartRow.getText()),Integer.parseInt(jtfNumEdges.getText())); jtfStartRow.setText(""+gstart_row); lblLinks.setText(""+total_links); layout.update(); if (!vv.isVisRunnerRunning()) vv.init(); vssa.setScaling(true); vv.repaint(); } if(ae.getSource() == chkVSmall){ AbstractButton ab = (AbstractButton)ae.getSource(); show_vertex.filterSmall(ab.isSelected()); } } public void colorConceptNode(Vertex vertex, int count){ if(count==1){ vertex.setUserDatum(DEMOKEY, Color.WHITE, UserData.REMOVE); }else if(count<3){ vertex.setUserDatum(DEMOKEY, Color.LIGHT_GRAY, UserData.REMOVE); }else if(count<5){ vertex.setUserDatum(DEMOKEY, Color.DARK_GRAY, UserData.REMOVE); }else { vertex.setUserDatum(DEMOKEY, Color.BLACK, UserData.REMOVE); } } public int getNodeSABCount(String cui){ try { Statement stmt = connMgr.getDirecStmt(); String qry = "select count(*) as cnt from MRSAB where cui='"+cui+"'"; ResultSet rs = stmt.executeQuery(qry); if(rs.next()) return rs.getInt("cnt"); } catch (Exception e) { e.printStackTrace(); } return -1; } public class VoltageTips extends DefaultToolTipFunction { public String getToolTipText(Vertex v) { return "Degree:"+v.degree()+" - "+v.getUserDatum("CUI"); } public String getToolTipText(Edge edge) { return edge.toString(); } } private final static class VertexShapeSizeAspect extends AbstractVertexShapeFunction implements VertexSizeFunction, VertexAspectRatioFunction { protected boolean stretch = false; protected boolean scale = false; protected boolean funny_shapes = false; protected NumberVertexValue voltages; public VertexShapeSizeAspect(NumberVertexValue voltages) { this.voltages = voltages; setSizeFunction(this); setAspectRatioFunction(this); } public void setStretching(boolean stretch) { this.stretch = stretch; } public void setScaling(boolean scale) { this.scale = scale; } public void useFunnyShapes(boolean use) { this.funny_shapes = use; } public int getSize(Vertex v) { int idegree = v.degree();// Integer.parseInt((String)v.getUserDatum("VDEGREE")); return 2+(idegree); // if (scale) // return (int)(voltages.getNumber(v).doubleValue() * 30) + 20; // else // return 20; } public float getAspectRatio(Vertex v) { if (stretch) return (float)(v.inDegree() + 1) / (v.outDegree() + 1); else return 1.0f; } public Shape getShape(Vertex v) { if (funny_shapes) { if (v.degree() < 5) { int sides = Math.max(v.degree(), 3); return factory.getRegularPolygon(v, sides); } else return factory.getRegularStar(v, v.degree()); } else return factory.getEllipse(v); } } private final static class VertexDisplayPredicate implements Predicate { protected boolean filter_small; protected final static int MIN_DEGREE = 4; public VertexDisplayPredicate(boolean filter) { this.filter_small = filter; } public void filterSmall(boolean b) { filter_small = b; } public boolean evaluate(Object arg0) { Vertex v = (Vertex)arg0; if (filter_small) return (v.degree() >= MIN_DEGREE); else return true; } } public static void main(String[] args) { UMLSGraphGen ugs = new UMLSGraphGen(); } }