Java tutorial
/////////////////////////////// // Makumba, Makumba tag library // Copyright (C) 2000-2003 http://www.makumba.org // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // ------------- // $Id: FormsOQLTest.java 2628 2008-06-17 21:03:46Z manuel_gay $ // $Name$ ///////////////////////////////////// package org.makumba.devel; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Vector; import javax.swing.JFrame; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Namespace; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; import org.makumba.DataDefinition; import org.makumba.DataDefinitionParseError; import org.makumba.FieldDefinition; import org.makumba.providers.DataDefinitionProvider; import prefuse.Constants; import prefuse.Display; import prefuse.Visualization; import prefuse.action.ActionList; import prefuse.action.RepaintAction; import prefuse.action.assignment.ColorAction; import prefuse.action.layout.Layout; import prefuse.action.layout.graph.ForceDirectedLayout; import prefuse.action.layout.graph.SquarifiedTreeMapLayout; import prefuse.activity.Activity; import prefuse.controls.DragControl; import prefuse.controls.PanControl; import prefuse.controls.ZoomControl; import prefuse.data.Graph; import prefuse.data.Node; import prefuse.data.io.DataIOException; import prefuse.data.io.GraphMLReader; import prefuse.render.AbstractShapeRenderer; import prefuse.render.DefaultRendererFactory; import prefuse.render.EdgeRenderer; import prefuse.render.LabelRenderer; import prefuse.util.ColorLib; import prefuse.visual.VisualItem; import prefuse.visual.expression.InGroupPredicate; /** * A (not-ready) class to visualise the relation of data definitions. * * @author Rudolf Mayer * @version $Id: MDDVisualiser.java,v 1.1 Jul 21, 2008 12:26:37 AM rudi Exp $ */ public class MDDRelationVisualiser { static final String treeNodes = "graph.nodes"; static final String treeEdges = "graph.edges"; public static void main(String[] args) throws IOException { DataDefinitionProvider ddp = DataDefinitionProvider.getInstance(); Vector<String> mdds; if (args.length > 0) { mdds = ddp.getDataDefinitionsInAbsoluteLocation(args[0]); } else { mdds = ddp.getDataDefinitionsInDefaultLocations(); } File tmp = new File("/tmp/graph.ml"); // File.createTempFile("graph_", ".ml"); Document d = DocumentHelper.createDocument(); Element graphml_tag = d.addElement("graphml"); Element root = graphml_tag.addElement("graph"); root.addAttribute("edgedefault", "directed"); Namespace ns = Namespace.get("", "http://graphml.graphdrawing.org/xmlns"); d.getRootElement().add(ns); Element incoming = root.addElement("key"); incoming.addAttribute("id", "name"); incoming.addAttribute("for", "node"); incoming.addAttribute("attr.name", "name"); incoming.addAttribute("attr.type", "string"); for (String mdd : mdds) { try { processMDD(root, ddp.getDataDefinition(mdd)); } catch (DataDefinitionParseError e) { System.out.println("Skipping broken MDD " + mdd); } } XMLWriter serializer = new XMLWriter(new FileWriter(tmp), new OutputFormat("", false)); serializer.write(d); serializer.close(); Graph graph = null; try { graph = new GraphMLReader().readGraph(tmp.getAbsoluteFile()); } catch (DataIOException e) { e.printStackTrace(); System.err.println("Error loading graph. Exiting..."); System.exit(1); } int minEdges = 3; for (int i = graph.getNodeCount() - 1; i >= 0; i--) { Node node = graph.getNode(i); System.out.println(node + ", " + node.getOutDegree()); if (node.getOutDegree() < minEdges) { graph.removeNode(node); } } // add the graph to the visualization as the data group "graph" // nodes and edges are accessible as "graph.nodes" and "graph.edges" Visualization m_vis = new Visualization(); m_vis.add("graph", graph); m_vis.setInteractive(treeNodes, null, false); // draw the "name" label for NodeItems LabelRenderer m_nodeRenderer = new LabelRenderer("name"); m_nodeRenderer.setRenderType(AbstractShapeRenderer.RENDER_TYPE_FILL); m_nodeRenderer.setHorizontalAlignment(Constants.CENTER); m_nodeRenderer.setRoundedCorner(8, 8); // round the corners EdgeRenderer m_edgeRenderer = new EdgeRenderer(); m_edgeRenderer.setDefaultLineWidth(1.0); // create a new default renderer factory // return our name label renderer as the default for all non-EdgeItems // includes straight line edges for EdgeItems by default final DefaultRendererFactory rf = new DefaultRendererFactory(m_nodeRenderer); rf.add(new InGroupPredicate(treeEdges), m_edgeRenderer); m_vis.setRendererFactory(rf); // use black for node text ColorAction text = new ColorAction(treeNodes, VisualItem.TEXTCOLOR, ColorLib.gray(0)); // use light grey for edges ColorAction edges = new ColorAction(treeEdges, VisualItem.STROKECOLOR, ColorLib.gray(200)); // create an action list containing all color assignments ActionList color = new ActionList(); // color.add(fill); color.add(text); color.add(edges); // create the tree layout action Layout graphLayout = new SquarifiedTreeMapLayout("graph"); m_vis.putAction("circleLayout", graphLayout); // create an action list with an animated layout // the INFINITY parameter tells the action list to run indefinitely ActionList layout = new ActionList(Activity.DEFAULT_STEP_TIME * 500); Layout l = new ForceDirectedLayout("graph"); layout.add(l); layout.add(new RepaintAction()); // add the actions to the visualization m_vis.putAction("color", color); m_vis.putAction("layout", layout); // create a new Display that pull from our Visualization Display display = new Display(m_vis); display.setSize(1200, 800); // set display size display.addControlListener(new DragControl()); // drag items around display.addControlListener(new PanControl()); // pan with background left-drag display.addControlListener(new ZoomControl()); // zoom with vertical right-drag // create a new window to hold the visualization JFrame frame = new JFrame("MDD analysis"); // ensure application exits when window is closed frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(display); frame.pack(); // layout components in window frame.setVisible(true); // show the window m_vis.run("color"); // assign the colors m_vis.run("layout"); // start up the animated layout } private static void processMDD(Element root, DataDefinition dd) { System.out.println(dd); addNode(root, dd.getName()); for (FieldDefinition fd : dd.getFieldDefinitions()) { if (fd.isPointer()) { final String name2 = fd.getPointedType().getName(); addEdge(root, dd.getName(), name2, 9); } else if (fd.getIntegerType() == FieldDefinition._set) { final String name2 = fd.getPointedType().getName(); addEdge(root, dd.getName(), name2, 9); } else if (fd.getIntegerType() == FieldDefinition._setComplex) { processMDD(root, fd.getSubtable()); } } } private static void addNode(Element root, String name) { Element elem = root.addElement("node").addAttribute("id", "" + name); elem.addElement("data").addAttribute("key", "name").setText(name); } private static Element addEdge(Element root, String from, String to, Integer count) { Element elem = root.addElement("edge"); elem.addAttribute("source", "" + from); elem.addAttribute("target", "" + to); elem.addAttribute("directed", "true"); return elem; } }